Index: vendor-crypto/openssl/dist-1.0.1/CHANGES
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/CHANGES	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/CHANGES	(revision 306191)
@@ -1,10737 +1,10897 @@
 
  OpenSSL CHANGES
  _______________
 
+ Changes between 1.0.1t and 1.0.1u [22 Sep 2016]
+
+  *) OCSP Status Request extension unbounded memory growth
+
+     A malicious client can send an excessively large OCSP Status Request
+     extension. If that client continually requests renegotiation, sending a
+     large OCSP Status Request extension each time, then there will be unbounded
+     memory growth on the server. This will eventually lead to a Denial Of
+     Service attack through memory exhaustion. Servers with a default
+     configuration are vulnerable even if they do not support OCSP. Builds using
+     the "no-ocsp" build time option are not affected.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6304)
+     [Matt Caswell]
+
+  *) In order to mitigate the SWEET32 attack, the DES ciphers were moved from
+     HIGH to MEDIUM.
+
+     This issue was reported to OpenSSL Karthikeyan Bhargavan and Gaetan
+     Leurent (INRIA)
+     (CVE-2016-2183)
+     [Rich Salz]
+
+  *) OOB write in MDC2_Update()
+
+     An overflow can occur in MDC2_Update() either if called directly or
+     through the EVP_DigestUpdate() function using MDC2. If an attacker
+     is able to supply very large amounts of input data after a previous
+     call to EVP_EncryptUpdate() with a partial block then a length check
+     can overflow resulting in a heap corruption.
+
+     The amount of data needed is comparable to SIZE_MAX which is impractical
+     on most platforms.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6303)
+     [Stephen Henson]
+
+  *) Malformed SHA512 ticket DoS
+
+     If a server uses SHA512 for TLS session ticket HMAC it is vulnerable to a
+     DoS attack where a malformed ticket will result in an OOB read which will
+     ultimately crash.
+
+     The use of SHA512 in TLS session tickets is comparatively rare as it requires
+     a custom server callback and ticket lookup mechanism.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6302)
+     [Stephen Henson]
+
+  *) OOB write in BN_bn2dec()
+
+     The function BN_bn2dec() does not check the return value of BN_div_word().
+     This can cause an OOB write if an application uses this function with an
+     overly large BIGNUM. This could be a problem if an overly large certificate
+     or CRL is printed out from an untrusted source. TLS is not affected because
+     record limits will reject an oversized certificate before it is parsed.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-2182)
+     [Stephen Henson]
+
+  *) OOB read in TS_OBJ_print_bio()
+
+     The function TS_OBJ_print_bio() misuses OBJ_obj2txt(): the return value is
+     the total length the OID text representation would use and not the amount
+     of data written. This will result in OOB reads when large OIDs are
+     presented.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-2180)
+     [Stephen Henson]
+
+  *) Pointer arithmetic undefined behaviour
+
+     Avoid some undefined pointer arithmetic
+
+     A common idiom in the codebase is to check limits in the following manner:
+     "p + len > limit"
+
+     Where "p" points to some malloc'd data of SIZE bytes and
+     limit == p + SIZE
+
+     "len" here could be from some externally supplied data (e.g. from a TLS
+     message).
+
+     The rules of C pointer arithmetic are such that "p + len" is only well
+     defined where len <= SIZE. Therefore the above idiom is actually
+     undefined behaviour.
+
+     For example this could cause problems if some malloc implementation
+     provides an address for "p" such that "p + len" actually overflows for
+     values of len that are too big and therefore p + len < limit.
+
+     This issue was reported to OpenSSL by Guido Vranken
+     (CVE-2016-2177)
+     [Matt Caswell]
+
+  *) Constant time flag not preserved in DSA signing
+
+     Operations in the DSA signing algorithm should run in constant time in
+     order to avoid side channel attacks. A flaw in the OpenSSL DSA
+     implementation means that a non-constant time codepath is followed for
+     certain operations. This has been demonstrated through a cache-timing
+     attack to be sufficient for an attacker to recover the private DSA key.
+
+     This issue was reported by César Pereida (Aalto University), Billy Brumley
+     (Tampere University of Technology), and Yuval Yarom (The University of
+     Adelaide and NICTA).
+     (CVE-2016-2178)
+     [César Pereida]
+
+  *) DTLS buffered message DoS
+
+     In a DTLS connection where handshake messages are delivered out-of-order
+     those messages that OpenSSL is not yet ready to process will be buffered
+     for later use. Under certain circumstances, a flaw in the logic means that
+     those messages do not get removed from the buffer even though the handshake
+     has been completed. An attacker could force up to approx. 15 messages to
+     remain in the buffer when they are no longer required. These messages will
+     be cleared when the DTLS connection is closed. The default maximum size for
+     a message is 100k. Therefore the attacker could force an additional 1500k
+     to be consumed per connection. By opening many simulataneous connections an
+     attacker could cause a DoS attack through memory exhaustion.
+
+     This issue was reported to OpenSSL by Quan Luo.
+     (CVE-2016-2179)
+     [Matt Caswell]
+
+  *) DTLS replay protection DoS
+
+     A flaw in the DTLS replay attack protection mechanism means that records
+     that arrive for future epochs update the replay protection "window" before
+     the MAC for the record has been validated. This could be exploited by an
+     attacker by sending a record for the next epoch (which does not have to
+     decrypt or have a valid MAC), with a very large sequence number. This means
+     that all subsequent legitimate packets are dropped causing a denial of
+     service for a specific DTLS connection.
+
+     This issue was reported to OpenSSL by the OCAP audit team.
+     (CVE-2016-2181)
+     [Matt Caswell]
+
+  *) Certificate message OOB reads
+
+     In OpenSSL 1.0.2 and earlier some missing message length checks can result
+     in OOB reads of up to 2 bytes beyond an allocated buffer. There is a
+     theoretical DoS risk but this has not been observed in practice on common
+     platforms.
+
+     The messages affected are client certificate, client certificate request
+     and server certificate. As a result the attack can only be performed
+     against a client or a server which enables client authentication.
+
+     This issue was reported to OpenSSL by Shi Lei (Gear Team, Qihoo 360 Inc.)
+     (CVE-2016-6306)
+     [Stephen Henson]
+
  Changes between 1.0.1s and 1.0.1t [3 May 2016]
 
   *) Prevent padding oracle in AES-NI CBC MAC check
 
      A MITM attacker can use a padding oracle attack to decrypt traffic
      when the connection uses an AES CBC cipher and the server support
      AES-NI.
 
      This issue was introduced as part of the fix for Lucky 13 padding
      attack (CVE-2013-0169). The padding check was rewritten to be in
      constant time by making sure that always the same bytes are read and
      compared against either the MAC or padding bytes. But it no longer
      checked that there was enough data to have both the MAC and padding
      bytes.
 
      This issue was reported by Juraj Somorovsky using TLS-Attacker.
      (CVE-2016-2107)
      [Kurt Roeckx]
 
   *) Fix EVP_EncodeUpdate overflow
 
      An overflow can occur in the EVP_EncodeUpdate() function which is used for
      Base64 encoding of binary data. If an attacker is able to supply very large
      amounts of input data then a length check can overflow resulting in a heap
      corruption.
 
      Internally to OpenSSL the EVP_EncodeUpdate() function is primarly used by
      the PEM_write_bio* family of functions. These are mainly used within the
      OpenSSL command line applications, so any application which processes data
      from an untrusted source and outputs it as a PEM file should be considered
      vulnerable to this issue. User applications that call these APIs directly
      with large amounts of untrusted data may also be vulnerable.
 
      This issue was reported by Guido Vranken.
      (CVE-2016-2105)
      [Matt Caswell]
 
   *) Fix EVP_EncryptUpdate overflow
 
      An overflow can occur in the EVP_EncryptUpdate() function. If an attacker
      is able to supply very large amounts of input data after a previous call to
      EVP_EncryptUpdate() with a partial block then a length check can overflow
      resulting in a heap corruption. Following an analysis of all OpenSSL
      internal usage of the EVP_EncryptUpdate() function all usage is one of two
      forms. The first form is where the EVP_EncryptUpdate() call is known to be
      the first called function after an EVP_EncryptInit(), and therefore that
      specific call must be safe. The second form is where the length passed to
      EVP_EncryptUpdate() can be seen from the code to be some small value and
      therefore there is no possibility of an overflow. Since all instances are
      one of these two forms, it is believed that there can be no overflows in
      internal code due to this problem. It should be noted that
      EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths.
      Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances
      of these calls have also been analysed too and it is believed there are no
      instances in internal usage where an overflow could occur.
 
      This issue was reported by Guido Vranken.
      (CVE-2016-2106)
      [Matt Caswell]
 
   *) Prevent ASN.1 BIO excessive memory allocation
 
      When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio()
      a short invalid encoding can casuse allocation of large amounts of memory
      potentially consuming excessive resources or exhausting memory.
 
      Any application parsing untrusted data through d2i BIO functions is
      affected. The memory based functions such as d2i_X509() are *not* affected.
      Since the memory based functions are used by the TLS library, TLS
      applications are not affected.
 
      This issue was reported by Brian Carpenter.
      (CVE-2016-2109)
      [Stephen Henson]
 
   *) EBCDIC overread
 
      ASN1 Strings that are over 1024 bytes can cause an overread in applications
      using the X509_NAME_oneline() function on EBCDIC systems. This could result
      in arbitrary stack data being returned in the buffer.
 
      This issue was reported by Guido Vranken.
      (CVE-2016-2176)
      [Matt Caswell]
 
   *) Modify behavior of ALPN to invoke callback after SNI/servername
      callback, such that updates to the SSL_CTX affect ALPN.
      [Todd Short]
 
   *) Remove LOW from the DEFAULT cipher list.  This removes singles DES from the
      default.
      [Kurt Roeckx]
 
   *) Only remove the SSLv2 methods with the no-ssl2-method option. When the
      methods are enabled and ssl2 is disabled the methods return NULL.
      [Kurt Roeckx]
 
  Changes between 1.0.1r and 1.0.1s [1 Mar 2016]
 
   * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL.
     Builds that are not configured with "enable-weak-ssl-ciphers" will not
     provide any "EXPORT" or "LOW" strength ciphers.
     [Viktor Dukhovni]
 
   * Disable SSLv2 default build, default negotiation and weak ciphers.  SSLv2
     is by default disabled at build-time.  Builds that are not configured with
     "enable-ssl2" will not support SSLv2.  Even if "enable-ssl2" is used,
     users who want to negotiate SSLv2 via the version-flexible SSLv23_method()
     will need to explicitly call either of:
 
         SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2);
     or
         SSL_clear_options(ssl, SSL_OP_NO_SSLv2);
 
     as appropriate.  Even if either of those is used, or the application
     explicitly uses the version-specific SSLv2_method() or its client and
     server variants, SSLv2 ciphers vulnerable to exhaustive search key
     recovery have been removed.  Specifically, the SSLv2 40-bit EXPORT
     ciphers, and SSLv2 56-bit DES are no longer available.
     (CVE-2016-0800)
     [Viktor Dukhovni]
 
   *) Fix a double-free in DSA code
 
      A double free bug was discovered when OpenSSL parses malformed DSA private
      keys and could lead to a DoS attack or memory corruption for applications
      that receive DSA private keys from untrusted sources.  This scenario is
      considered rare.
 
      This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using
      libFuzzer.
      (CVE-2016-0705)
      [Stephen Henson]
 
   *) Disable SRP fake user seed to address a server memory leak.
 
      Add a new method SRP_VBASE_get1_by_user that handles the seed properly.
 
      SRP_VBASE_get_by_user had inconsistent memory management behaviour.
      In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user
      was changed to ignore the "fake user" SRP seed, even if the seed
      is configured.
 
      Users should use SRP_VBASE_get1_by_user instead. Note that in
      SRP_VBASE_get1_by_user, caller must free the returned value. Note
      also that even though configuring the SRP seed attempts to hide
      invalid usernames by continuing the handshake with fake
      credentials, this behaviour is not constant time and no strong
      guarantees are made that the handshake is indistinguishable from
      that of a valid user.
      (CVE-2016-0798)
      [Emilia Käsper]
 
   *) Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption
 
      In the BN_hex2bn function the number of hex digits is calculated using an
      int value |i|. Later |bn_expand| is called with a value of |i * 4|. For
      large values of |i| this can result in |bn_expand| not allocating any
      memory because |i * 4| is negative. This can leave the internal BIGNUM data
      field as NULL leading to a subsequent NULL ptr deref. For very large values
      of |i|, the calculation |i * 4| could be a positive value smaller than |i|.
      In this case memory is allocated to the internal BIGNUM data field, but it
      is insufficiently sized leading to heap corruption. A similar issue exists
      in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn
      is ever called by user applications with very large untrusted hex/dec data.
      This is anticipated to be a rare occurrence.
 
      All OpenSSL internal usage of these functions use data that is not expected
      to be untrusted, e.g. config file data or application command line
      arguments. If user developed applications generate config file data based
      on untrusted data then it is possible that this could also lead to security
      consequences. This is also anticipated to be rare.
 
      This issue was reported to OpenSSL by Guido Vranken.
      (CVE-2016-0797)
      [Matt Caswell]
 
   *) Fix memory issues in BIO_*printf functions
 
      The internal |fmtstr| function used in processing a "%s" format string in
      the BIO_*printf functions could overflow while calculating the length of a
      string and cause an OOB read when printing very long strings.
 
      Additionally the internal |doapr_outch| function can attempt to write to an
      OOB memory location (at an offset from the NULL pointer) in the event of a
      memory allocation failure. In 1.0.2 and below this could be caused where
      the size of a buffer to be allocated is greater than INT_MAX. E.g. this
      could be in processing a very long "%s" format string. Memory leaks can
      also occur.
 
      The first issue may mask the second issue dependent on compiler behaviour.
      These problems could enable attacks where large amounts of untrusted data
      is passed to the BIO_*printf functions. If applications use these functions
      in this way then they could be vulnerable. OpenSSL itself uses these
      functions when printing out human-readable dumps of ASN.1 data. Therefore
      applications that print this data could be vulnerable if the data is from
      untrusted sources. OpenSSL command line applications could also be
      vulnerable where they print out ASN.1 data, or if untrusted data is passed
      as command line arguments.
 
      Libssl is not considered directly vulnerable. Additionally certificates etc
      received via remote connections via libssl are also unlikely to be able to
      trigger these issues because of message size limits enforced within libssl.
 
      This issue was reported to OpenSSL Guido Vranken.
      (CVE-2016-0799)
      [Matt Caswell]
 
   *) Side channel attack on modular exponentiation
 
      A side-channel attack was found which makes use of cache-bank conflicts on
      the Intel Sandy-Bridge microarchitecture which could lead to the recovery
      of RSA keys.  The ability to exploit this issue is limited as it relies on
      an attacker who has control of code in a thread running on the same
      hyper-threaded core as the victim thread which is performing decryptions.
 
      This issue was reported to OpenSSL by Yuval Yarom, The University of
      Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and
      Nadia Heninger, University of Pennsylvania with more information at
      http://cachebleed.info.
      (CVE-2016-0702)
      [Andy Polyakov]
 
   *) Change the req app to generate a 2048-bit RSA/DSA key by default,
      if no keysize is specified with default_bits. This fixes an
      omission in an earlier change that changed all RSA/DSA key generation
      apps to use 2048 bits by default.
      [Emilia Käsper]
 
  Changes between 1.0.1q and 1.0.1r [28 Jan 2016]
 
   *) Protection for DH small subgroup attacks
 
      As a precautionary measure the SSL_OP_SINGLE_DH_USE option has been
      switched on by default and cannot be disabled. This could have some
      performance impact.
      [Matt Caswell]
 
   *) SSLv2 doesn't block disabled ciphers
 
      A malicious client can negotiate SSLv2 ciphers that have been disabled on
      the server and complete SSLv2 handshakes even if all SSLv2 ciphers have
      been disabled, provided that the SSLv2 protocol was not also disabled via
      SSL_OP_NO_SSLv2.
 
      This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram
      and Sebastian Schinzel.
      (CVE-2015-3197)
      [Viktor Dukhovni]
 
   *) Reject DH handshakes with parameters shorter than 1024 bits.
      [Kurt Roeckx]
 
  Changes between 1.0.1p and 1.0.1q [3 Dec 2015]
 
   *) Certificate verify crash with missing PSS parameter
 
      The signature verification routines will crash with a NULL pointer
      dereference if presented with an ASN.1 signature using the RSA PSS
      algorithm and absent mask generation function parameter. Since these
      routines are used to verify certificate signature algorithms this can be
      used to crash any certificate verification operation and exploited in a
      DoS attack. Any application which performs certificate verification is
      vulnerable including OpenSSL clients and servers which enable client
      authentication.
 
      This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG).
      (CVE-2015-3194)
      [Stephen Henson]
 
   *) X509_ATTRIBUTE memory leak
 
      When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak
      memory. This structure is used by the PKCS#7 and CMS routines so any
      application which reads PKCS#7 or CMS data from untrusted sources is
      affected. SSL/TLS is not affected.
 
      This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using
      libFuzzer.
      (CVE-2015-3195)
      [Stephen Henson]
 
   *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs.
      This changes the decoding behaviour for some invalid messages,
      though the change is mostly in the more lenient direction, and
      legacy behaviour is preserved as much as possible.
      [Emilia Käsper]
 
   *) In DSA_generate_parameters_ex, if the provided seed is too short,
      use a random seed, as already documented.
      [Rich Salz and Ismo Puustinen <ismo.puustinen@intel.com>]
 
  Changes between 1.0.1o and 1.0.1p [9 Jul 2015]
 
   *) Alternate chains certificate forgery
 
      During certificate verfification, OpenSSL will attempt to find an
      alternative certificate chain if the first attempt to build such a chain
      fails. An error in the implementation of this logic can mean that an
      attacker could cause certain checks on untrusted certificates to be
      bypassed, such as the CA flag, enabling them to use a valid leaf
      certificate to act as a CA and "issue" an invalid certificate.
 
      This issue was reported to OpenSSL by Adam Langley/David Benjamin
      (Google/BoringSSL).
      (CVE-2015-1793)
      [Matt Caswell]
 
   *) Race condition handling PSK identify hint
 
      If PSK identity hints are received by a multi-threaded client then
      the values are wrongly updated in the parent SSL_CTX structure. This can
      result in a race condition potentially leading to a double free of the
      identify hint data.
      (CVE-2015-3196)
      [Stephen Henson]
 
  Changes between 1.0.1n and 1.0.1o [12 Jun 2015]
   *) Fix HMAC ABI incompatibility. The previous version introduced an ABI
      incompatibility in the handling of HMAC. The previous ABI has now been
      restored.
 
  Changes between 1.0.1m and 1.0.1n [11 Jun 2015]
 
   *) Malformed ECParameters causes infinite loop
 
      When processing an ECParameters structure OpenSSL enters an infinite loop
      if the curve specified is over a specially malformed binary polynomial
      field.
 
      This can be used to perform denial of service against any
      system which processes public keys, certificate requests or
      certificates.  This includes TLS clients and TLS servers with
      client authentication enabled.
 
      This issue was reported to OpenSSL by Joseph Barr-Pixton.
      (CVE-2015-1788)
      [Andy Polyakov]
 
   *) Exploitable out-of-bounds read in X509_cmp_time
 
      X509_cmp_time does not properly check the length of the ASN1_TIME
      string and can read a few bytes out of bounds. In addition,
      X509_cmp_time accepts an arbitrary number of fractional seconds in the
      time string.
 
      An attacker can use this to craft malformed certificates and CRLs of
      various sizes and potentially cause a segmentation fault, resulting in
      a DoS on applications that verify certificates or CRLs. TLS clients
      that verify CRLs are affected. TLS clients and servers with client
      authentication enabled may be affected if they use custom verification
      callbacks.
 
      This issue was reported to OpenSSL by Robert Swiecki (Google), and
      independently by Hanno Böck.
      (CVE-2015-1789)
      [Emilia Käsper]
 
   *) PKCS7 crash with missing EnvelopedContent
 
      The PKCS#7 parsing code does not handle missing inner EncryptedContent
      correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs
      with missing content and trigger a NULL pointer dereference on parsing.
 
      Applications that decrypt PKCS#7 data or otherwise parse PKCS#7
      structures from untrusted sources are affected. OpenSSL clients and
      servers are not affected.
 
      This issue was reported to OpenSSL by Michal Zalewski (Google).
      (CVE-2015-1790)
      [Emilia Käsper]
 
   *) CMS verify infinite loop with unknown hash function
 
      When verifying a signedData message the CMS code can enter an infinite loop
      if presented with an unknown hash function OID. This can be used to perform
      denial of service against any system which verifies signedData messages using
      the CMS code.
      This issue was reported to OpenSSL by Johannes Bauer.
      (CVE-2015-1792)
      [Stephen Henson]
 
   *) Race condition handling NewSessionTicket
 
      If a NewSessionTicket is received by a multi-threaded client when attempting to
      reuse a previous ticket then a race condition can occur potentially leading to
      a double free of the ticket data.
      (CVE-2015-1791)
      [Matt Caswell]
 
   *) Reject DH handshakes with parameters shorter than 768 bits.
      [Kurt Roeckx and Emilia Kasper]
 
   *) dhparam: generate 2048-bit parameters by default.
      [Kurt Roeckx and Emilia Kasper]
 
  Changes between 1.0.1l and 1.0.1m [19 Mar 2015]
 
   *) Segmentation fault in ASN1_TYPE_cmp fix
 
      The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is
      made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check
      certificate signature algorithm consistency this can be used to crash any
      certificate verification operation and exploited in a DoS attack. Any
      application which performs certificate verification is vulnerable including
      OpenSSL clients and servers which enable client authentication.
      (CVE-2015-0286)
      [Stephen Henson]
 
   *) ASN.1 structure reuse memory corruption fix
 
      Reusing a structure in ASN.1 parsing may allow an attacker to cause
      memory corruption via an invalid write. Such reuse is and has been
      strongly discouraged and is believed to be rare.
 
      Applications that parse structures containing CHOICE or ANY DEFINED BY
      components may be affected. Certificate parsing (d2i_X509 and related
      functions) are however not affected. OpenSSL clients and servers are
      not affected.
      (CVE-2015-0287)
      [Stephen Henson]
 
   *) PKCS7 NULL pointer dereferences fix
 
      The PKCS#7 parsing code does not handle missing outer ContentInfo
      correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with
      missing content and trigger a NULL pointer dereference on parsing.
 
      Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or
      otherwise parse PKCS#7 structures from untrusted sources are
      affected. OpenSSL clients and servers are not affected.
 
      This issue was reported to OpenSSL by Michal Zalewski (Google).
      (CVE-2015-0289)
      [Emilia Käsper]
 
   *) DoS via reachable assert in SSLv2 servers fix
 
      A malicious client can trigger an OPENSSL_assert (i.e., an abort) in
      servers that both support SSLv2 and enable export cipher suites by sending
      a specially crafted SSLv2 CLIENT-MASTER-KEY message.
 
      This issue was discovered by Sean Burford (Google) and Emilia Käsper
      (OpenSSL development team).
      (CVE-2015-0293)
      [Emilia Käsper]
 
   *) Use After Free following d2i_ECPrivatekey error fix
 
      A malformed EC private key file consumed via the d2i_ECPrivateKey function
      could cause a use after free condition. This, in turn, could cause a double
      free in several private key parsing functions (such as d2i_PrivateKey
      or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption
      for applications that receive EC private keys from untrusted
      sources. This scenario is considered rare.
 
      This issue was discovered by the BoringSSL project and fixed in their
      commit 517073cd4b.
      (CVE-2015-0209)
      [Matt Caswell]
 
   *) X509_to_X509_REQ NULL pointer deref fix
 
      The function X509_to_X509_REQ will crash with a NULL pointer dereference if
      the certificate key is invalid. This function is rarely used in practice.
 
      This issue was discovered by Brian Carpenter.
      (CVE-2015-0288)
      [Stephen Henson]
 
   *) Removed the export ciphers from the DEFAULT ciphers
      [Kurt Roeckx]
 
  Changes between 1.0.1k and 1.0.1l [15 Jan 2015]
 
   *) Build fixes for the Windows and OpenVMS platforms
      [Matt Caswell and Richard Levitte]
 
  Changes between 1.0.1j and 1.0.1k [8 Jan 2015]
 
   *) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS
      message can cause a segmentation fault in OpenSSL due to a NULL pointer
      dereference. This could lead to a Denial Of Service attack. Thanks to
      Markus Stenberg of Cisco Systems, Inc. for reporting this issue.
      (CVE-2014-3571)
      [Steve Henson]
 
   *) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the
      dtls1_buffer_record function under certain conditions. In particular this
      could occur if an attacker sent repeated DTLS records with the same
      sequence number but for the next epoch. The memory leak could be exploited
      by an attacker in a Denial of Service attack through memory exhaustion.
      Thanks to Chris Mueller for reporting this issue.
      (CVE-2015-0206)
      [Matt Caswell]
 
   *) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is
      built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl
      method would be set to NULL which could later result in a NULL pointer
      dereference. Thanks to Frank Schmirler for reporting this issue.
      (CVE-2014-3569)
      [Kurt Roeckx]
 
   *) Abort handshake if server key exchange message is omitted for ephemeral
      ECDH ciphersuites.
 
      Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for
      reporting this issue.
      (CVE-2014-3572)
      [Steve Henson]
 
   *) Remove non-export ephemeral RSA code on client and server. This code
      violated the TLS standard by allowing the use of temporary RSA keys in
      non-export ciphersuites and could be used by a server to effectively
      downgrade the RSA key length used to a value smaller than the server
      certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at
      INRIA or reporting this issue.
      (CVE-2015-0204)
      [Steve Henson]
 
   *) Fixed issue where DH client certificates are accepted without verification.
      An OpenSSL server will accept a DH certificate for client authentication
      without the certificate verify message. This effectively allows a client to
      authenticate without the use of a private key. This only affects servers
      which trust a client certificate authority which issues certificates
      containing DH keys: these are extremely rare and hardly ever encountered.
      Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting
      this issue.
      (CVE-2015-0205)
      [Steve Henson]
 
   *) Ensure that the session ID context of an SSL is updated when its
      SSL_CTX is updated via SSL_set_SSL_CTX.
 
      The session ID context is typically set from the parent SSL_CTX,
      and can vary with the CTX.
      [Adam Langley]
 
   *) Fix various certificate fingerprint issues.
 
      By using non-DER or invalid encodings outside the signed portion of a
      certificate the fingerprint can be changed without breaking the signature.
      Although no details of the signed portion of the certificate can be changed
      this can cause problems with some applications: e.g. those using the
      certificate fingerprint for blacklists.
 
      1. Reject signatures with non zero unused bits.
 
      If the BIT STRING containing the signature has non zero unused bits reject
      the signature. All current signature algorithms require zero unused bits.
 
      2. Check certificate algorithm consistency.
 
      Check the AlgorithmIdentifier inside TBS matches the one in the
      certificate signature. NB: this will result in signature failure
      errors for some broken certificates.
 
      Thanks to Konrad Kraszewski from Google for reporting this issue.
 
      3. Check DSA/ECDSA signatures use DER.
 
      Reencode DSA/ECDSA signatures and compare with the original received
      signature. Return an error if there is a mismatch.
 
      This will reject various cases including garbage after signature
      (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS
      program for discovering this case) and use of BER or invalid ASN.1 INTEGERs
      (negative or with leading zeroes).
 
      Further analysis was conducted and fixes were developed by Stephen Henson
      of the OpenSSL core team.
 
      (CVE-2014-8275)
      [Steve Henson]
 
    *) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect
       results on some platforms, including x86_64. This bug occurs at random
       with a very low probability, and is not known to be exploitable in any
       way, though its exact impact is difficult to determine. Thanks to Pieter
       Wuille (Blockstream) who reported this issue and also suggested an initial
       fix. Further analysis was conducted by the OpenSSL development team and
       Adam Langley of Google. The final fix was developed by Andy Polyakov of
       the OpenSSL core team.
       (CVE-2014-3570)
       [Andy Polyakov]
 
    *) Do not resume sessions on the server if the negotiated protocol
       version does not match the session's version. Resuming with a different
       version, while not strictly forbidden by the RFC, is of questionable
       sanity and breaks all known clients.
       [David Benjamin, Emilia Käsper]
 
    *) Tighten handling of the ChangeCipherSpec (CCS) message: reject
       early CCS messages during renegotiation. (Note that because
       renegotiation is encrypted, this early CCS was not exploitable.)
       [Emilia Käsper]
 
    *) Tighten client-side session ticket handling during renegotiation:
       ensure that the client only accepts a session ticket if the server sends
       the extension anew in the ServerHello. Previously, a TLS client would
       reuse the old extension state and thus accept a session ticket if one was
       announced in the initial ServerHello.
 
       Similarly, ensure that the client requires a session ticket if one
       was advertised in the ServerHello. Previously, a TLS client would
       ignore a missing NewSessionTicket message.
       [Emilia Käsper]
 
  Changes between 1.0.1i and 1.0.1j [15 Oct 2014]
 
   *) SRTP Memory Leak.
 
      A flaw in the DTLS SRTP extension parsing code allows an attacker, who
      sends a carefully crafted handshake message, to cause OpenSSL to fail
      to free up to 64k of memory causing a memory leak. This could be
      exploited in a Denial Of Service attack. This issue affects OpenSSL
      1.0.1 server implementations for both SSL/TLS and DTLS regardless of
      whether SRTP is used or configured. Implementations of OpenSSL that
      have been compiled with OPENSSL_NO_SRTP defined are not affected.
 
      The fix was developed by the OpenSSL team.
      (CVE-2014-3513)
      [OpenSSL team]
 
   *) Session Ticket Memory Leak.
 
      When an OpenSSL SSL/TLS/DTLS server receives a session ticket the
      integrity of that ticket is first verified. In the event of a session
      ticket integrity check failing, OpenSSL will fail to free memory
      causing a memory leak. By sending a large number of invalid session
      tickets an attacker could exploit this issue in a Denial Of Service
      attack.
      (CVE-2014-3567)
      [Steve Henson]
 
   *) Build option no-ssl3 is incomplete.
 
      When OpenSSL is configured with "no-ssl3" as a build option, servers
      could accept and complete a SSL 3.0 handshake, and clients could be
      configured to send them.
      (CVE-2014-3568)
      [Akamai and the OpenSSL team]
 
   *) Add support for TLS_FALLBACK_SCSV.
      Client applications doing fallback retries should call
      SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV).
      (CVE-2014-3566)
      [Adam Langley, Bodo Moeller]
 
   *) Add additional DigestInfo checks.
  
      Reencode DigestInto in DER and check against the original when
      verifying RSA signature: this will reject any improperly encoded
      DigestInfo structures.
 
      Note: this is a precautionary measure and no attacks are currently known.
 
      [Steve Henson]
 
  Changes between 1.0.1h and 1.0.1i [6 Aug 2014]
 
   *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the
      SRP code can be overrun an internal buffer. Add sanity check that
      g, A, B < N to SRP code.
 
      Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC
      Group for discovering this issue.
      (CVE-2014-3512)
      [Steve Henson]
 
   *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate
      TLS 1.0 instead of higher protocol versions when the ClientHello message
      is badly fragmented. This allows a man-in-the-middle attacker to force a
      downgrade to TLS 1.0 even if both the server and the client support a
      higher protocol version, by modifying the client's TLS records.
 
      Thanks to David Benjamin and Adam Langley (Google) for discovering and
      researching this issue.
      (CVE-2014-3511)
      [David Benjamin]
 
   *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject
      to a denial of service attack. A malicious server can crash the client
      with a null pointer dereference (read) by specifying an anonymous (EC)DH
      ciphersuite and sending carefully crafted handshake messages.
 
      Thanks to Felix Gröbert (Google) for discovering and researching this
      issue.
      (CVE-2014-3510)
      [Emilia Käsper]
 
   *) By sending carefully crafted DTLS packets an attacker could cause openssl
      to leak memory. This can be exploited through a Denial of Service attack.
      Thanks to Adam Langley for discovering and researching this issue.
      (CVE-2014-3507)
      [Adam Langley]
 
   *) An attacker can force openssl to consume large amounts of memory whilst
      processing DTLS handshake messages. This can be exploited through a
      Denial of Service attack.
      Thanks to Adam Langley for discovering and researching this issue.
      (CVE-2014-3506)
      [Adam Langley]
 
   *) An attacker can force an error condition which causes openssl to crash
      whilst processing DTLS packets due to memory being freed twice. This
      can be exploited through a Denial of Service attack.
      Thanks to Adam Langley and Wan-Teh Chang for discovering and researching
      this issue.
      (CVE-2014-3505)
      [Adam Langley]
 
   *) If a multithreaded client connects to a malicious server using a resumed
      session and the server sends an ec point format extension it could write
      up to 255 bytes to freed memory.
 
      Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this
      issue.
      (CVE-2014-3509)
      [Gabor Tyukasz]
 
   *) A malicious server can crash an OpenSSL client with a null pointer
      dereference (read) by specifying an SRP ciphersuite even though it was not
      properly negotiated with the client. This can be exploited through a
      Denial of Service attack.
 
      Thanks to Joonas Kuorilehto and Riku Hietamäki (Codenomicon) for
      discovering and researching this issue.
      (CVE-2014-5139)
      [Steve Henson]
 
   *) A flaw in OBJ_obj2txt may cause pretty printing functions such as
      X509_name_oneline, X509_name_print_ex et al. to leak some information
      from the stack. Applications may be affected if they echo pretty printing
      output to the attacker.
 
      Thanks to Ivan Fratric (Google) for discovering this issue.
      (CVE-2014-3508)
      [Emilia Käsper, and Steve Henson]
 
   *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.)
      for corner cases. (Certain input points at infinity could lead to
      bogus results, with non-infinity inputs mapped to infinity too.)
      [Bodo Moeller]
 
  Changes between 1.0.1g and 1.0.1h [5 Jun 2014]
 
   *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted
      handshake can force the use of weak keying material in OpenSSL
      SSL/TLS clients and servers.
 
      Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and
      researching this issue. (CVE-2014-0224)
      [KIKUCHI Masashi, Steve Henson]
 
   *) Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an
      OpenSSL DTLS client the code can be made to recurse eventually crashing
      in a DoS attack.
 
      Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue.
      (CVE-2014-0221)
      [Imre Rad, Steve Henson]
 
   *) Fix DTLS invalid fragment vulnerability. A buffer overrun attack can
      be triggered by sending invalid DTLS fragments to an OpenSSL DTLS
      client or server. This is potentially exploitable to run arbitrary
      code on a vulnerable client or server.
 
      Thanks to Jüri Aedla for reporting this issue. (CVE-2014-0195)
      [Jüri Aedla, Steve Henson]
 
   *) Fix bug in TLS code where clients enable anonymous ECDH ciphersuites
      are subject to a denial of service attack.
 
      Thanks to Felix Gröbert and Ivan Fratric at Google for discovering
      this issue. (CVE-2014-3470)
      [Felix Gröbert, Ivan Fratric, Steve Henson]
 
   *) Harmonize version and its documentation. -f flag is used to display
      compilation flags.
      [mancha <mancha1@zoho.com>]
 
   *) Fix eckey_priv_encode so it immediately returns an error upon a failure
      in i2d_ECPrivateKey.
      [mancha <mancha1@zoho.com>]
 
   *) Fix some double frees. These are not thought to be exploitable.
      [mancha <mancha1@zoho.com>]
 
  Changes between 1.0.1f and 1.0.1g [7 Apr 2014]
 
   *) A missing bounds check in the handling of the TLS heartbeat extension
      can be used to reveal up to 64k of memory to a connected client or
      server.
 
      Thanks for Neel Mehta of Google Security for discovering this bug and to
      Adam Langley <agl@chromium.org> and Bodo Moeller <bmoeller@acm.org> for
      preparing the fix (CVE-2014-0160)
      [Adam Langley, Bodo Moeller]
 
   *) Fix for the attack described in the paper "Recovering OpenSSL
      ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack"
      by Yuval Yarom and Naomi Benger. Details can be obtained from:
      http://eprint.iacr.org/2014/140
 
      Thanks to Yuval Yarom and Naomi Benger for discovering this
      flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076)
      [Yuval Yarom and Naomi Benger]
 
   *) TLS pad extension: draft-agl-tls-padding-03
 
      Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the
      TLS client Hello record length value would otherwise be > 255 and
      less that 512 pad with a dummy extension containing zeroes so it
      is at least 512 bytes long.
 
      [Adam Langley, Steve Henson]
 
  Changes between 1.0.1e and 1.0.1f [6 Jan 2014]
 
   *) Fix for TLS record tampering bug. A carefully crafted invalid 
      handshake could crash OpenSSL with a NULL pointer exception.
      Thanks to Anton Johansson for reporting this issues.
      (CVE-2013-4353)
 
   *) Keep original DTLS digest and encryption contexts in retransmission
      structures so we can use the previous session parameters if they need
      to be resent. (CVE-2013-6450)
      [Steve Henson]
 
   *) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which
      avoids preferring ECDHE-ECDSA ciphers when the client appears to be
      Safari on OS X.  Safari on OS X 10.8..10.8.3 advertises support for
      several ECDHE-ECDSA ciphers, but fails to negotiate them.  The bug
      is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing
      10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer.
      [Rob Stradling, Adam Langley]
 
  Changes between 1.0.1d and 1.0.1e [11 Feb 2013]
 
   *) Correct fix for CVE-2013-0169. The original didn't work on AES-NI
      supporting platforms or when small records were transferred.
      [Andy Polyakov, Steve Henson]
 
  Changes between 1.0.1c and 1.0.1d [5 Feb 2013]
 
   *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time.
 
      This addresses the flaw in CBC record processing discovered by 
      Nadhem Alfardan and Kenny Paterson. Details of this attack can be found
      at: http://www.isg.rhul.ac.uk/tls/     
 
      Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
      Security Group at Royal Holloway, University of London
      (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and
      Emilia Käsper for the initial patch.
      (CVE-2013-0169)
      [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson]
 
   *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode
      ciphersuites which can be exploited in a denial of service attack.
      Thanks go to and to Adam Langley <agl@chromium.org> for discovering
      and detecting this bug and to Wolfgang Ettlinger
      <wolfgang.ettlinger@gmail.com> for independently discovering this issue.
      (CVE-2012-2686)
      [Adam Langley]
 
   *) Return an error when checking OCSP signatures when key is NULL.
      This fixes a DoS attack. (CVE-2013-0166)
      [Steve Henson]
 
   *) Make openssl verify return errors.
      [Chris Palmer <palmer@google.com> and Ben Laurie]
 
   *) Call OCSP Stapling callback after ciphersuite has been chosen, so
      the right response is stapled. Also change SSL_get_certificate()
      so it returns the certificate actually sent.
      See http://rt.openssl.org/Ticket/Display.html?id=2836.
      [Rob Stradling <rob.stradling@comodo.com>]
 
   *) Fix possible deadlock when decoding public keys.
      [Steve Henson]
 
   *) Don't use TLS 1.0 record version number in initial client hello
      if renegotiating.
      [Steve Henson]
 
  Changes between 1.0.1b and 1.0.1c [10 May 2012]
 
   *) Sanity check record length before skipping explicit IV in TLS
      1.2, 1.1 and DTLS to fix DoS attack.
 
      Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic
      fuzzing as a service testing platform.
      (CVE-2012-2333)
      [Steve Henson]
 
   *) Initialise tkeylen properly when encrypting CMS messages.
      Thanks to Solar Designer of Openwall for reporting this issue.
      [Steve Henson]
 
   *) In FIPS mode don't try to use composite ciphers as they are not
      approved.
      [Steve Henson]
 
  Changes between 1.0.1a and 1.0.1b [26 Apr 2012]
 
   *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and
      1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately
      mean any application compiled against OpenSSL 1.0.0 headers setting
      SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng
      TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to
      0x10000000L Any application which was previously compiled against
      OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1
      will need to be recompiled as a result. Letting be results in
      inability to disable specifically TLS 1.1 and in client context,
      in unlike event, limit maximum offered version to TLS 1.0 [see below].
      [Steve Henson]
 
   *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not
      disable just protocol X, but all protocols above X *if* there are
      protocols *below* X still enabled. In more practical terms it means
      that if application wants to disable TLS1.0 in favor of TLS1.1 and
      above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass
      SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to
      client side.
      [Andy Polyakov]
 
  Changes between 1.0.1 and 1.0.1a [19 Apr 2012]
 
   *) Check for potentially exploitable overflows in asn1_d2i_read_bio
      BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer
      in CRYPTO_realloc_clean.
 
      Thanks to Tavis Ormandy, Google Security Team, for discovering this
      issue and to Adam Langley <agl@chromium.org> for fixing it.
      (CVE-2012-2110)
      [Adam Langley (Google), Tavis Ormandy, Google Security Team]
 
   *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
      [Adam Langley]
 
   *) Workarounds for some broken servers that "hang" if a client hello
      record length exceeds 255 bytes.
 
      1. Do not use record version number > TLS 1.0 in initial client
         hello: some (but not all) hanging servers will now work.
      2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate
 	the number of ciphers sent in the client hello. This should be
         set to an even number, such as 50, for example by passing:
         -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure.
         Most broken servers should now work.
      3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable
 	TLS 1.2 client support entirely.
      [Steve Henson]
 
   *) Fix SEGV in Vector Permutation AES module observed in OpenSSH.
      [Andy Polyakov]
 
  Changes between 1.0.0h and 1.0.1  [14 Mar 2012]
 
   *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET
      STRING form instead of a DigestInfo.
      [Steve Henson]
 
   *) The format used for MDC2 RSA signatures is inconsistent between EVP
      and the RSA_sign/RSA_verify functions. This was made more apparent when
      OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular
      those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect 
      the correct format in RSA_verify so both forms transparently work.
      [Steve Henson]
 
   *) Some servers which support TLS 1.0 can choke if we initially indicate
      support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
      encrypted premaster secret. As a workaround use the maximum pemitted
      client version in client hello, this should keep such servers happy
      and still work with previous versions of OpenSSL.
      [Steve Henson]
 
   *) Add support for TLS/DTLS heartbeats.
      [Robin Seggelmann <seggelmann@fh-muenster.de>]
 
   *) Add support for SCTP.
      [Robin Seggelmann <seggelmann@fh-muenster.de>]
 
   *) Improved PRNG seeding for VOS.
      [Paul Green <Paul.Green@stratus.com>]
 
   *) Extensive assembler packs updates, most notably:
 
 	- x86[_64]:     AES-NI, PCLMULQDQ, RDRAND support;
 	- x86[_64]:     SSSE3 support (SHA1, vector-permutation AES);
 	- x86_64:       bit-sliced AES implementation;
 	- ARM:          NEON support, contemporary platforms optimizations;
 	- s390x:        z196 support;
 	- *:            GHASH and GF(2^m) multiplication implementations;
 
      [Andy Polyakov]
 
   *) Make TLS-SRP code conformant with RFC 5054 API cleanup
      (removal of unnecessary code)
      [Peter Sylvester <peter.sylvester@edelweb.fr>]
 
   *) Add TLS key material exporter from RFC 5705.
      [Eric Rescorla]
 
   *) Add DTLS-SRTP negotiation from RFC 5764.
      [Eric Rescorla]
 
   *) Add Next Protocol Negotiation,
      http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be
      disabled with a no-npn flag to config or Configure. Code donated
      by Google.
      [Adam Langley <agl@google.com> and Ben Laurie]
 
   *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224,
      NIST-P256, NIST-P521, with constant-time single point multiplication on
      typical inputs. Compiler support for the nonstandard type __uint128_t is
      required to use this (present in gcc 4.4 and later, for 64-bit builds).
      Code made available under Apache License version 2.0.
 
      Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command
      line to include this in your build of OpenSSL, and run "make depend" (or
      "make update"). This enables the following EC_METHODs:
 
          EC_GFp_nistp224_method()
          EC_GFp_nistp256_method()
          EC_GFp_nistp521_method()
 
      EC_GROUP_new_by_curve_name() will automatically use these (while
      EC_GROUP_new_curve_GFp() currently prefers the more flexible
      implementations).
      [Emilia Käsper, Adam Langley, Bodo Moeller (Google)]
 
   *) Use type ossl_ssize_t instad of ssize_t which isn't available on
      all platforms. Move ssize_t definition from e_os.h to the public
      header file e_os2.h as it now appears in public header file cms.h
      [Steve Henson]
 
   *) New -sigopt option to the ca, req and x509 utilities. Additional
      signature parameters can be passed using this option and in
      particular PSS. 
      [Steve Henson]
 
   *) Add RSA PSS signing function. This will generate and set the
      appropriate AlgorithmIdentifiers for PSS based on those in the
      corresponding EVP_MD_CTX structure. No application support yet.
      [Steve Henson]
 
   *) Support for companion algorithm specific ASN1 signing routines.
      New function ASN1_item_sign_ctx() signs a pre-initialised
      EVP_MD_CTX structure and sets AlgorithmIdentifiers based on
      the appropriate parameters.
      [Steve Henson]
 
   *) Add new algorithm specific ASN1 verification initialisation function
      to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1
      handling will be the same no matter what EVP_PKEY_METHOD is used.
      Add a PSS handler to support verification of PSS signatures: checked
      against a number of sample certificates.
      [Steve Henson]
 
   *) Add signature printing for PSS. Add PSS OIDs.
      [Steve Henson, Martin Kaiser <lists@kaiser.cx>]
 
   *) Add algorithm specific signature printing. An individual ASN1 method
      can now print out signatures instead of the standard hex dump. 
 
      More complex signatures (e.g. PSS) can print out more meaningful
      information. Include DSA version that prints out the signature
      parameters r, s.
      [Steve Henson]
 
   *) Password based recipient info support for CMS library: implementing
      RFC3211.
      [Steve Henson]
 
   *) Split password based encryption into PBES2 and PBKDF2 functions. This
      neatly separates the code into cipher and PBE sections and is required
      for some algorithms that split PBES2 into separate pieces (such as
      password based CMS).
      [Steve Henson]
 
   *) Session-handling fixes:
      - Fix handling of connections that are resuming with a session ID,
        but also support Session Tickets.
      - Fix a bug that suppressed issuing of a new ticket if the client
        presented a ticket with an expired session.
      - Try to set the ticket lifetime hint to something reasonable.
      - Make tickets shorter by excluding irrelevant information.
      - On the client side, don't ignore renewed tickets.
      [Adam Langley, Bodo Moeller (Google)]
 
   *) Fix PSK session representation.
      [Bodo Moeller]
 
   *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations.
 
      This work was sponsored by Intel.
      [Andy Polyakov]
 
   *) Add GCM support to TLS library. Some custom code is needed to split
      the IV between the fixed (from PRF) and explicit (from TLS record)
      portions. This adds all GCM ciphersuites supported by RFC5288 and 
      RFC5289. Generalise some AES* cipherstrings to inlclude GCM and
      add a special AESGCM string for GCM only.
      [Steve Henson]
 
   *) Expand range of ctrls for AES GCM. Permit setting invocation
      field on decrypt and retrieval of invocation field only on encrypt.
      [Steve Henson]
 
   *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support.
      As required by RFC5289 these ciphersuites cannot be used if for
      versions of TLS earlier than 1.2.
      [Steve Henson]
 
   *) For FIPS capable OpenSSL interpret a NULL default public key method
      as unset and return the appopriate default but do *not* set the default.
      This means we can return the appopriate method in applications that
      swicth between FIPS and non-FIPS modes.
      [Steve Henson]
 
   *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an
      ENGINE is used then we cannot handle that in the FIPS module so we
      keep original code iff non-FIPS operations are allowed.
      [Steve Henson]
 
   *) Add -attime option to openssl utilities.
      [Peter Eckersley <pde@eff.org>, Ben Laurie and Steve Henson]
 
   *) Redirect DSA and DH operations to FIPS module in FIPS mode.
      [Steve Henson]
 
   *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use
      FIPS EC methods unconditionally for now.
      [Steve Henson]
 
   *) New build option no-ec2m to disable characteristic 2 code.
      [Steve Henson]
 
   *) Backport libcrypto audit of return value checking from 1.1.0-dev; not
      all cases can be covered as some introduce binary incompatibilities.
      [Steve Henson]
 
   *) Redirect RSA operations to FIPS module including keygen,
      encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods.
      [Steve Henson]
 
   *) Add similar low level API blocking to ciphers.
      [Steve Henson]
 
   *) Low level digest APIs are not approved in FIPS mode: any attempt
      to use these will cause a fatal error. Applications that *really* want
      to use them can use the private_* version instead.
      [Steve Henson]
 
   *) Redirect cipher operations to FIPS module for FIPS builds. 
      [Steve Henson]
 
   *) Redirect digest operations to FIPS module for FIPS builds. 
      [Steve Henson]
 
   *) Update build system to add "fips" flag which will link in fipscanister.o
      for static and shared library builds embedding a signature if needed.
      [Steve Henson]
 
   *) Output TLS supported curves in preference order instead of numerical
      order. This is currently hardcoded for the highest order curves first.
      This should be configurable so applications can judge speed vs strength.
      [Steve Henson]
 
   *) Add TLS v1.2 server support for client authentication. 
      [Steve Henson]
 
   *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers
      and enable MD5.
      [Steve Henson]
 
   *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying
      FIPS modules versions.
      [Steve Henson]
 
   *) Add TLS v1.2 client side support for client authentication. Keep cache
      of handshake records longer as we don't know the hash algorithm to use
      until after the certificate request message is received.
      [Steve Henson]
 
   *) Initial TLS v1.2 client support. Add a default signature algorithms
      extension including all the algorithms we support. Parse new signature
      format in client key exchange. Relax some ECC signing restrictions for
      TLS v1.2 as indicated in RFC5246.
      [Steve Henson]
 
   *) Add server support for TLS v1.2 signature algorithms extension. Switch
      to new signature format when needed using client digest preference.
      All server ciphersuites should now work correctly in TLS v1.2. No client
      support yet and no support for client certificates.
      [Steve Henson]
 
   *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch
      to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based
      ciphersuites. At present only RSA key exchange ciphersuites work with
      TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete
      SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods
      and version checking.
      [Steve Henson]
 
   *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled
      with this defined it will not be affected by any changes to ssl internal
      structures. Add several utility functions to allow openssl application
      to work with OPENSSL_NO_SSL_INTERN defined.
      [Steve Henson]
 
   *) Add SRP support.
      [Tom Wu <tjw@cs.stanford.edu> and Ben Laurie]
 
   *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id.
      [Steve Henson]
 
   *) Permit abbreviated handshakes when renegotiating using the function
      SSL_renegotiate_abbreviated().
      [Robin Seggelmann <seggelmann@fh-muenster.de>]
 
   *) Add call to ENGINE_register_all_complete() to
      ENGINE_load_builtin_engines(), so some implementations get used
      automatically instead of needing explicit application support.
      [Steve Henson]
 
   *) Add support for TLS key exporter as described in RFC5705.
      [Robin Seggelmann <seggelmann@fh-muenster.de>, Steve Henson]
 
   *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only
      a few changes are required:
 
        Add SSL_OP_NO_TLSv1_1 flag.
        Add TLSv1_1 methods.
        Update version checking logic to handle version 1.1.
        Add explicit IV handling (ported from DTLS code).
        Add command line options to s_client/s_server.
      [Steve Henson]
 
  Changes between 1.0.0g and 1.0.0h [12 Mar 2012]
 
   *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness
      in CMS and PKCS7 code. When RSA decryption fails use a random key for
      content decryption and always return the same error. Note: this attack
      needs on average 2^20 messages so it only affects automated senders. The
      old behaviour can be reenabled in the CMS code by setting the
      CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where
      an MMA defence is not necessary.
      Thanks to Ivan Nestlerode <inestlerode@us.ibm.com> for discovering
      this issue. (CVE-2012-0884)
      [Steve Henson]
 
   *) Fix CVE-2011-4619: make sure we really are receiving a 
      client hello before rejecting multiple SGC restarts. Thanks to
      Ivan Nestlerode <inestlerode@us.ibm.com> for discovering this bug.
      [Steve Henson]
 
  Changes between 1.0.0f and 1.0.0g [18 Jan 2012]
 
   *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109.
      Thanks to Antonio Martin, Enterprise Secure Access Research and
      Development, Cisco Systems, Inc. for discovering this bug and
      preparing a fix. (CVE-2012-0050)
      [Antonio Martin]
 
  Changes between 1.0.0e and 1.0.0f [4 Jan 2012]
 
   *) Nadhem Alfardan and Kenny Paterson have discovered an extension
      of the Vaudenay padding oracle attack on CBC mode encryption
      which enables an efficient plaintext recovery attack against
      the OpenSSL implementation of DTLS. Their attack exploits timing
      differences arising during decryption processing. A research
      paper describing this attack can be found at:
                   http://www.isg.rhul.ac.uk/~kp/dtls.pdf
      Thanks go to Nadhem Alfardan and Kenny Paterson of the Information
      Security Group at Royal Holloway, University of London
      (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann
      <seggelmann@fh-muenster.de> and Michael Tuexen <tuexen@fh-muenster.de>
      for preparing the fix. (CVE-2011-4108)
      [Robin Seggelmann, Michael Tuexen]
 
   *) Clear bytes used for block padding of SSL 3.0 records.
      (CVE-2011-4576)
      [Adam Langley (Google)]
 
   *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George
      Kadianakis <desnacked@gmail.com> for discovering this issue and
      Adam Langley for preparing the fix. (CVE-2011-4619)
      [Adam Langley (Google)]
 
   *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027)
      [Andrey Kulikov <amdeich@gmail.com>]
 
   *) Prevent malformed RFC3779 data triggering an assertion failure.
      Thanks to Andrew Chi, BBN Technologies, for discovering the flaw
      and Rob Austein <sra@hactrn.net> for fixing it. (CVE-2011-4577)
      [Rob Austein <sra@hactrn.net>]
 
   *) Improved PRNG seeding for VOS.
      [Paul Green <Paul.Green@stratus.com>]
 
   *) Fix ssl_ciph.c set-up race.
      [Adam Langley (Google)]
 
   *) Fix spurious failures in ecdsatest.c.
      [Emilia Käsper (Google)]
 
   *) Fix the BIO_f_buffer() implementation (which was mixing different
      interpretations of the '..._len' fields).
      [Adam Langley (Google)]
 
   *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than
      BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent
      threads won't reuse the same blinding coefficients.
 
      This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING
      lock to call BN_BLINDING_invert_ex, and avoids one use of
      BN_BLINDING_update for each BN_BLINDING structure (previously,
      the last update always remained unused).
      [Emilia Käsper (Google)]
 
   *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf.
      [Bob Buckholz (Google)]
 
  Changes between 1.0.0d and 1.0.0e [6 Sep 2011]
 
   *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted
      by initialising X509_STORE_CTX properly. (CVE-2011-3207)
      [Kaspar Brand <ossl@velox.ch>]
 
   *) Fix SSL memory handling for (EC)DH ciphersuites, in particular
      for multi-threaded use of ECDH. (CVE-2011-3210)
      [Adam Langley (Google)]
 
   *) Fix x509_name_ex_d2i memory leak on bad inputs.
      [Bodo Moeller]
 
   *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check
      signature public key algorithm by using OID xref utilities instead.
      Before this you could only use some ECC ciphersuites with SHA1 only.
      [Steve Henson]
 
   *) Add protection against ECDSA timing attacks as mentioned in the paper
      by Billy Bob Brumley and Nicola Tuveri, see:
 
 	http://eprint.iacr.org/2011/232.pdf
 
      [Billy Bob Brumley and Nicola Tuveri]
 
  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.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>]
 
Index: vendor-crypto/openssl/dist-1.0.1/CONTRIBUTING
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/CONTRIBUTING	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/CONTRIBUTING	(revision 306191)
@@ -1,38 +1,75 @@
-HOW TO CONTRIBUTE TO OpenSSL
-----------------------------
+HOW TO CONTRIBUTE TO PATCHES 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 rt@openssl.org with
-the string "[PATCH]" in the subject. Please be sure to include a
-textual explanation of what your patch does.
+(Please visit https://www.openssl.org/community/getting-started.html for
+other ideas about how to contribute.)
 
-You can also make GitHub pull requests. If you do this, please also send
-mail to rt@openssl.org with a brief description and a link to the PR so
-that we can more easily keep track of it.
-
+Development is coordinated on the openssl-dev mailing list (see the
+above link or https://mta.openssl.org for information on subscribing).
 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.
+OpenSSL community you might want to 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 Git or the last snapshot. They should follow our coding style
-(see https://www.openssl.org/policies/codingstyle.html) and compile without
-warnings using the --strict-warnings flag.  OpenSSL compiles on many varied
-platforms: try to ensure you only use portable features.
+The best way to submit a patch is to make a pull request on GitHub.
+(It is not necessary to send mail to rt@openssl.org to open a ticket!)
+If you think the patch could use feedback from the community, please
+start a thread on openssl-dev.
 
-Our preferred format for patch files is "git format-patch" output. For example
-to provide a patch file containing the last commit in your local git repository
-use the following command:
+You can also submit patches by sending it as mail to rt@openssl.org.
+Please include the word "PATCH" and an explanation of what the patch
+does in the subject line.  If you do this, our preferred format is "git
+format-patch" output. For example to provide a patch file containing the
+last commit in your local git repository use the following command:
 
-# git format-patch --stdout HEAD^ >mydiffs.patch
+    % git format-patch --stdout HEAD^ >mydiffs.patch
 
 Another method of creating an acceptable patch file without using git is as
 follows:
 
-# cd openssl-work
-# [your changes]
-# ./Configure dist; make clean
-# cd ..
-# diff -ur openssl-orig openssl-work > mydiffs.patch
+    % cd openssl-work
+    ...make your changes...
+    % ./Configure dist; make clean
+    % cd ..
+    % diff -ur openssl-orig openssl-work >mydiffs.patch
+
+Note that pull requests are generally easier for the team, and community, to
+work with.  Pull requests benefit from all of the standard GitHub features,
+including code review tools, simpler integration, and CI build support.
+
+No matter how a patch is submitted, the following items will help make
+the acceptance and review process faster:
+
+    1. Anything other than trivial contributions will require a contributor
+    licensing agreement, giving us permission to use your code. See
+    https://www.openssl.org/policies/cla.html for details.
+
+    2.  All source files should start with the following text (with
+    appropriate comment characters at the start of each line and the
+    year(s) updated):
+
+        Copyright 20xx-20yy The OpenSSL Project Authors. All Rights Reserved.
+
+        Licensed under the OpenSSL license (the "License").  You may not use
+        this file except in compliance with the License.  You can obtain a copy
+        in the file LICENSE in the source distribution or at
+        https://www.openssl.org/source/license.html
+
+    3.  Patches should be as current as possible.  When using GitHub, please
+    expect to have to rebase and update often. Note that we do not accept merge
+    commits. You will be asked to remove them before a patch is considered
+    acceptable.
+
+    4.  Patches should follow our coding style (see
+    https://www.openssl.org/policies/codingstyle.html) and compile without
+    warnings. Where gcc or clang is availble you should use the
+    --strict-warnings Configure option.  OpenSSL compiles on many varied
+    platforms: try to ensure you only use portable features.
+
+    5.  When at all possible, patches should include tests. These can either be
+    added to an existing test, or completely new.  Please see test/README
+    for information on the test framework.
+
+    6.  New features or changed functionality must include documentation. Please
+    look at the "pod" files in doc/apps, doc/crypto and doc/ssl for examples of
+    our style.
Index: vendor-crypto/openssl/dist-1.0.1/Configure
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/Configure	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/Configure	(revision 306191)
@@ -1,2210 +1,2210 @@
 :
 eval 'exec perl -S $0 ${1+"$@"}'
     if $running_under_some_shell;
 ##
 ##  Configure -- OpenSSL source tree configuration script
 ##
 
 require 5.000;
 use strict;
 
 # see INSTALL for instructions.
 
 my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
 
 # Options:
 #
 # --openssldir  install OpenSSL in OPENSSLDIR (Default: DIR/ssl if the
 #               --prefix option is given; /usr/local/ssl otherwise)
 # --prefix      prefix for the OpenSSL include, lib and bin directories
 #               (Default: the OPENSSLDIR directory)
 #
 # --install_prefix  Additional prefix for package builders (empty by
 #               default).  This needn't be set in advance, you can
 #               just as well use "make INSTALL_PREFIX=/whatever install".
 #
 # --with-krb5-dir  Declare where Kerberos 5 lives.  The libraries are expected
 #		to live in the subdirectory lib/ and the header files in
 #		include/.  A value is required.
 # --with-krb5-lib  Declare where the Kerberos 5 libraries live.  A value is
 #		required.
 #		(Default: KRB5_DIR/lib)
 # --with-krb5-include  Declare where the Kerberos 5 header files live.  A
 #		value is required.
 #		(Default: KRB5_DIR/include)
 # --with-krb5-flavor  Declare what flavor of Kerberos 5 is used.  Currently
 #		supported values are "MIT" and "Heimdal".  A value is required.
 #
 # --test-sanity Make a number of sanity checks on the data in this file.
 #               This is a debugging tool for OpenSSL developers.
 #
 # --cross-compile-prefix Add specified prefix to binutils components.
 #
 # no-hw-xxx     do not compile support for specific crypto hardware.
 #               Generic OpenSSL-style methods relating to this support
 #               are always compiled but return NULL if the hardware
 #               support isn't compiled.
 # no-hw         do not compile support for any crypto hardware.
 # [no-]threads  [don't] try to create a library that is suitable for
 #               multithreaded applications (default is "threads" if we
 #               know how to do it)
 # [no-]shared	[don't] try to create shared libraries when supported.
 # no-asm        do not use assembler
 # no-dso        do not compile in any native shared-library methods. This
 #               will ensure that all methods just return NULL.
 # no-krb5       do not compile in any KRB5 library or code.
 # [no-]zlib     [don't] compile support for zlib compression.
 # zlib-dynamic	Like "zlib", but the zlib library is expected to be a shared
 #		library and will be loaded in run-time by the OpenSSL library.
 # sctp          include SCTP support
 # 386           generate 80386 code
 # enable-weak-ssl-ciphers
 #		Enable EXPORT and LOW SSLv3 ciphers that are disabled by
 #		default.  Note, weak SSLv2 ciphers are unconditionally
 #		disabled.
 # no-sse2	disables IA-32 SSE2 code, above option implies no-sse2
 # no-<cipher>   build without specified algorithm (rsa, idea, rc5, ...)
 # -<xxx> +<xxx> compiler options are passed through 
 #
 # DEBUG_SAFESTACK use type-safe stacks to enforce type-safety on stack items
 #		provided to stack calls. Generates unique stack functions for
 #		each possible stack type.
 # DES_PTR	use pointer lookup vs arrays in the DES in crypto/des/des_locl.h
 # DES_RISC1	use different DES_ENCRYPT macro that helps reduce register
 #		dependancies but needs to more registers, good for RISC CPU's
 # DES_RISC2	A different RISC variant.
 # DES_UNROLL	unroll the inner DES loop, sometimes helps, somtimes hinders.
 # DES_INT	use 'int' instead of 'long' for DES_LONG in crypto/des/des.h
 #		This is used on the DEC Alpha where long is 8 bytes
 #		and int is 4
 # BN_LLONG	use the type 'long long' in crypto/bn/bn.h
 # MD2_CHAR	use 'char' instead of 'int' for MD2_INT in crypto/md2/md2.h
 # MD2_LONG	use 'long' instead of 'int' for MD2_INT in crypto/md2/md2.h
 # IDEA_SHORT	use 'short' instead of 'int' for IDEA_INT in crypto/idea/idea.h
 # IDEA_LONG	use 'long' instead of 'int' for IDEA_INT in crypto/idea/idea.h
 # RC2_SHORT	use 'short' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
 # RC2_LONG	use 'long' instead of 'int' for RC2_INT in crypto/rc2/rc2.h
 # RC4_CHAR	use 'char' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
 # RC4_LONG	use 'long' instead of 'int' for RC4_INT in crypto/rc4/rc4.h
 # RC4_INDEX	define RC4_INDEX in crypto/rc4/rc4_locl.h.  This turns on
 #		array lookups instead of pointer use.
 # RC4_CHUNK	enables code that handles data aligned at long (natural CPU
 #		word) boundary.
 # RC4_CHUNK_LL	enables code that handles data aligned at long long boundary
 #		(intended for 64-bit CPUs running 32-bit OS).
 # BF_PTR	use 'pointer arithmatic' for Blowfish (unsafe on Alpha).
 # BF_PTR2	intel specific version (generic version is more efficient).
 #
 # Following are set automatically by this script
 #
 # MD5_ASM	use some extra md5 assember,
 # SHA1_ASM	use some extra sha1 assember, must define L_ENDIAN for x86
 # RMD160_ASM	use some extra ripemd160 assember,
 # SHA256_ASM	sha256_block is implemented in assembler
 # SHA512_ASM	sha512_block is implemented in assembler
 # AES_ASM	ASE_[en|de]crypt is implemented in assembler
 
 # Minimum warning options... any contributions to OpenSSL should at least get
 # past these. 
 
 my $gcc_devteam_warn = "-Wall -pedantic -DPEDANTIC -Wno-long-long -Wsign-compare -Wmissing-prototypes -Wshadow -Wformat -Werror -DCRYPTO_MDEBUG_ALL -DCRYPTO_MDEBUG_ABORT -DREF_CHECK -DOPENSSL_NO_DEPRECATED";
 
 # Warn that "make depend" should be run?
 my $warn_make_depend = 0;
 
 my $clang_devteam_warn = "-Wno-unused-parameter -Wno-missing-field-initializers -Wno-language-extension-token -Wno-extended-offsetof -Qunused-arguments";
 
 my $strict_warnings = 0;
 
 my $x86_gcc_des="DES_PTR DES_RISC1 DES_UNROLL";
 
 # MD2_CHAR slags pentium pros
 my $x86_gcc_opts="RC4_INDEX MD2_INT";
 
 # MODIFY THESE PARAMETERS IF YOU ARE GOING TO USE THE 'util/speed.sh SCRIPT
 # Don't worry about these normally
 
 my $tcc="cc";
 my $tflags="-fast -Xa";
 my $tbn_mul="";
 my $tlib="-lnsl -lsocket";
 #$bits1="SIXTEEN_BIT ";
 #$bits2="THIRTY_TWO_BIT ";
 my $bits1="THIRTY_TWO_BIT ";
 my $bits2="SIXTY_FOUR_BIT ";
 
 my $x86_asm="x86cpuid.o:bn-586.o co-586.o x86-mont.o x86-gf2m.o:des-586.o crypt586.o:aes-586.o vpaes-x86.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o:cmll-x86.o:ghash-x86.o:";
 
 my $x86_elf_asm="$x86_asm:elf";
 
 my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
 my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
 my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
 my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
 my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
 my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
 my $mips64_asm=":bn-mips.o mips-mont.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::";
 my $s390x_asm="s390xcap.o s390xcpuid.o:bn-s390x.o s390x-mont.o s390x-gf2m.o::aes-s390x.o aes-ctr.o aes-xts.o:::sha1-s390x.o sha256-s390x.o sha512-s390x.o::rc4-s390x.o:::::ghash-s390x.o:";
 my $armv4_asm="armcap.o armv4cpuid.o:bn_asm.o armv4-mont.o armv4-gf2m.o::aes_cbc.o aes-armv4.o:::sha1-armv4-large.o sha256-armv4.o sha512-armv4.o:::::::ghash-armv4.o::void";
 my $parisc11_asm="pariscid.o:bn_asm.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::32";
 my $parisc20_asm="pariscid.o:pa-risc2W.o parisc-mont.o::aes_core.o aes_cbc.o aes-parisc.o:::sha1-parisc.o sha256-parisc.o sha512-parisc.o::rc4-parisc.o:::::ghash-parisc.o::64";
 my $ppc32_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o::::::::";
 my $ppc64_asm="ppccpuid.o ppccap.o:bn-ppc.o ppc-mont.o ppc64-mont.o::aes_core.o aes_cbc.o aes-ppc.o:::sha1-ppc.o sha256-ppc.o sha512-ppc.o::::::::";
 my $no_asm=":::::::::::::::void";
 
 # As for $BSDthreads. Idea is to maintain "collective" set of flags,
 # which would cover all BSD flavors. -pthread applies to them all, 
 # but is treated differently. OpenBSD expands is as -D_POSIX_THREAD
 # -lc_r, which is sufficient. FreeBSD 4.x expands it as -lc_r,
 # which has to be accompanied by explicit -D_THREAD_SAFE and
 # sometimes -D_REENTRANT. FreeBSD 5.x expands it as -lc_r, which
 # seems to be sufficient?
 my $BSDthreads="-pthread -D_THREAD_SAFE -D_REENTRANT";
 
 #config-string	$cc : $cflags : $unistd : $thread_cflag : $sys_id : $lflags : $bn_ops : $cpuid_obj : $bn_obj : $des_obj : $aes_obj : $bf_obj : $md5_obj : $sha1_obj : $cast_obj : $rc4_obj : $rmd160_obj : $rc5_obj : $wp_obj : $cmll_obj : $modes_obj : $engines_obj : $dso_scheme : $shared_target : $shared_cflag : $shared_ldflag : $shared_extension : $ranlib : $arflags : $multilib
 
 my %table=(
 # File 'TABLE' (created by 'make TABLE') contains the data from this list,
 # formatted for better readability.
 
 
 #"b",		"${tcc}:${tflags}::${tlib}:${bits1}:${tbn_mul}::",
 #"bl-4c-2c",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR MD2_CHAR:${tbn_mul}::",
 #"bl-4c-ri",	"${tcc}:${tflags}::${tlib}:${bits1}BN_LLONG RC4_CHAR RC4_INDEX:${tbn_mul}::",
 #"b2-is-ri-dp",	"${tcc}:${tflags}::${tlib}:${bits2}IDEA_SHORT RC4_INDEX DES_PTR:${tbn_mul}::",
 
 # Our development configs
 "purify",	"purify gcc:-g -DPURIFY -Wall::(unknown)::-lsocket -lnsl::::",
 "debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -ggdb -g2 -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror::(unknown)::-lefence::::",
 "debug-ben",	"gcc:$gcc_devteam_warn -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DDEBUG_SAFESTACK -O2 -pipe::(unknown):::::",
 "debug-ben-openbsd","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
 "debug-ben-openbsd-debug","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DOPENSSL_OPENBSD_DEV_CRYPTO -DOPENSSL_NO_ASM -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown)::::",
 "debug-ben-debug",	"gcc44:$gcc_devteam_warn -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O2 -pipe::(unknown)::::::",
 "debug-ben-debug-64",	"gcc:$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -g3 -O3 -pipe::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-ben-macos",	"cc:$gcc_devteam_warn -arch i386 -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::-Wl,-search_paths_first::::",
 "debug-ben-macos-gcc46",	"gcc-mp-4.6:$gcc_devteam_warn -Wconversion -DBN_DEBUG -DCONF_DEBUG -DDEBUG_SAFESTACK -DDEBUG_UNUSED -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -O3 -DL_ENDIAN -g3 -pipe::(unknown)::::::",
 "debug-ben-darwin64","cc:$gcc_devteam_warn -Wno-language-extension-token -Wno-extended-offsetof -arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "debug-ben-no-opt",	"gcc: -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -DDEBUG_SAFESTACK -DCRYPTO_MDEBUG -Werror -DL_ENDIAN -DTERMIOS -Wall -g3::(unknown)::::::",
 "debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown)::::::",
 "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
 "debug-bodo",	"gcc:$gcc_devteam_warn -Wno-error=overlength-strings -DBN_DEBUG -DBN_DEBUG_RAND -DCONF_DEBUG -DBIO_PAIR_DEBUG -m64 -DL_ENDIAN -DTERMIO -g -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "debug-ulf", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DBN_DEBUG_RAND -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations:::CYGWIN32:::${no_asm}:win32:cygwin-shared:::.dll",
 "debug-steve64", "gcc:$gcc_devteam_warn -m64 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -Wno-overlength-strings -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-steve32", "gcc:$gcc_devteam_warn -m32 -DL_ENDIAN -DCONF_DEBUG -DDEBUG_SAFESTACK -g -pipe::-D_REENTRANT::-rdynamic -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-steve-opt", "gcc:$gcc_devteam_warn -m64 -O3 -DL_ENDIAN -DTERMIO -DCONF_DEBUG -DDEBUG_SAFESTACK -g::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-levitte-linux-elf","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-levitte-linux-noasm","gcc:-DLEVITTE_DEBUG -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -ggdb -g3 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-levitte-linux-elf-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DL_ENDIAN -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-levitte-linux-noasm-extreme","gcc:-DLEVITTE_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_DEBUG -DBN_DEBUG_RAND -DCRYPTO_MDEBUG -DENGINE_CONF_DEBUG -DOPENSSL_NO_ASM -DL_ENDIAN -DPEDANTIC -ggdb -g3 -pedantic -ansi -Wall -W -Wundef -Wshadow -Wcast-align -Wstrict-prototypes -Wmissing-prototypes -Wno-long-long -Wundef -Wconversion -pipe::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-geoff32","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:BN_LLONG:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-geoff64","gcc:-DBN_DEBUG -DBN_DEBUG_RAND -DBN_STRICT -DPURIFY -DOPENSSL_NO_DEPRECATED -DOPENSSL_NO_ASM -DOPENSSL_NO_INLINE_ASM -DL_ENDIAN -DTERMIO -DPEDANTIC -O1 -ggdb2 -Wall -Werror -Wundef -pedantic -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-align -Wsign-compare -Wmissing-prototypes -Wmissing-declarations -Wno-long-long::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-pentium","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -g -mcpu=pentium -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
 "debug-linux-ppro","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -g -mcpu=pentiumpro -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn",
 "debug-linux-elf","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -g -march=i486 -Wall::-D_REENTRANT::-lefence -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-elf-noefence","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DL_ENDIAN -g -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-ia32-aes", "gcc:-DAES_EXPERIMENTAL -DL_ENDIAN -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:x86cpuid.o:bn-586.o co-586.o x86-mont.o:des-586.o crypt586.o:aes_x86core.o aes_cbc.o aesni-x86.o:bf-586.o:md5-586.o:sha1-586.o sha256-586.o sha512-586.o:cast-586.o:rc4-586.o:rmd-586.o:rc5-586.o:wp_block.o wp-mmx.o::ghash-x86.o::elf:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-generic32","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -g -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-generic64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-linux-x86_64","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -g -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "debug-linux-x86_64-clang","clang: -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -m64 -DL_ENDIAN -g -Wall -Qunused-arguments::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "dist",		"cc:-O::(unknown)::::::",
 
 # Basic configs that should work on any (32 and less bit) box
 "gcc",		"gcc:-O3::(unknown):::BN_LLONG:::",
 "cc",		"cc:-O::(unknown)::::::",
 
 ####VOS Configurations
 "vos-gcc","gcc:-O3 -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
 "debug-vos-gcc","gcc:-O0 -g -Wall -DOPENSSL_SYSNAME_VOS -D_POSIX_C_SOURCE=200112L -D_BSD -D_VOS_EXTENDED_NAMES -DB_ENDIAN -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG::(unknown):VOS:-Wl,-map:BN_LLONG:${no_asm}:::::.so:",
 
 #### Solaris x86 with GNU C setups
 # -DOPENSSL_NO_INLINE_ASM switches off inline assembler. We have to do it
 # here because whenever GNU C instantiates an assembler template it
 # surrounds it with #APP #NO_APP comment pair which (at least Solaris
 # 7_x86) /usr/ccs/bin/as fails to assemble with "Illegal mnemonic"
 # error message.
 "solaris-x86-gcc","gcc:-O3 -fomit-frame-pointer -march=pentium -Wall -DL_ENDIAN -DOPENSSL_NO_INLINE_ASM::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # -shared -static-libgcc might appear controversial, but modules taken
 # from static libgcc do not have relocations and linking them into our
 # shared objects doesn't have any negative side-effects. On the contrary,
 # doing so makes it possible to use gcc shared build with Sun C. Given
 # that gcc generates faster code [thanks to inline assembler], I would
 # actually recommend to consider using gcc shared build even with vendor
 # compiler:-)
 #						<appro@fy.chalmers.se>
 "solaris64-x86_64-gcc","gcc:-m64 -O3 -Wall -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-fPIC:-m64 -shared -static-libgcc:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
  
 #### Solaris x86 with Sun C setups
 "solaris-x86-cc","cc:-fast -O -Xa::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris64-x86_64-cc","cc:-fast -xarch=amd64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-xarch=amd64 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
 
 #### SPARC Solaris with GNU C setups
 "solaris-sparcv7-gcc","gcc:-O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris-sparcv8-gcc","gcc:-mcpu=v8 -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # -m32 should be safe to add as long as driver recognizes -mcpu=ultrasparc
 "solaris-sparcv9-gcc","gcc:-m32 -mcpu=ultrasparc -O3 -fomit-frame-pointer -Wall -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris64-sparcv9-gcc","gcc:-m64 -mcpu=ultrasparc -O3 -Wall -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-m64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
 ####
 "debug-solaris-sparcv8-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -O -g -mcpu=v8 -Wall -DB_ENDIAN::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-solaris-sparcv9-gcc","gcc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -DPEDANTIC -O -g -mcpu=ultrasparc -pedantic -ansi -Wall -Wshadow -Wno-long-long -D__EXTENSIONS__ -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 #### SPARC Solaris with Sun C setups
 # SC4.0 doesn't pass 'make test', upgrade to SC5.0 or SC4.2.
 # SC4.2 is ok, better than gcc even on bn as long as you tell it -xarch=v8
 # SC5.0 note: Compiler common patch 107357-01 or later is required!
 "solaris-sparcv7-cc","cc:-xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${no_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris-sparcv8-cc","cc:-xarch=v8 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris-sparcv9-cc","cc:-xtarget=ultra -xarch=v8plus -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "solaris64-sparcv9-cc","cc:-xtarget=ultra -xarch=v9 -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-xarch=v9 -G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/64",
 ####
 "debug-solaris-sparcv8-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xarch=v8 -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-solaris-sparcv9-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG_ALL -xtarget=ultra -xarch=v8plus -g -O -xstrconst -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -ldl:BN_LLONG RC4_CHAR RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-G -dy -z text:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", 
 
 #### SunOS configs, assuming sparc for the gcc one.
 #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
 "sunos-gcc","gcc:-O3 -mcpu=v8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
 
 #### IRIX 5.x configs
 # -mips2 flag is added by ./config when appropriate.
 "irix-gcc","gcc:-O3 -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "irix-cc", "cc:-O2 -use_readonly_const -DB_ENDIAN::(unknown):::BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 #### IRIX 6.x configs
 # Only N32 and N64 ABIs are supported. If you need O32 ABI build, invoke
 # './Configure irix-cc -o32' manually.
 "irix-mips3-gcc","gcc:-mabi=n32 -O3 -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK_LL DES_UNROLL DES_RISC2 DES_PTR BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-mabi=n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
 "irix-mips3-cc", "cc:-n32 -mips3 -O2 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::DES_PTR RC4_CHAR RC4_CHUNK_LL DES_RISC2 DES_UNROLL BF_PTR SIXTY_FOUR_BIT:${mips64_asm}:n32:dlfcn:irix-shared::-n32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::32",
 # N64 ABI builds.
 "irix64-mips4-gcc","gcc:-mabi=64 -mips4 -O3 -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-mabi=64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "irix64-mips4-cc", "cc:-64 -mips4 -O2 -use_readonly_const -G0 -rdata_shared -DB_ENDIAN -DBN_DIV3W::-D_SGI_MP_SOURCE:::RC4_CHAR RC4_CHUNK DES_RISC2 DES_UNROLL SIXTY_FOUR_BIT_LONG:${mips64_asm}:64:dlfcn:irix-shared::-64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 
 #### Unified HP-UX ANSI C configs.
 # Special notes:
 # - Originally we were optimizing at +O4 level. It should be noted
 #   that the only difference between +O3 and +O4 is global inter-
 #   procedural analysis. As it has to be performed during the link
 #   stage the compiler leaves behind certain pseudo-code in lib*.a
 #   which might be release or even patch level specific. Generating
 #   the machine code for and analyzing the *whole* program appears
 #   to be *extremely* memory demanding while the performance gain is
 #   actually questionable. The situation is intensified by the default
 #   HP-UX data set size limit (infamous 'maxdsiz' tunable) of 64MB
 #   which is way too low for +O4. In other words, doesn't +O3 make
 #   more sense?
 # - Keep in mind that the HP compiler by default generates code
 #   suitable for execution on the host you're currently compiling at.
 #   If the toolkit is ment to be used on various PA-RISC processors
 #   consider './config +DAportable'.
 # - +DD64 is chosen in favour of +DA2.0W because it's meant to be
 #   compatible with *future* releases.
 # - If you run ./Configure hpux-parisc-[g]cc manually don't forget to
 #   pass -D_REENTRANT on HP-UX 10 and later.
 # - -DMD32_XARRAY triggers workaround for compiler bug we ran into in
 #   32-bit message digests. (For the moment of this writing) HP C
 #   doesn't seem to "digest" too many local variables (they make "him"
 #   chew forever:-). For more details look-up MD32_XARRAY comment in
 #   crypto/sha/sha_lcl.h.
 #					<appro@fy.chalmers.se>
 #
 # Since there is mention of this in shlib/hpux10-cc.sh
 "hpux-parisc-cc-o4","cc:-Ae +O4 +ESlit -z -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "hpux-parisc-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "hpux-parisc1_1-gcc","gcc:-O3 -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT::-Wl,+s -ldld:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:${parisc11_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
 "hpux-parisc2-gcc","gcc:-march=2.0 -O3 -DB_ENDIAN -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT RC4_CHAR RC4_CHUNK DES_PTR DES_UNROLL DES_RISC1:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
 "hpux64-parisc2-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT::pa-risc2W.o::::::::::::::void:dlfcn:hpux-shared:-fpic:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
 
 # More attempts at unified 10.X and 11.X targets for HP C compiler.
 #
 # Chris Ruemmler <ruemmler@cup.hp.com>
 # Kevin Steves <ks@hp.se>
 "hpux-parisc-cc","cc:+O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "hpux-parisc1_1-cc","cc:+DA1.1 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY::-D_REENTRANT::-Wl,+s -ldld:MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc11_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa1.1",
 "hpux-parisc2-cc","cc:+DA2.0 +DS2.0 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-Wl,+s -ldld:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:".eval{my $asm=$parisc20_asm;$asm=~s/2W\./2\./;$asm=~s/:64/:32/;$asm}.":dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_32",
 "hpux64-parisc2-cc","cc:+DD64 +O3 +Optrs_strongly_typed -Ae +ESlit -DB_ENDIAN -DMD32_XARRAY -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC1 DES_INT:${parisc20_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/pa20_64",
 
 # HP/UX IA-64 targets
 "hpux-ia64-cc","cc:-Ae +DD32 +O2 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD32 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
 # Frank Geurts <frank.geurts@nl.abnamro.com> has patiently assisted with
 # with debugging of the following config.
 "hpux64-ia64-cc","cc:-Ae +DD64 +O3 +Olit=all -z -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:+Z:+DD64 -b:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64",
 # GCC builds...
 "hpux-ia64-gcc","gcc:-O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux32",
 "hpux64-ia64-gcc","gcc:-mlp64 -O3 -DB_ENDIAN -D_REENTRANT::::-ldl:SIXTY_FOUR_BIT_LONG MD2_CHAR RC4_INDEX DES_UNROLL DES_RISC1 DES_INT:${ia64_asm}:dlfcn:hpux-shared:-fpic:-mlp64 -shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/hpux64", 
 
 # Legacy HPUX 9.X configs...
 "hpux-cc",	"cc:-DB_ENDIAN -DBN_DIV2W -DMD32_XARRAY -Ae +ESlit +O2 -z::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:+Z:-b:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "hpux-gcc",	"gcc:-DB_ENDIAN -DBN_DIV2W -O3::(unknown)::-Wl,+s -ldld:DES_PTR DES_UNROLL DES_RISC1:${no_asm}:dl:hpux-shared:-fPIC:-shared:.sl.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 #### HP MPE/iX http://jazz.external.hp.com/src/openssl/
 "MPE/iX-gcc",	"gcc:-D_ENDIAN -DBN_DIV2W -O3 -D_POSIX_SOURCE -D_SOCKET_SOURCE -I/SYSLOG/PUB::(unknown):MPE:-L/SYSLOG/PUB -lsyslog -lsocket -lcurses:BN_LLONG DES_PTR DES_UNROLL DES_RISC1:::",
 
 # DEC Alpha OSF/1/Tru64 targets.
 #
 #	"What's in a name? That which we call a rose
 #	 By any other word would smell as sweet."
 #
 # - William Shakespeare, "Romeo & Juliet", Act II, scene II.
 #
 # For gcc, the following gave a %50 speedup on a 164 over the 'DES_INT' version
 #
 "osf1-alpha-gcc", "gcc:-O3::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_RISC1:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
 "osf1-alpha-cc",  "cc:-std1 -tune host -O4 -readonly_strings::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared:::.so",
 "tru64-alpha-cc", "cc:-std1 -tune host -fast -readonly_strings::-pthread:::SIXTY_FOUR_BIT_LONG RC4_CHUNK:${alpha_asm}:dlfcn:alpha-osf1-shared::-msym:.so",
 
 ####
 #### Variety of LINUX:-)
 ####
 # *-generic* is endian-neutral target, but ./config is free to
 # throw in -D[BL]_ENDIAN, whichever appropriate...
 "linux-generic32","gcc:-O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-ppc",	"gcc:-DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc32_asm}:linux32:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # It's believed that majority of ARM toolchains predefine appropriate -march.
 # If you compiler does not, do complement config command line with one!
 "linux-armv4",	"gcc:-O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 #### IA-32 targets...
 "linux-ia32-icc",	"icc:-DL_ENDIAN -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-elf",	"gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-aout",	"gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out",
 ####
 "linux-generic64","gcc:-O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-ppc64",	"gcc:-m64 -DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${ppc64_asm}:linux64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "linux-ia64",	"gcc:-DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-ia64-ecc","ecc:-DL_ENDIAN -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-ia64-icc","icc:-DL_ENDIAN -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_INT:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-x86_64",	"gcc:-m64 -DL_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "linux-x86_64-clang","clang: -m64 -DL_ENDIAN -O3 -Wall -Qunused-arguments::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 "linux64-s390x",	"gcc:-m64 -DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 #### So called "highgprs" target for z/Architecture CPUs
 # "Highgprs" is kernel feature first implemented in Linux 2.6.32, see
 # /proc/cpuinfo. The idea is to preserve most significant bits of
 # general purpose registers not only upon 32-bit process context
 # switch, but even on asynchronous signal delivery to such process.
 # This makes it possible to deploy 64-bit instructions even in legacy
 # application context and achieve better [or should we say adequate]
 # performance. The build is binary compatible with linux-generic32,
 # and the idea is to be able to install the resulting libcrypto.so
 # alongside generic one, e.g. as /lib/highgprs/libcrypto.so.x.y, for
 # ldconfig and run-time linker to autodiscover. Unfortunately it
 # doesn't work just yet, because of couple of bugs in glibc
 # sysdeps/s390/dl-procinfo.c affecting ldconfig and ld.so.1...
 "linux32-s390x",	"gcc:-m31 -Wa,-mzarch -DB_ENDIAN -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$s390x_asm;$asm=~s/bn\-s390x\.o/bn_asm.o/;$asm}.":31:dlfcn:linux-shared:-fPIC:-m31:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::/highgprs",
 #### SPARC Linux setups
 # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
 # assisted with debugging of following two configs.
 "linux-sparcv8","gcc:-mcpu=v8 -DB_ENDIAN -O3 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv8_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # it's a real mess with -mcpu=ultrasparc option under Linux, but
 # -Wa,-Av8plus should do the trick no matter what.
 "linux-sparcv9","gcc:-m32 -mcpu=ultrasparc -DB_ENDIAN -O3 -fomit-frame-pointer -Wall -Wa,-Av8plus -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m32:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # GCC 3.1 is a requirement
 "linux64-sparcv9","gcc:-m64 -mcpu=ultrasparc -DB_ENDIAN -O3 -fomit-frame-pointer -Wall::-D_REENTRANT:ULTRASPARC:-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
 #### Alpha Linux with GNU C and Compaq C setups
 # Special notes:
 # - linux-alpha+bwx-gcc is ment to be used from ./config only. If you
 #   ought to run './Configure linux-alpha+bwx-gcc' manually, do
 #   complement the command line with -mcpu=ev56, -mcpu=ev6 or whatever
 #   which is appropriate.
 # - If you use ccc keep in mind that -fast implies -arch host and the
 #   compiler is free to issue instructions which gonna make elder CPU
 #   choke. If you wish to build "blended" toolkit, add -arch generic
 #   *after* -fast and invoke './Configure linux-alpha-ccc' manually.
 #
 #					<appro@fy.chalmers.se>
 #
 "linux-alpha-gcc","gcc:-O3 -DL_ENDIAN::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-alpha+bwx-gcc","gcc:-O3 -DL_ENDIAN::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "linux-alpha-ccc","ccc:-fast -readonly_strings -DL_ENDIAN::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
 "linux-alpha+bwx-ccc","ccc:-fast -readonly_strings -DL_ENDIAN::-D_REENTRANT:::SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL:${alpha_asm}",
 
 # Android: linux-* but without pointers to headers and libs.
 "android","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "android-x86","gcc:-mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:".eval{my $asm=${x86_elf_asm};$asm=~s/:elf/:android/;$asm}.":dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "android-armv7","gcc:-march=armv7-a -mandroid -I\$(ANDROID_DEV)/include -B\$(ANDROID_DEV)/lib -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 #### *BSD [do see comment about ${BSDthreads} above!]
 "BSD-generic32","gcc:-O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "BSD-x86",	"gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "BSD-x86-elf",	"gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -Wall::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "debug-BSD-x86-elf",	"gcc:-DL_ENDIAN -O3 -Wall -g::${BSDthreads}:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "BSD-sparcv8",	"gcc:-DB_ENDIAN -O3 -mcpu=v8 -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_INDEX DES_INT DES_UNROLL:${sparcv8_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 "BSD-generic64","gcc:-O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # -DMD32_REG_T=int doesn't actually belong in sparc64 target, it
 # simply *happens* to work around a compiler bug in gcc 3.3.3,
 # triggered by RIPEMD160 code.
 "BSD-sparc64",	"gcc:-DB_ENDIAN -O3 -DMD32_REG_T=int -Wall::${BSDthreads}:::BN_LLONG RC2_CHAR RC4_CHUNK DES_INT DES_PTR DES_RISC2 BF_PTR:${sparcv9_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "BSD-ia64",	"gcc:-DL_ENDIAN -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${ia64_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "BSD-x86_64",	"gcc:-DL_ENDIAN -O3 -Wall::${BSDthreads}:::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 "bsdi-elf-gcc",     "gcc:-DPERL5 -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall::(unknown)::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 "nextstep",	"cc:-O -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
 "nextstep3.3",	"cc:-O3 -Wall:<libc.h>:(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:::",
 
 # NCR MP-RAS UNIX ver 02.03.01
 "ncr-scde","cc:-O6 -Xa -Hoff=BEHAVED -686 -Hwide -Hiw::(unknown)::-lsocket -lnsl -lc89:${x86_gcc_des} ${x86_gcc_opts}:::",
 
 # QNX
 "qnx4",	"cc:-DL_ENDIAN -DTERMIO::(unknown):::${x86_gcc_des} ${x86_gcc_opts}:",
 "QNX6",       "gcc:::::-lsocket::${no_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "QNX6-i386",  "gcc:-DL_ENDIAN -O2 -Wall::::-lsocket:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 # BeOS
 "beos-x86-r5",   "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lnet:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC -DPIC:-shared:.so",
 "beos-x86-bone", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mcpu=pentium -Wall::-D_REENTRANT:BEOS:-lbe -lbind -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:beos:beos-shared:-fPIC:-shared:.so",
 
 #### SCO/Caldera targets.
 #
 # Originally we had like unixware-*, unixware-*-pentium, unixware-*-p6, etc.
 # Now we only have blended unixware-* as it's the only one used by ./config.
 # If you want to optimize for particular microarchitecture, bypass ./config
 # and './Configure unixware-7 -Kpentium_pro' or whatever appropriate.
 # Note that not all targets include assembler support. Mostly because of
 # lack of motivation to support out-of-date platforms with out-of-date
 # compiler drivers and assemblers. Tim Rice <tim@multitalents.net> has
 # patiently assisted to debug most of it.
 #
 # UnixWare 2.0x fails destest with -O.
 "unixware-2.0","cc:-DFILIO_H -DNO_STRINGS_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
 "unixware-2.1","cc:-O -DFILIO_H::-Kthread::-lsocket -lnsl -lresolv -lx:${x86_gcc_des} ${x86_gcc_opts}:::",
 "unixware-7","cc:-O -DFILIO_H -Kalloca::-Kthread::-lsocket -lnsl:BN_LLONG MD2_CHAR RC4_INDEX ${x86_gcc_des}:${x86_elf_asm}:dlfcn:svr5-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "unixware-7-gcc","gcc:-DL_ENDIAN -DFILIO_H -O3 -fomit-frame-pointer -march=pentium -Wall::-D_REENTRANT::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:gnu-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 # SCO 5 - Ben Laurie <ben@algroup.co.uk> says the -O breaks the SCO cc.
 "sco5-cc",  "cc:-belf::(unknown)::-lsocket -lnsl:${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-Kpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "sco5-gcc",  "gcc:-O3 -fomit-frame-pointer::(unknown)::-lsocket -lnsl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:svr3-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 
 #### IBM's AIX.
 "aix3-cc",  "cc:-O -DB_ENDIAN -qmaxmem=16384::(unknown):AIX::BN_LLONG RC4_CHAR:::",
 "aix-gcc",  "gcc:-O -DB_ENDIAN::-pthread:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X32",
 "aix64-gcc","gcc:-maix64 -O -DB_ENDIAN::-pthread:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-maix64 -shared -Wl,-G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X64",
 # Below targets assume AIX 5. Idea is to effectively disregard $OBJECT_MODE
 # at build time. $OBJECT_MODE is respected at ./config stage!
 "aix-cc",   "cc:-q32 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::BN_LLONG RC4_CHAR:${ppc32_asm}:aix32:dlfcn:aix-shared::-q32 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 32",
 "aix64-cc", "cc:-q64 -O -DB_ENDIAN -qmaxmem=16384 -qro -qroconst::-qthreaded -D_THREAD_SAFE:AIX::SIXTY_FOUR_BIT_LONG RC4_CHAR:${ppc64_asm}:aix64:dlfcn:aix-shared::-q64 -G:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)::-X 64",
 
 #
 # Cray T90 and similar (SDSC)
 # It's Big-endian, but the algorithms work properly when B_ENDIAN is NOT
 # defined.  The T90 ints and longs are 8 bytes long, and apparently the
 # B_ENDIAN code assumes 4 byte ints.  Fortunately, the non-B_ENDIAN and
 # non L_ENDIAN code aligns the bytes in each word correctly.
 #
 # The BIT_FIELD_LIMITS define is to avoid two fatal compiler errors:
 #'Taking the address of a bit field is not allowed. '
 #'An expression with bit field exists as the operand of "sizeof" '
 # (written by Wayne Schroeder <schroede@SDSC.EDU>)
 #
 # j90 is considered the base machine type for unicos machines,
 # so this configuration is now called "cray-j90" ...
 "cray-j90", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG DES_INT:::",
 
 #
 # Cray T3E (Research Center Juelich, beckman@acl.lanl.gov)
 #
 # The BIT_FIELD_LIMITS define was written for the C90 (it seems).  I added
 # another use.  Basically, the problem is that the T3E uses some bit fields
 # for some st_addr stuff, and then sizeof and address-of fails
 # I could not use the ams/alpha.o option because the Cray assembler, 'cam'
 # did not like it.
 "cray-t3e", "cc: -DBIT_FIELD_LIMITS -DTERMIOS::(unknown):CRAY::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT:::",
 
 # DGUX, 88100.
 "dgux-R3-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown):::RC4_INDEX DES_UNROLL:::",
 "dgux-R4-gcc",	"gcc:-O3 -fomit-frame-pointer::(unknown)::-lnsl -lsocket:RC4_INDEX DES_UNROLL:::",
 "dgux-R4-x86-gcc",	"gcc:-O3 -fomit-frame-pointer -DL_ENDIAN::(unknown)::-lnsl -lsocket:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}",
 
 # Sinix/ReliantUNIX RM400
 # NOTE: The CDS++ Compiler up to V2.0Bsomething has the IRIX_CC_BUG optimizer problem. Better use -g  */
 "ReliantUNIX","cc:-KPIC -g -DTERMIOS -DB_ENDIAN::-Kthread:SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:BN_LLONG DES_PTR DES_RISC2 DES_UNROLL BF_PTR:${no_asm}:dlfcn:reliantunix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
 "SINIX","cc:-O::(unknown):SNI:-lsocket -lnsl -lc -L/usr/ucblib -lucb:RC4_INDEX RC4_CHAR:::",
 "SINIX-N","/usr/ucb/cc:-O2 -misaligned::(unknown)::-lucb:RC4_INDEX RC4_CHAR:::",
 
 # SIEMENS BS2000/OSD: an EBCDIC-based mainframe
 "BS2000-OSD","c89:-O -XLLML -XLLMK -XL -DB_ENDIAN -DCHARSET_EBCDIC::(unknown)::-lsocket -lnsl:THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
 
 # OS/390 Unix an EBCDIC-based Unix system on IBM mainframe
 # You need to compile using the c89.sh wrapper in the tools directory, because the
 # IBM compiler does not like the -L switch after any object modules.
 #
 "OS390-Unix","c89.sh:-O -DB_ENDIAN -DCHARSET_EBCDIC -DNO_SYS_PARAM_H  -D_ALL_SOURCE::(unknown):::THIRTY_TWO_BIT DES_PTR DES_UNROLL MD2_CHAR RC4_INDEX RC4_CHAR BF_PTR:::",
 
 # Visual C targets
 #
 # Win64 targets, WIN64I denotes IA-64 and WIN64A - AMD64
 "VC-WIN64I","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
 "VC-WIN64A","cl:-W3 -Gs0 -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
 "debug-VC-WIN64I","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64I::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:ia64cpuid.o:ia64.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o:::::::ghash-ia64.o::ias:win32",
 "debug-VC-WIN64A","cl:-W3 -Gs0 -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -DUNICODE -D_UNICODE -D_CRT_SECURE_NO_DEPRECATE:::WIN64A::SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:".eval{my $asm=$x86_64_asm;$asm=~s/x86_64-gcc\.o/bn_asm.o/;$asm}.":auto:win32",
 # x86 Win32 target defaults to ANSI API, if you want UNICODE, complement
 # 'perl Configure VC-WIN32' with '-DUNICODE -D_UNICODE'
 "VC-WIN32","cl:-W3 -Gs0 -GF -Gy -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
 # Unified CE target
 "debug-VC-WIN32","cl:-W3 -Gs0 -GF -Gy -Zi -nologo -DOPENSSL_SYSNAME_WIN32 -DWIN32_LEAN_AND_MEAN -DL_ENDIAN -D_CRT_SECURE_NO_DEPRECATE:::WIN32::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${x86_asm}:win32n:win32",
 "VC-CE","cl::::WINCE::BN_LLONG RC4_INDEX EXPORT_VAR_AS_FN ${x86_gcc_opts}:${no_asm}:win32",
 
 # Borland C++ 4.5
 "BC-32","bcc32::::WIN32::BN_LLONG DES_PTR RC4_INDEX EXPORT_VAR_AS_FN:${no_asm}:win32",
 
 # MinGW
 "mingw", "gcc:-mno-cygwin -DL_ENDIAN -DWIN32_LEAN_AND_MEAN -fomit-frame-pointer -O3 -march=i486 -Wall::-D_MT:MINGW32:-lws2_32 -lgdi32 -lcrypt32:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts} EXPORT_VAR_AS_FN:${x86_asm}:coff:win32:cygwin-shared:-D_WINDLL -DOPENSSL_USE_APPLINK:-mno-cygwin:.dll.a",
 # As for OPENSSL_USE_APPLINK. Applink makes it possible to use .dll
 # compiled with one compiler with application compiled with another
 # compiler. It's possible to engage Applink support in mingw64 build,
 # but it's not done, because till mingw64 supports structured exception
 # handling, one can't seriously consider its binaries for using with
 # non-mingw64 run-time environment. And as mingw64 is always consistent
 # with itself, Applink is never engaged and can as well be omitted.
 "mingw64", "gcc:-mno-cygwin -DL_ENDIAN -O3 -Wall -DWIN32_LEAN_AND_MEAN -DUNICODE -D_UNICODE::-D_MT:MINGW64:-lws2_32 -lgdi32 -lcrypt32:SIXTY_FOUR_BIT RC4_CHUNK_LL DES_INT EXPORT_VAR_AS_FN:${x86_64_asm}:mingw64:win32:cygwin-shared:-D_WINDLL:-mno-cygwin:.dll.a",
 
 # UWIN 
 "UWIN", "cc:-DTERMIOS -DL_ENDIAN -O -Wall:::UWIN::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
 
 # Cygwin
 "Cygwin-pre1.3", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::(unknown):CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${no_asm}:win32",
 "Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -march=i486 -Wall:::CYGWIN32::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:coff:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
 "debug-Cygwin", "gcc:-DTERMIOS -DL_ENDIAN -march=i486 -Wall -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DOPENSSL_NO_ASM -g -Wformat -Wshadow -Wmissing-prototypes -Wmissing-declarations -Werror:::CYGWIN32:::${no_asm}:dlfcn:cygwin-shared:-D_WINDLL:-shared:.dll.a",
 
 # NetWare from David Ward (dsward@novell.com)
 # requires either MetroWerks NLM development tools, or gcc / nlmconv
 # NetWare defaults socket bio to WinSock sockets. However,
 # the builds can be configured to use BSD sockets instead.
 # netware-clib => legacy CLib c-runtime support
 "netware-clib", "mwccnlm::::::${x86_gcc_opts}::",
 "netware-clib-bsdsock", "mwccnlm::::::${x86_gcc_opts}::",
 "netware-clib-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -I/ndk/ws295sdk/include -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
 "netware-clib-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/nwsdk/include/nlm -DNETWARE_BSDSOCK -DNETDB_USE_INTERNET -DL_ENDIAN -DNETWARE_CLIB -DOPENSSL_SYSNAME_NETWARE -O2 -Wall:::::${x86_gcc_opts}::",
 # netware-libc => LibC/NKS support
 "netware-libc", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
 "netware-libc-bsdsock", "mwccnlm::::::BN_LLONG ${x86_gcc_opts}::",
 "netware-libc-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -I/ndk/libc/include/winsock -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
 "netware-libc-bsdsock-gcc", "i586-netware-gcc:-nostdinc -I/ndk/libc/include -DNETWARE_BSDSOCK -DL_ENDIAN -DNETWARE_LIBC -DOPENSSL_SYSNAME_NETWARE -DTERMIO -O2 -Wall:::::BN_LLONG ${x86_gcc_opts}::",
 
 # DJGPP
 "DJGPP", "gcc:-I/dev/env/WATT_ROOT/inc -DTERMIO -DL_ENDIAN -fomit-frame-pointer -O2 -Wall:::MSDOS:-L/dev/env/WATT_ROOT/lib -lwatt:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_asm}:a.out:",
 
 # Ultrix from Bernhard Simon <simon@zid.tuwien.ac.at>
 "ultrix-cc","cc:-std1 -O -Olimit 2500 -DL_ENDIAN::(unknown):::::::",
 "ultrix-gcc","gcc:-O3 -DL_ENDIAN::(unknown):::BN_LLONG::::",
 # K&R C is no longer supported; you need gcc on old Ultrix installations
 ##"ultrix","cc:-O2 -DNOPROTO -DNOCONST -DL_ENDIAN::(unknown):::::::",
 
 ##### MacOS X (a.k.a. Rhapsody or Darwin) setup
 "rhapsody-ppc-cc","cc:-O3 -DB_ENDIAN::(unknown):MACOSX_RHAPSODY::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}::",
 "darwin-ppc-cc","cc:-arch ppc -O3 -DB_ENDIAN -Wa,-force_cpusubtype_ALL::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "darwin64-ppc-cc","cc:-arch ppc64 -O3 -DB_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc64_asm}:osx64:dlfcn:darwin-shared:-fPIC -fno-common:-arch ppc64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "darwin-i386-cc","cc:-arch i386 -O3 -fomit-frame-pointer -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:".eval{my $asm=$x86_asm;$asm=~s/cast\-586\.o//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "debug-darwin-i386-cc","cc:-arch i386 -g3 -DL_ENDIAN::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:BN_LLONG RC4_INT RC4_CHUNK DES_UNROLL BF_PTR:${x86_asm}:macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch i386 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "darwin64-x86_64-cc","cc:-arch x86_64 -O3 -DL_ENDIAN -Wall::-D_REENTRANT:MACOSX:-Wl,-search_paths_first%:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:".eval{my $asm=$x86_64_asm;$asm=~s/rc4\-[^:]+//;$asm}.":macosx:dlfcn:darwin-shared:-fPIC -fno-common:-arch x86_64 -dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 "debug-darwin-ppc-cc","cc:-DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DCRYPTO_MDEBUG -DB_ENDIAN -g -Wall -O::-D_REENTRANT:MACOSX::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${ppc32_asm}:osx32:dlfcn:darwin-shared:-fPIC:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 # iPhoneOS/iOS
 "iphoneos-cross","llvm-gcc:-O3 -isysroot \$(CROSS_TOP)/SDKs/\$(CROSS_SDK) -fomit-frame-pointer -fno-common::-D_REENTRANT:iOS:-Wl,-search_paths_first%:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:${no_asm}:dlfcn:darwin-shared:-fPIC -fno-common:-dynamiclib:.\$(SHLIB_MAJOR).\$(SHLIB_MINOR).dylib",
 
 ##### A/UX
 "aux3-gcc","gcc:-O2 -DTERMIO::(unknown):AUX:-lbsd:RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:::",
 
 ##### Sony NEWS-OS 4.x
 "newsos4-gcc","gcc:-O -DB_ENDIAN::(unknown):NEWS4:-lmld -liberty:BN_LLONG RC4_CHAR RC4_CHUNK DES_PTR DES_RISC1 DES_UNROLL BF_PTR::::",
 
 ##### GNU Hurd
 "hurd-x86",  "gcc:-DL_ENDIAN -O3 -fomit-frame-pointer -march=i486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC",
 
 ##### OS/2 EMX
 "OS2-EMX", "gcc::::::::",
 
 ##### VxWorks for various targets
 "vxworks-ppc60x","ccppc:-D_REENTRANT -mrtp -mhard-float -mstrict-align -fno-implicit-fp -DPPC32_fp60x -O2 -fstrength-reduce -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/common:::::",
 "vxworks-ppcgen","ccppc:-D_REENTRANT -mrtp -msoft-float -mstrict-align -O1 -fno-builtin -fno-strict-aliasing -Wall -DCPU=PPC32 -DTOOL_FAMILY=gnu -DTOOL=gnu -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/usr/h/wrn/coreip:::VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/ppc/PPC32/sfcommon:::::",
 "vxworks-ppc405","ccppc:-g -msoft-float -mlongcall -DCPU=PPC405 -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
 "vxworks-ppc750","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h \$(DEBUG_FLAG):::VXWORKS:-r:::::",
 "vxworks-ppc750-debug","ccppc:-ansi -nostdinc -DPPC750 -D_REENTRANT -fvolatile -fno-builtin -fno-for-scope -fsigned-char -Wall -msoft-float -mlongcall -DCPU=PPC604 -I\$(WIND_BASE)/target/h -DBN_DEBUG -DREF_CHECK -DCONF_DEBUG -DBN_CTX_DEBUG -DCRYPTO_MDEBUG -DPEDANTIC -DDEBUG_SAFESTACK -DDEBUG -g:::VXWORKS:-r:::::",
 "vxworks-ppc860","ccppc:-nostdinc -msoft-float -DCPU=PPC860 -DNO_STRINGS_H -I\$(WIND_BASE)/target/h:::VXWORKS:-r:::::",
 "vxworks-simlinux","ccpentium:-B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DL_ENDIAN -DCPU=SIMLINUX -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/h -I\$(WIND_BASE)/target/h/wrn/coreip -DOPENSSL_NO_HW_PADLOCK:::VXWORKS:-r::${no_asm}::::::ranlibpentium:",
 "vxworks-mips","ccmips:-mrtp -mips2 -O -G 0 -B\$(WIND_BASE)/host/\$(WIND_HOST_TYPE)/lib/gcc-lib/ -D_VSB_CONFIG_FILE=\"\$(WIND_BASE)/target/lib/h/config/vsbConfig.h\" -DCPU=MIPS32 -msoft-float -mno-branch-likely -DTOOL_FAMILY=gnu -DTOOL=gnu -fno-builtin -fno-defer-pop -DNO_STRINGS_H -I\$(WIND_BASE)/target/usr/h -I\$(WIND_BASE)/target/h/wrn/coreip::-D_REENTRANT:VXWORKS:-Wl,--defsym,__wrs_rtp_base=0xe0000000 -L \$(WIND_BASE)/target/usr/lib/mips/MIPSI32/sfcommon::${mips32_asm}:o32::::::ranlibmips:",
 
 ##### Compaq Non-Stop Kernel (Tandem)
 "tandem-c89","c89:-Ww -D__TANDEM -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1 -D_TANDEM_SOURCE -DB_ENDIAN::(unknown):::THIRTY_TWO_BIT:::",
 
 # uClinux
 "uClinux-dist","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):BN_LLONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
 "uClinux-dist64","$ENV{'CC'}:\$(CFLAGS)::-D_REENTRANT::\$(LDFLAGS) \$(LDLIBS):SIXTY_FOUR_BIT_LONG:${no_asm}:$ENV{'LIBSSL_dlfcn'}:linux-shared:-fPIC:-shared:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):$ENV{'RANLIB'}::",
 
 );
 
 my @MK1MF_Builds=qw(VC-WIN64I VC-WIN64A
 		    debug-VC-WIN64I debug-VC-WIN64A
 		    VC-NT VC-CE VC-WIN32 debug-VC-WIN32
 		    BC-32 
 		    netware-clib netware-clib-bsdsock
 		    netware-libc netware-libc-bsdsock);
 
 my $idx = 0;
 my $idx_cc = $idx++;
 my $idx_cflags = $idx++;
 my $idx_unistd = $idx++;
 my $idx_thread_cflag = $idx++;
 my $idx_sys_id = $idx++;
 my $idx_lflags = $idx++;
 my $idx_bn_ops = $idx++;
 my $idx_cpuid_obj = $idx++;
 my $idx_bn_obj = $idx++;
 my $idx_des_obj = $idx++;
 my $idx_aes_obj = $idx++;
 my $idx_bf_obj = $idx++;
 my $idx_md5_obj = $idx++;
 my $idx_sha1_obj = $idx++;
 my $idx_cast_obj = $idx++;
 my $idx_rc4_obj = $idx++;
 my $idx_rmd160_obj = $idx++;
 my $idx_rc5_obj = $idx++;
 my $idx_wp_obj = $idx++;
 my $idx_cmll_obj = $idx++;
 my $idx_modes_obj = $idx++;
 my $idx_engines_obj = $idx++;
 my $idx_perlasm_scheme = $idx++;
 my $idx_dso_scheme = $idx++;
 my $idx_shared_target = $idx++;
 my $idx_shared_cflag = $idx++;
 my $idx_shared_ldflag = $idx++;
 my $idx_shared_extension = $idx++;
 my $idx_ranlib = $idx++;
 my $idx_arflags = $idx++;
 my $idx_multilib = $idx++;
 
 my $prefix="";
 my $libdir="";
 my $openssldir="";
 my $exe_ext="";
 my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
 my $cross_compile_prefix="";
 my $fipsdir="/usr/local/ssl/fips-2.0";
 my $fipslibdir="";
 my $baseaddr="0xFB00000";
 my $no_threads=0;
 my $threads=0;
 my $no_shared=0; # but "no-shared" is default
 my $zlib=1;      # but "no-zlib" is default
 my $no_krb5=0;   # but "no-krb5" is implied unless "--with-krb5-..." is used
 my $no_rfc3779=1; # but "no-rfc3779" is default
 my $no_asm=0;
 my $no_dso=0;
 my $no_gmp=0;
 my @skip=();
 my $Makefile="Makefile";
 my $des_locl="crypto/des/des_locl.h";
 my $des	="crypto/des/des.h";
 my $bn	="crypto/bn/bn.h";
 my $md2	="crypto/md2/md2.h";
 my $rc4	="crypto/rc4/rc4.h";
 my $rc4_locl="crypto/rc4/rc4_locl.h";
 my $idea	="crypto/idea/idea.h";
 my $rc2	="crypto/rc2/rc2.h";
 my $bf	="crypto/bf/bf_locl.h";
 my $bn_asm	="bn_asm.o";
 my $des_enc="des_enc.o fcrypt_b.o";
 my $aes_enc="aes_core.o aes_cbc.o";
 my $bf_enc	="bf_enc.o";
 my $cast_enc="c_enc.o";
 my $rc4_enc="rc4_enc.o rc4_skey.o";
 my $rc5_enc="rc5_enc.o";
 my $md5_obj="";
 my $sha1_obj="";
 my $rmd160_obj="";
 my $cmll_enc="camellia.o cmll_misc.o cmll_cbc.o";
 my $processor="";
 my $default_ranlib;
 my $perl;
 my $fips=0;
 
 if (exists $ENV{FIPSDIR})
 	{
 	$fipsdir = $ENV{FIPSDIR};
 	$fipsdir =~ s/\/$//;
 	}
 
 # All of the following is disabled by default (RC5 was enabled before 0.9.8):
 
 my %disabled = ( # "what"         => "comment" [or special keyword "experimental"]
 		 "ec_nistp_64_gcc_128" => "default",
 		 "gmp"		  => "default",
 		 "jpake"          => "experimental",
 		 "md2"            => "default",
 		 "rc5"            => "default",
 		 "rfc3779"	  => "default",
 		 "sctp"           => "default",
 		 "shared"         => "default",
 		 "ssl2"           => "default",
 		 "store"	  => "experimental",
 		 "unit-test"	  => "default",
 		 "weak-ssl-ciphers" => "default",
 		 "zlib"           => "default",
 		 "zlib-dynamic"   => "default"
 	       );
 my @experimental = ();
 
 # This is what $depflags will look like with the above defaults
 # (we need this to see if we should advise the user to run "make depend"):
-my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST";
+my $default_depflags = " -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL2 -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST -DOPENSSL_NO_WEAK_SSL_CIPHERS";
 
 # Explicit "no-..." options will be collected in %disabled along with the defaults.
 # To remove something from %disabled, use "enable-foo" (unless it's experimental).
 # For symmetry, "disable-foo" is a synonym for "no-foo".
 
 # For features called "experimental" here, a more explicit "experimental-foo" is needed to enable.
 # We will collect such requests in @experimental.
 # To avoid accidental use of experimental features, applications will have to use -DOPENSSL_EXPERIMENTAL_FOO.
 
 
 my $no_sse2=0;
 
 &usage if ($#ARGV < 0);
 
 my $flags;
 my $depflags;
 my $openssl_experimental_defines;
 my $openssl_algorithm_defines;
 my $openssl_thread_defines;
 my $openssl_sys_defines="";
 my $openssl_other_defines;
 my $libs;
 my $libkrb5="";
 my $target;
 my $options;
 my $symlink;
 my $make_depend=0;
 my %withargs=();
 
 my @argvcopy=@ARGV;
 my $argvstring="";
 my $argv_unprocessed=1;
 
 while($argv_unprocessed)
 	{
 	$flags="";
 	$depflags="";
 	$openssl_experimental_defines="";
 	$openssl_algorithm_defines="";
 	$openssl_thread_defines="";
 	$openssl_sys_defines="";
 	$openssl_other_defines="";
 	$libs="";
 	$target="";
 	$options="";
 	$symlink=1;
 
 	$argv_unprocessed=0;
 	$argvstring=join(' ',@argvcopy);
 
 PROCESS_ARGS:
 	foreach (@argvcopy)
 		{
 		s /^-no-/no-/; # some people just can't read the instructions
 
 		# rewrite some options in "enable-..." form
 		s /^-?-?shared$/enable-shared/;
 		s /^sctp$/enable-sctp/;
 		s /^threads$/enable-threads/;
 		s /^zlib$/enable-zlib/;
 		s /^zlib-dynamic$/enable-zlib-dynamic/;
 
 		if (/^no-(.+)$/ || /^disable-(.+)$/)
 			{
 			if (!($disabled{$1} eq "experimental"))
 				{
 				if ($1 eq "ssl")
 					{
 					$disabled{"ssl2"} = "option(ssl)";
 					$disabled{"ssl3"} = "option(ssl)";
 					}
 				elsif ($1 eq "tls")
 					{
 					$disabled{"tls1"} = "option(tls)"
 					}
 				elsif ($1 eq "ssl3-method")
 					{
 					$disabled{"ssl3-method"} = "option(ssl)";
 					$disabled{"ssl3"} = "option(ssl)";
 					}
 				else
 					{
 					$disabled{$1} = "option";
 					}
 				}			
 			}
 		elsif (/^enable-(.+)$/ || /^experimental-(.+)$/)
 			{
 			my $algo = $1;
 			if ($disabled{$algo} eq "experimental")
 				{
 				die "You are requesting an experimental feature; please say 'experimental-$algo' if you are sure\n"
 					unless (/^experimental-/);
 				push @experimental, $algo;
 				}
 			delete $disabled{$algo};
 
 			$threads = 1 if ($algo eq "threads");
 			}
 		elsif (/^--test-sanity$/)
 			{
 			exit(&test_sanity());
 			}
 		elsif (/^--strict-warnings/)
 			{
 			$strict_warnings = 1;
 			}
 		elsif (/^reconfigure/ || /^reconf/)
 			{
 			if (open(IN,"<$Makefile"))
 				{
 				while (<IN>)
 					{
 					chomp;
 					if (/^CONFIGURE_ARGS=(.*)/)
 						{
 						$argvstring=$1;
 						@argvcopy=split(' ',$argvstring);
 						die "Incorrect data to reconfigure, please do a normal configuration\n"
 							if (grep(/^reconf/,@argvcopy));
 						print "Reconfiguring with: $argvstring\n";
 						$argv_unprocessed=1;
 						close(IN);
 						last PROCESS_ARGS;
 						}
 					}
 				close(IN);
 				}
 			die "Insufficient data to reconfigure, please do a normal configuration\n";
 			}
 		elsif (/^386$/)
 			{ $processor=386; }
 		elsif (/^fips$/)
 			{
 			$fips=1;
 			}
 		elsif (/^rsaref$/)
 			{
 			# No RSAref support any more since it's not needed.
 			# The check for the option is there so scripts aren't
 			# broken
 			}
 		elsif (/^[-+]/)
 			{
 			if (/^-[lL](.*)$/ or /^-Wl,/)
 				{
 				$libs.=$_." ";
 				}
 			elsif (/^-[^-]/ or /^\+/)
 				{
 				$_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
 				$flags.=$_." ";
 				}
 			elsif (/^--prefix=(.*)$/)
 				{
 				$prefix=$1;
 				}
 			elsif (/^--libdir=(.*)$/)
 				{
 				$libdir=$1;
 				}
 			elsif (/^--openssldir=(.*)$/)
 				{
 				$openssldir=$1;
 				}
 			elsif (/^--install.prefix=(.*)$/)
 				{
 				$install_prefix=$1;
 				}
 			elsif (/^--with-krb5-(dir|lib|include|flavor)=(.*)$/)
 				{
 				$withargs{"krb5-".$1}=$2;
 				}
 			elsif (/^--with-zlib-lib=(.*)$/)
 				{
 				$withargs{"zlib-lib"}=$1;
 				}
 			elsif (/^--with-zlib-include=(.*)$/)
 				{
 				$withargs{"zlib-include"}="-I$1";
 				}
 			elsif (/^--with-fipsdir=(.*)$/)
 				{
 				$fipsdir="$1";
 				}
 			elsif (/^--with-fipslibdir=(.*)$/)
 				{
 				$fipslibdir="$1";
 				}
 			elsif (/^--with-baseaddr=(.*)$/)
 				{
 				$baseaddr="$1";
 				}
 			elsif (/^--cross-compile-prefix=(.*)$/)
 				{
 				$cross_compile_prefix=$1;
 				}
 			else
 				{
 				print STDERR $usage;
 				exit(1);
 				}
 			}
 		elsif ($_ =~ /^([^:]+):(.+)$/)
 			{
 			eval "\$table{\$1} = \"$2\""; # allow $xxx constructs in the string
 			$target=$1;
 			}
 		else
 			{
 			die "target already defined - $target (offending arg: $_)\n" if ($target ne "");
 			$target=$_;
 			}
 
 		unless ($_ eq $target || /^no-/ || /^disable-/)
 			{
 			# "no-..." follows later after implied disactivations
 			# have been derived.  (Don't take this too seroiusly,
 			# we really only write OPTIONS to the Makefile out of
 			# nostalgia.)
 
 			if ($options eq "")
 				{ $options = $_; }
 			else
 				{ $options .= " ".$_; }
 			}
 		}
 	}
 
 
 
 if ($processor eq "386")
 	{
 	$disabled{"sse2"} = "forced";
 	}
 
 if (!defined($withargs{"krb5-flavor"}) || $withargs{"krb5-flavor"} eq "")
 	{
 	$disabled{"krb5"} = "krb5-flavor not specified";
 	}
 
 if (!defined($disabled{"zlib-dynamic"}))
 	{
 	# "zlib-dynamic" was specifically enabled, so enable "zlib"
 	delete $disabled{"zlib"};
 	}
 
 if (defined($disabled{"rijndael"}))
 	{
 	$disabled{"aes"} = "forced";
 	}
 if (defined($disabled{"des"}))
 	{
 	$disabled{"mdc2"} = "forced";
 	}
 if (defined($disabled{"ec"}))
 	{
 	$disabled{"ecdsa"} = "forced";
 	$disabled{"ecdh"} = "forced";
 	}
 
 # SSL 2.0 requires MD5 and RSA
 if (defined($disabled{"md5"}) || defined($disabled{"rsa"}))
 	{
 	$disabled{"ssl2"} = "forced";
 	}
 
 if ($fips && $fipslibdir eq "")
 	{
 	$fipslibdir = $fipsdir . "/lib/";
 	}
 
 # RSAX ENGINE sets default non-FIPS RSA method.
 if ($fips)
 	{
 	$disabled{"rsax"} = "forced";
 	}
 
 # SSL 3.0 and TLS requires MD5 and SHA and either RSA or DSA+DH
 if (defined($disabled{"md5"}) || defined($disabled{"sha"})
     || (defined($disabled{"rsa"})
         && (defined($disabled{"dsa"}) || defined($disabled{"dh"}))))
 	{
 	$disabled{"ssl3"} = "forced";
 	$disabled{"tls1"} = "forced";
 	}
 
 if (defined($disabled{"tls1"}))
 	{
 	$disabled{"tlsext"} = "forced";
 	}
 
 if (defined($disabled{"ec"}) || defined($disabled{"dsa"})
     || defined($disabled{"dh"}))
 	{
 	$disabled{"gost"} = "forced";
 	}
 
 # SRP and HEARTBEATS require TLSEXT
 if (defined($disabled{"tlsext"}))
 	{
 	$disabled{"srp"} = "forced";
 	$disabled{"heartbeats"} = "forced";
 	}
 
 if ($target eq "TABLE") {
 	foreach $target (sort keys %table) {
 		print_table_entry($target);
 	}
 	exit 0;
 }
 
 if ($target eq "LIST") {
 	foreach (sort keys %table) {
 		print;
 		print "\n";
 	}
 	exit 0;
 }
 
 if ($target =~ m/^CygWin32(-.*)$/) {
 	$target = "Cygwin".$1;
 }
 
 print "Configuring for $target\n";
 
 &usage if (!defined($table{$target}));
 
 
 foreach (sort (keys %disabled))
 	{
 	$options .= " no-$_";
 
 	printf "    no-%-12s %-10s", $_, "[$disabled{$_}]";
 
 	if (/^dso$/)
 		{ $no_dso = 1; }
 	elsif (/^threads$/)
 		{ $no_threads = 1; }
 	elsif (/^shared$/)
 		{ $no_shared = 1; }
 	elsif (/^zlib$/)
 		{ $zlib = 0; }
 	elsif (/^static-engine$/)
 		{ }
 	elsif (/^zlib-dynamic$/)
 		{ }
 	elsif (/^symlinks$/)
 		{ $symlink = 0; }
 	elsif (/^sse2$/)
 		{ $no_sse2 = 1; }
 	else
 		{
 		my ($ALGO, $algo);
 		($ALGO = $algo = $_) =~ tr/[\-a-z]/[_A-Z]/;
 
 		if (/^asm$/ || /^err$/ || /^hw$/ || /^hw-/)
 			{
 			$openssl_other_defines .= "#define OPENSSL_NO_$ALGO\n";
 			print " OPENSSL_NO_$ALGO";
 		
 			if (/^err$/)	{ $flags .= "-DOPENSSL_NO_ERR "; }
 			elsif (/^asm$/)	{ $no_asm = 1; }
 			}
 		else
 			{
 			$openssl_algorithm_defines .= "#define OPENSSL_NO_$ALGO\n";
 			print " OPENSSL_NO_$ALGO";
 
 			if (/^krb5$/)
 				{ $no_krb5 = 1; }
 			else
 				{
 				push @skip, $algo;
 				# fix-up crypto/directory name(s)
 				@skip[$#skip]="whrlpool" if $algo eq "whirlpool";
 				print " (skip dir)";
 
 				$depflags .= " -DOPENSSL_NO_$ALGO";
 				}
 			}
 		}
 
 	print "\n";
 	}
 
 my $exp_cflags = "";
 foreach (sort @experimental)
 	{
 	my $ALGO;
 	($ALGO = $_) =~ tr/[a-z]/[A-Z]/;
 
 	# opensslconf.h will set OPENSSL_NO_... unless OPENSSL_EXPERIMENTAL_... is defined
 	$openssl_experimental_defines .= "#define OPENSSL_NO_$ALGO\n";
 	$exp_cflags .= " -DOPENSSL_EXPERIMENTAL_$ALGO";
 	}
 
 my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
 
 $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
 $exe_ext=".nlm" if ($target =~ /netware/);
 $exe_ext=".pm"  if ($target =~ /vos/);
 $openssldir="/usr/local/ssl" if ($openssldir eq "" and $prefix eq "");
 $prefix=$openssldir if $prefix eq "";
 
 $default_ranlib= &which("ranlib") or $default_ranlib="true";
 $perl=$ENV{'PERL'} or $perl=&which("perl5") or $perl=&which("perl")
   or $perl="perl";
 my $make = $ENV{'MAKE'} || "make";
 
 $cross_compile_prefix=$ENV{'CROSS_COMPILE'} if $cross_compile_prefix eq "";
 
 chop $openssldir if $openssldir =~ /\/$/;
 chop $prefix if $prefix =~ /.\/$/;
 
 $openssldir=$prefix . "/ssl" if $openssldir eq "";
 $openssldir=$prefix . "/" . $openssldir if $openssldir !~ /(^\/|^[a-zA-Z]:[\\\/])/;
 
 
 print "IsMK1MF=$IsMK1MF\n";
 
 my @fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
 my $cc = $fields[$idx_cc];
 # Allow environment CC to override compiler...
 if($ENV{CC}) {
     $cc = $ENV{CC};
 }
 my $cflags = $fields[$idx_cflags];
 my $unistd = $fields[$idx_unistd];
 my $thread_cflag = $fields[$idx_thread_cflag];
 my $sys_id = $fields[$idx_sys_id];
 my $lflags = $fields[$idx_lflags];
 my $bn_ops = $fields[$idx_bn_ops];
 my $cpuid_obj = $fields[$idx_cpuid_obj];
 my $bn_obj = $fields[$idx_bn_obj];
 my $des_obj = $fields[$idx_des_obj];
 my $aes_obj = $fields[$idx_aes_obj];
 my $bf_obj = $fields[$idx_bf_obj];
 my $md5_obj = $fields[$idx_md5_obj];
 my $sha1_obj = $fields[$idx_sha1_obj];
 my $cast_obj = $fields[$idx_cast_obj];
 my $rc4_obj = $fields[$idx_rc4_obj];
 my $rmd160_obj = $fields[$idx_rmd160_obj];
 my $rc5_obj = $fields[$idx_rc5_obj];
 my $wp_obj = $fields[$idx_wp_obj];
 my $cmll_obj = $fields[$idx_cmll_obj];
 my $modes_obj = $fields[$idx_modes_obj];
 my $engines_obj = $fields[$idx_engines_obj];
 my $perlasm_scheme = $fields[$idx_perlasm_scheme];
 my $dso_scheme = $fields[$idx_dso_scheme];
 my $shared_target = $fields[$idx_shared_target];
 my $shared_cflag = $fields[$idx_shared_cflag];
 my $shared_ldflag = $fields[$idx_shared_ldflag];
 my $shared_extension = $fields[$idx_shared_extension];
 my $ranlib = $ENV{'RANLIB'} || $fields[$idx_ranlib];
 my $ar = $ENV{'AR'} || "ar";
 my $arflags = $fields[$idx_arflags];
 my $multilib = $fields[$idx_multilib];
 
 # if $prefix/lib$multilib is not an existing directory, then
 # assume that it's not searched by linker automatically, in
 # which case adding $multilib suffix causes more grief than
 # we're ready to tolerate, so don't...
 $multilib="" if !-d "$prefix/lib$multilib";
 
 $libdir="lib$multilib" if $libdir eq "";
 
 $cflags = "$cflags$exp_cflags";
 
 # '%' in $lflags is used to split flags to "pre-" and post-flags
 my ($prelflags,$postlflags)=split('%',$lflags);
 if (defined($postlflags))	{ $lflags=$postlflags;	}
 else				{ $lflags=$prelflags; undef $prelflags;	}
 
 if ($target =~ /^mingw/ && `$cc --target-help 2>&1` !~ m/\-mno\-cygwin/m)
 	{
 	$cflags =~ s/\-mno\-cygwin\s*//;
 	$shared_ldflag =~ s/\-mno\-cygwin\s*//;
 	}
 
 my $no_shared_warn=0;
 my $no_user_cflags=0;
 
 if ($flags ne "")	{ $cflags="$flags$cflags"; }
 else			{ $no_user_cflags=1;       }
 
 # Kerberos settings.  The flavor must be provided from outside, either through
 # the script "config" or manually.
 if (!$no_krb5)
 	{
 	my ($lresolv, $lpath, $lext);
 	if ($withargs{"krb5-flavor"} =~ /^[Hh]eimdal$/)
 		{
 		die "Sorry, Heimdal is currently not supported\n";
 		}
 	##### HACK to force use of Heimdal.
 	##### WARNING: Since we don't really have adequate support for Heimdal,
 	#####          using this will break the build.  You'll have to make
 	#####          changes to the source, and if you do, please send
 	#####          patches to openssl-dev@openssl.org
 	if ($withargs{"krb5-flavor"} =~ /^force-[Hh]eimdal$/)
 		{
 		warn "Heimdal isn't really supported.  Your build WILL break\n";
 		warn "If you fix the problems, please send a patch to openssl-dev\@openssl.org\n";
 		$withargs{"krb5-dir"} = "/usr/heimdal"
 			if $withargs{"krb5-dir"} eq "";
 		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
 			"/lib -lgssapi -lkrb5 -lcom_err"
 			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
 		$cflags="-DKRB5_HEIMDAL $cflags";
 		}
 	if ($withargs{"krb5-flavor"} =~ /^[Mm][Ii][Tt]/)
 		{
 		$withargs{"krb5-dir"} = "/usr/kerberos"
 			if $withargs{"krb5-dir"} eq "";
 		$withargs{"krb5-lib"} = "-L".$withargs{"krb5-dir"}.
 			"/lib -lgssapi_krb5 -lkrb5 -lcom_err -lk5crypto"
 			if $withargs{"krb5-lib"} eq "" && !$IsMK1MF;
 		$cflags="-DKRB5_MIT $cflags";
 		$withargs{"krb5-flavor"} =~ s/^[Mm][Ii][Tt][._-]*//;
 		if ($withargs{"krb5-flavor"} =~ /^1[._-]*[01]/)
 			{
 			$cflags="-DKRB5_MIT_OLD11 $cflags";
 			}
 		}
 	LRESOLV:
 	foreach $lpath ("/lib", "/usr/lib")
 		{
 		foreach $lext ("a", "so")
 			{
 			$lresolv = "$lpath/libresolv.$lext";
 			last LRESOLV	if (-r "$lresolv");
 			$lresolv = "";
 			}
 		}
 	$withargs{"krb5-lib"} .= " -lresolv"
 		if ("$lresolv" ne "");
 	$withargs{"krb5-include"} = "-I".$withargs{"krb5-dir"}."/include"
 		if $withargs{"krb5-include"} eq "" &&
 		   $withargs{"krb5-dir"} ne "";
 	}
 
 # The DSO code currently always implements all functions so that no
 # applications will have to worry about that from a compilation point
 # of view. However, the "method"s may return zero unless that platform
 # has support compiled in for them. Currently each method is enabled
 # by a define "DSO_<name>" ... we translate the "dso_scheme" config
 # string entry into using the following logic;
 my $dso_cflags;
 if (!$no_dso && $dso_scheme ne "")
 	{
 	$dso_scheme =~ tr/[a-z]/[A-Z]/;
 	if ($dso_scheme eq "DLFCN")
 		{
 		$dso_cflags = "-DDSO_DLFCN -DHAVE_DLFCN_H";
 		}
 	elsif ($dso_scheme eq "DLFCN_NO_H")
 		{
 		$dso_cflags = "-DDSO_DLFCN";
 		}
 	else
 		{
 		$dso_cflags = "-DDSO_$dso_scheme";
 		}
 	$cflags = "$dso_cflags $cflags";
 	}
 
 my $thread_cflags;
 my $thread_defines;
 if ($thread_cflag ne "(unknown)" && !$no_threads)
 	{
 	# If we know how to do it, support threads by default.
 	$threads = 1;
 	}
 if ($thread_cflag eq "(unknown)" && $threads)
 	{
 	# If the user asked for "threads", [s]he is also expected to
 	# provide any system-dependent compiler options that are
 	# necessary.
 	if ($no_user_cflags)
 		{
 		print "You asked for multi-threading support, but didn't\n";
 		print "provide any system-specific compiler options\n";
 		exit(1);
 		}
 	$thread_cflags="-DOPENSSL_THREADS $cflags" ;
 	$thread_defines .= "#define OPENSSL_THREADS\n";
 	}
 else
 	{
 	$thread_cflags="-DOPENSSL_THREADS $thread_cflag $cflags";
 	$thread_defines .= "#define OPENSSL_THREADS\n";
 #	my $def;
 #	foreach $def (split ' ',$thread_cflag)
 #		{
 #		if ($def =~ s/^-D// && $def !~ /^_/)
 #			{
 #			$thread_defines .= "#define $def\n";
 #			}
 #		}
 	}	
 
 $lflags="$libs$lflags" if ($libs ne "");
 
 if ($no_asm)
 	{
 	$cpuid_obj=$bn_obj=
 	$des_obj=$aes_obj=$bf_obj=$cast_obj=$rc4_obj=$rc5_obj=$cmll_obj=
 	$modes_obj=$sha1_obj=$md5_obj=$rmd160_obj=$wp_obj=$engines_obj="";
 	}
 
 if (!$no_shared)
 	{
 	$cast_obj="";	# CAST assembler is not PIC
 	}
 
 if ($threads)
 	{
 	$cflags=$thread_cflags;
 	$openssl_thread_defines .= $thread_defines;
 	}
 
 if ($zlib)
 	{
 	$cflags = "-DZLIB $cflags";
 	if (defined($disabled{"zlib-dynamic"}))
 		{
 		if (defined($withargs{"zlib-lib"}))
 			{
 			$lflags = "$lflags -L" . $withargs{"zlib-lib"} . " -lz";
 			}
 		else
 			{
 			$lflags = "$lflags -lz";
 			}
 		}
 	else
 		{
 		$cflags = "-DZLIB_SHARED $cflags";
 		}
 	}
 
 # You will find shlib_mark1 and shlib_mark2 explained in Makefile.org
 my $shared_mark = "";
 if ($shared_target eq "")
 	{
 	$no_shared_warn = 1 if !$no_shared;
 	$no_shared = 1;
 	}
 if (!$no_shared)
 	{
 	if ($shared_cflag ne "")
 		{
 		$cflags = "$shared_cflag -DOPENSSL_PIC $cflags";
 		}
 	}
 
 if (!$IsMK1MF)
 	{
 	# add {no-}static-engine to options to allow mkdef.pl to work without extra arguments
 	if ($no_shared)
 		{
 		$openssl_other_defines.="#define OPENSSL_NO_DYNAMIC_ENGINE\n";
 		$options.=" static-engine";
 		}
 	else
 		{
 		$openssl_other_defines.="#define OPENSSL_NO_STATIC_ENGINE\n";
 		$options.=" no-static-engine";
 		}
 	}
 
 $cpuid_obj.=" uplink.o uplink-x86.o" if ($cflags =~ /\-DOPENSSL_USE_APPLINK/);
 
 #
 # Platform fix-ups
 #
 if ($target =~ /\-icc$/)	# Intel C compiler
 	{
 	my $iccver=0;
 	if (open(FD,"$cc -V 2>&1 |"))
 		{
 		while(<FD>) { $iccver=$1 if (/Version ([0-9]+)\./); }
 		close(FD);
 		}
 	if ($iccver>=8)
 		{
 		# Eliminate unnecessary dependency from libirc.a. This is
 		# essential for shared library support, as otherwise
 		# apps/openssl can end up in endless loop upon startup...
 		$cflags.=" -Dmemcpy=__builtin_memcpy -Dmemset=__builtin_memset";
 		}
 	if ($iccver>=9)
 		{
 		$cflags.=" -i-static";
 		$cflags=~s/\-no_cpprt/-no-cpprt/;
 		}
 	if ($iccver>=10)
 		{
 		$cflags=~s/\-i\-static/-static-intel/;
 		}
 	}
 
 # Unlike other OSes (like Solaris, Linux, Tru64, IRIX) BSD run-time
 # linkers (tested OpenBSD, NetBSD and FreeBSD) "demand" RPATH set on
 # .so objects. Apparently application RPATH is not global and does
 # not apply to .so linked with other .so. Problem manifests itself
 # when libssl.so fails to load libcrypto.so. One can argue that we
 # should engrave this into Makefile.shared rules or into BSD-* config
 # lines above. Meanwhile let's try to be cautious and pass -rpath to
 # linker only when --prefix is not /usr.
 if ($target =~ /^BSD\-/)
 	{
 	$shared_ldflag.=" -Wl,-rpath,\$\$(LIBRPATH)" if ($prefix !~ m|^/usr[/]*$|);
 	}
 
 if ($sys_id ne "")
 	{
 	#$cflags="-DOPENSSL_SYSNAME_$sys_id $cflags";
 	$openssl_sys_defines="#define OPENSSL_SYSNAME_$sys_id\n";
 	}
 
 if ($ranlib eq "")
 	{
 	$ranlib = $default_ranlib;
 	}
 
 #my ($bn1)=split(/\s+/,$bn_obj);
 #$bn1 = "" unless defined $bn1;
 #$bn1=$bn_asm unless ($bn1 =~ /\.o$/);
 #$bn_obj="$bn1";
 
 $cpuid_obj="" if ($processor eq "386");
 
 $bn_obj = $bn_asm unless $bn_obj ne "";
 # bn-586 is the only one implementing bn_*_part_words
 $cflags.=" -DOPENSSL_BN_ASM_PART_WORDS" if ($bn_obj =~ /bn-586/);
 $cflags.=" -DOPENSSL_IA32_SSE2" if (!$no_sse2 && $bn_obj =~ /86/);
 
 $cflags.=" -DOPENSSL_BN_ASM_MONT" if ($bn_obj =~ /-mont/);
 $cflags.=" -DOPENSSL_BN_ASM_MONT5" if ($bn_obj =~ /-mont5/);
 $cflags.=" -DOPENSSL_BN_ASM_GF2m" if ($bn_obj =~ /-gf2m/);
 
 if ($fips)
 	{
 	$openssl_other_defines.="#define OPENSSL_FIPS\n";
 	$cflags .= " -I\$(FIPSDIR)/include";
 	}
 
 $cpuid_obj="mem_clr.o"	unless ($cpuid_obj =~ /\.o$/);
 $des_obj=$des_enc	unless ($des_obj =~ /\.o$/);
 $bf_obj=$bf_enc		unless ($bf_obj =~ /\.o$/);
 $cast_obj=$cast_enc	unless ($cast_obj =~ /\.o$/);
 $rc4_obj=$rc4_enc	unless ($rc4_obj =~ /\.o$/);
 $rc5_obj=$rc5_enc	unless ($rc5_obj =~ /\.o$/);
 if ($sha1_obj =~ /\.o$/)
 	{
 #	$sha1_obj=$sha1_enc;
 	$cflags.=" -DSHA1_ASM"   if ($sha1_obj =~ /sx86/ || $sha1_obj =~ /sha1/);
 	$cflags.=" -DSHA256_ASM" if ($sha1_obj =~ /sha256/);
 	$cflags.=" -DSHA512_ASM" if ($sha1_obj =~ /sha512/);
 	if ($sha1_obj =~ /sse2/)
 	    {	if ($no_sse2)
 		{   $sha1_obj =~ s/\S*sse2\S+//;        }
 		elsif ($cflags !~ /OPENSSL_IA32_SSE2/)
 		{   $cflags.=" -DOPENSSL_IA32_SSE2";    }
 	    }
 	}
 if ($md5_obj =~ /\.o$/)
 	{
 #	$md5_obj=$md5_enc;
 	$cflags.=" -DMD5_ASM";
 	}
 if ($rmd160_obj =~ /\.o$/)
 	{
 #	$rmd160_obj=$rmd160_enc;
 	$cflags.=" -DRMD160_ASM";
 	}
 if ($aes_obj =~ /\.o$/)
 	{
 	$cflags.=" -DAES_ASM";
 	# aes-ctr.o is not a real file, only indication that assembler
 	# module implements AES_ctr32_encrypt...
 	$cflags.=" -DAES_CTR_ASM" if ($aes_obj =~ s/\s*aes\-ctr\.o//);
 	# aes-xts.o indicates presense of AES_xts_[en|de]crypt...
 	$cflags.=" -DAES_XTS_ASM" if ($aes_obj =~ s/\s*aes\-xts\.o//);
 	$aes_obj =~ s/\s*(vpaes|aesni)\-x86\.o//g if ($no_sse2);
 	$cflags.=" -DVPAES_ASM" if ($aes_obj =~ m/vpaes/);
 	$cflags.=" -DBSAES_ASM" if ($aes_obj =~ m/bsaes/);
 	}
 else	{
 	$aes_obj=$aes_enc;
 	}
 $wp_obj="" if ($wp_obj =~ /mmx/ && $processor eq "386");
 if ($wp_obj =~ /\.o$/ && !$disabled{"whirlpool"})
 	{
 	$cflags.=" -DWHIRLPOOL_ASM";
 	}
 else	{
 	$wp_obj="wp_block.o";
 	}
 $cmll_obj=$cmll_enc	unless ($cmll_obj =~ /.o$/);
 if ($modes_obj =~ /ghash/)
 	{
 	$cflags.=" -DGHASH_ASM";
 	}
 
 # "Stringify" the C flags string.  This permits it to be made part of a string
 # and works as well on command lines.
 $cflags =~ s/([\\\"])/\\\1/g;
 
 my $version = "unknown";
 my $version_num = "unknown";
 my $major = "unknown";
 my $minor = "unknown";
 my $shlib_version_number = "unknown";
 my $shlib_version_history = "unknown";
 my $shlib_major = "unknown";
 my $shlib_minor = "unknown";
 
 open(IN,'<crypto/opensslv.h') || die "unable to read opensslv.h:$!\n";
 while (<IN>)
 	{
 	$version=$1 if /OPENSSL.VERSION.TEXT.*OpenSSL (\S+) /;
 	$version_num=$1 if /OPENSSL.VERSION.NUMBER.*0x(\S+)/;
 	$shlib_version_number=$1 if /SHLIB_VERSION_NUMBER *"([^"]+)"/;
 	$shlib_version_history=$1 if /SHLIB_VERSION_HISTORY *"([^"]*)"/;
 	}
 close(IN);
 if ($shlib_version_history ne "") { $shlib_version_history .= ":"; }
 
 if ($version =~ /(^[0-9]*)\.([0-9\.]*)/)
 	{
 	$major=$1;
 	$minor=$2;
 	}
 
 if ($shlib_version_number =~ /(^[0-9]*)\.([0-9\.]*)/)
 	{
 	$shlib_major=$1;
 	$shlib_minor=$2;
 	}
 
 if ($strict_warnings)
 	{
 	my $ecc = $cc;
 	$ecc = "clang" if `$cc --version 2>&1` =~ /clang/;
 	my $wopt;
 	die "ERROR --strict-warnings requires gcc or clang" unless ($ecc =~ /gcc$/ or $ecc =~ /clang$/);
 	foreach $wopt (split /\s+/, $gcc_devteam_warn)
 		{
 		$cflags .= " $wopt" unless ($cflags =~ /(^|\s)$wopt(\s|$)/)
 		}
 	if ($ecc eq "clang")
 		{
 		foreach $wopt (split /\s+/, $clang_devteam_warn)
 			{
 			$cflags .= " $wopt" unless ($cflags =~ /(^|\s)$wopt(\s|$)/)
 			}
 		}
 	}
 
 open(IN,'<Makefile.org') || die "unable to read Makefile.org:$!\n";
 unlink("$Makefile.new") || die "unable to remove old $Makefile.new:$!\n" if -e "$Makefile.new";
 open(OUT,">$Makefile.new") || die "unable to create $Makefile.new:$!\n";
 print OUT "### Generated automatically from Makefile.org by Configure.\n\n";
 my $sdirs=0;
 while (<IN>)
 	{
 	chomp;
 	$sdirs = 1 if /^SDIRS=/;
 	if ($sdirs) {
 		my $dir;
 		foreach $dir (@skip) {
 			s/(\s)$dir /$1/;
 			s/\s$dir$//;
 			}
 		}
 	$sdirs = 0 unless /\\$/;
         s/engines // if (/^DIRS=/ && $disabled{"engine"});
 	s/ccgost// if (/^ENGDIRS=/ && $disabled{"gost"});
 	s/^VERSION=.*/VERSION=$version/;
 	s/^MAJOR=.*/MAJOR=$major/;
 	s/^MINOR=.*/MINOR=$minor/;
 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
 	s/^SHLIB_MINOR=.*/SHLIB_MINOR=$shlib_minor/;
 	s/^SHLIB_EXT=.*/SHLIB_EXT=$shared_extension/;
 	s/^INSTALLTOP=.*$/INSTALLTOP=$prefix/;
 	s/^MULTILIB=.*$/MULTILIB=$multilib/;
 	s/^OPENSSLDIR=.*$/OPENSSLDIR=$openssldir/;
 	s/^LIBDIR=.*$/LIBDIR=$libdir/;
 	s/^INSTALL_PREFIX=.*$/INSTALL_PREFIX=$install_prefix/;
 	s/^PLATFORM=.*$/PLATFORM=$target/;
 	s/^OPTIONS=.*$/OPTIONS=$options/;
 	s/^CONFIGURE_ARGS=.*$/CONFIGURE_ARGS=$argvstring/;
 	if ($cross_compile_prefix)
 		{
 		s/^CC=.*$/CROSS_COMPILE= $cross_compile_prefix\nCC= \$\(CROSS_COMPILE\)$cc/;
 		s/^AR=\s*/AR= \$\(CROSS_COMPILE\)/;
 		s/^NM=\s*/NM= \$\(CROSS_COMPILE\)/;
 		s/^RANLIB=\s*/RANLIB= \$\(CROSS_COMPILE\)/;
 		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= \$\(CROSS_COMPILE\)$cc/ if $cc eq "gcc";
 		}
 	else	{
 		s/^CC=.*$/CC= $cc/;
 		s/^AR=\s*ar/AR= $ar/;
 		s/^RANLIB=.*/RANLIB= $ranlib/;
 		s/^MAKEDEPPROG=.*$/MAKEDEPPROG= $cc/ if $cc eq "gcc";
 		}
 	s/^CFLAG=.*$/CFLAG= $cflags/;
 	s/^DEPFLAG=.*$/DEPFLAG=$depflags/;
 	s/^PEX_LIBS=.*$/PEX_LIBS= $prelflags/;
 	s/^EX_LIBS=.*$/EX_LIBS= $lflags/;
 	s/^EXE_EXT=.*$/EXE_EXT= $exe_ext/;
 	s/^CPUID_OBJ=.*$/CPUID_OBJ= $cpuid_obj/;
 	s/^BN_ASM=.*$/BN_ASM= $bn_obj/;
 	s/^DES_ENC=.*$/DES_ENC= $des_obj/;
 	s/^AES_ENC=.*$/AES_ENC= $aes_obj/;
 	s/^BF_ENC=.*$/BF_ENC= $bf_obj/;
 	s/^CAST_ENC=.*$/CAST_ENC= $cast_obj/;
 	s/^RC4_ENC=.*$/RC4_ENC= $rc4_obj/;
 	s/^RC5_ENC=.*$/RC5_ENC= $rc5_obj/;
 	s/^MD5_ASM_OBJ=.*$/MD5_ASM_OBJ= $md5_obj/;
 	s/^SHA1_ASM_OBJ=.*$/SHA1_ASM_OBJ= $sha1_obj/;
 	s/^RMD160_ASM_OBJ=.*$/RMD160_ASM_OBJ= $rmd160_obj/;
 	s/^WP_ASM_OBJ=.*$/WP_ASM_OBJ= $wp_obj/;
 	s/^CMLL_ENC=.*$/CMLL_ENC= $cmll_obj/;
 	s/^MODES_ASM_OBJ.=*$/MODES_ASM_OBJ= $modes_obj/;
 	s/^ENGINES_ASM_OBJ.=*$/ENGINES_ASM_OBJ= $engines_obj/;
 	s/^PERLASM_SCHEME=.*$/PERLASM_SCHEME= $perlasm_scheme/;
 	s/^PROCESSOR=.*/PROCESSOR= $processor/;
 	s/^ARFLAGS=.*/ARFLAGS= $arflags/;
 	s/^PERL=.*/PERL= $perl/;
 	s/^KRB5_INCLUDES=.*/KRB5_INCLUDES=$withargs{"krb5-include"}/;
 	s/^LIBKRB5=.*/LIBKRB5=$withargs{"krb5-lib"}/;
 	s/^LIBZLIB=.*/LIBZLIB=$withargs{"zlib-lib"}/;
 	s/^ZLIB_INCLUDE=.*/ZLIB_INCLUDE=$withargs{"zlib-include"}/;
 
 	s/^FIPSDIR=.*/FIPSDIR=$fipsdir/;
 	s/^FIPSLIBDIR=.*/FIPSLIBDIR=$fipslibdir/;
 	s/^FIPSCANLIB=.*/FIPSCANLIB=libcrypto/ if $fips;
 	s/^BASEADDR=.*/BASEADDR=$baseaddr/;
 
 	s/^SHLIB_TARGET=.*/SHLIB_TARGET=$shared_target/;
 	s/^SHLIB_MARK=.*/SHLIB_MARK=$shared_mark/;
 	s/^SHARED_LIBS=.*/SHARED_LIBS=\$(SHARED_CRYPTO) \$(SHARED_SSL)/ if (!$no_shared);
 	if ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*$/)
 		{
 		my $sotmp = $1;
 		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp/;
 		}
 	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.dylib$/)
 		{
 		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.dylib/;
 		}
 	elsif ($shared_extension ne "" && $shared_extension =~ /^\.s([ol])\.[^\.]*\.[^\.]*$/)
 		{
 		my $sotmp = $1;
 		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.s$sotmp.\$(SHLIB_MAJOR) .s$sotmp/;
 		}
 	elsif ($shared_extension ne "" && $shared_extension =~ /^\.[^\.]*\.[^\.]*\.dylib$/)
 		{
 		s/^SHARED_LIBS_LINK_EXTS=.*/SHARED_LIBS_LINK_EXTS=.\$(SHLIB_MAJOR).dylib .dylib/;
 		}
 	s/^SHARED_LDFLAGS=.*/SHARED_LDFLAGS=$shared_ldflag/;
 	print OUT $_."\n";
 	}
 close(IN);
 close(OUT);
 rename($Makefile,"$Makefile.bak") || die "unable to rename $Makefile\n" if -e $Makefile;
 rename("$Makefile.new",$Makefile) || die "unable to rename $Makefile.new\n";
 
 print "CC            =$cc\n";
 print "CFLAG         =$cflags\n";
 print "EX_LIBS       =$lflags\n";
 print "CPUID_OBJ     =$cpuid_obj\n";
 print "BN_ASM        =$bn_obj\n";
 print "DES_ENC       =$des_obj\n";
 print "AES_ENC       =$aes_obj\n";
 print "BF_ENC        =$bf_obj\n";
 print "CAST_ENC      =$cast_obj\n";
 print "RC4_ENC       =$rc4_obj\n";
 print "RC5_ENC       =$rc5_obj\n";
 print "MD5_OBJ_ASM   =$md5_obj\n";
 print "SHA1_OBJ_ASM  =$sha1_obj\n";
 print "RMD160_OBJ_ASM=$rmd160_obj\n";
 print "CMLL_ENC      =$cmll_obj\n";
 print "MODES_OBJ     =$modes_obj\n";
 print "ENGINES_OBJ   =$engines_obj\n";
 print "PROCESSOR     =$processor\n";
 print "RANLIB        =$ranlib\n";
 print "ARFLAGS       =$arflags\n";
 print "PERL          =$perl\n";
 print "KRB5_INCLUDES =",$withargs{"krb5-include"},"\n"
 	if $withargs{"krb5-include"} ne "";
 
 my $des_ptr=0;
 my $des_risc1=0;
 my $des_risc2=0;
 my $des_unroll=0;
 my $bn_ll=0;
 my $def_int=2;
 my $rc4_int=$def_int;
 my $md2_int=$def_int;
 my $idea_int=$def_int;
 my $rc2_int=$def_int;
 my $rc4_idx=0;
 my $rc4_chunk=0;
 my $bf_ptr=0;
 my @type=("char","short","int","long");
 my ($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0);
 my $export_var_as_fn=0;
 
 my $des_int;
 
 foreach (sort split(/\s+/,$bn_ops))
 	{
 	$des_ptr=1 if /DES_PTR/;
 	$des_risc1=1 if /DES_RISC1/;
 	$des_risc2=1 if /DES_RISC2/;
 	$des_unroll=1 if /DES_UNROLL/;
 	$des_int=1 if /DES_INT/;
 	$bn_ll=1 if /BN_LLONG/;
 	$rc4_int=0 if /RC4_CHAR/;
 	$rc4_int=3 if /RC4_LONG/;
 	$rc4_idx=1 if /RC4_INDEX/;
 	$rc4_chunk=1 if /RC4_CHUNK/;
 	$rc4_chunk=2 if /RC4_CHUNK_LL/;
 	$md2_int=0 if /MD2_CHAR/;
 	$md2_int=3 if /MD2_LONG/;
 	$idea_int=1 if /IDEA_SHORT/;
 	$idea_int=3 if /IDEA_LONG/;
 	$rc2_int=1 if /RC2_SHORT/;
 	$rc2_int=3 if /RC2_LONG/;
 	$bf_ptr=1 if $_ eq "BF_PTR";
 	$bf_ptr=2 if $_ eq "BF_PTR2";
 	($b64l,$b64,$b32,$b16,$b8)=(0,1,0,0,0) if /SIXTY_FOUR_BIT/;
 	($b64l,$b64,$b32,$b16,$b8)=(1,0,0,0,0) if /SIXTY_FOUR_BIT_LONG/;
 	($b64l,$b64,$b32,$b16,$b8)=(0,0,1,0,0) if /THIRTY_TWO_BIT/;
 	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,1,0) if /SIXTEEN_BIT/;
 	($b64l,$b64,$b32,$b16,$b8)=(0,0,0,0,1) if /EIGHT_BIT/;
 	$export_var_as_fn=1 if /EXPORT_VAR_AS_FN/;
 	}
 
 open(IN,'<crypto/opensslconf.h.in') || die "unable to read crypto/opensslconf.h.in:$!\n";
 unlink("crypto/opensslconf.h.new") || die "unable to remove old crypto/opensslconf.h.new:$!\n" if -e "crypto/opensslconf.h.new";
 open(OUT,'>crypto/opensslconf.h.new') || die "unable to create crypto/opensslconf.h.new:$!\n";
 print OUT "/* opensslconf.h */\n";
 print OUT "/* WARNING: Generated automatically from opensslconf.h.in by Configure. */\n\n";
 
 print OUT "#ifdef  __cplusplus\n";
 print OUT "extern \"C\" {\n";
 print OUT "#endif\n";
 print OUT "/* OpenSSL was configured with the following options: */\n";
 my $openssl_algorithm_defines_trans = $openssl_algorithm_defines;
 $openssl_experimental_defines =~ s/^\s*#\s*define\s+OPENSSL_NO_(.*)/#ifndef OPENSSL_EXPERIMENTAL_$1\n# ifndef OPENSSL_NO_$1\n#  define OPENSSL_NO_$1\n# endif\n#endif/mg;
 $openssl_algorithm_defines_trans =~ s/^\s*#\s*define\s+OPENSSL_(.*)/# if defined(OPENSSL_$1) \&\& !defined($1)\n#  define $1\n# endif/mg;
 $openssl_algorithm_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
 $openssl_algorithm_defines = "   /* no ciphers excluded */\n" if $openssl_algorithm_defines eq "";
 $openssl_thread_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
 $openssl_sys_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
 $openssl_other_defines =~ s/^\s*#\s*define\s+(.*)/#ifndef $1\n# define $1\n#endif/mg;
 print OUT $openssl_sys_defines;
 print OUT "#ifndef OPENSSL_DOING_MAKEDEPEND\n\n";
 print OUT $openssl_experimental_defines;
 print OUT "\n";
 print OUT $openssl_algorithm_defines;
 print OUT "\n#endif /* OPENSSL_DOING_MAKEDEPEND */\n\n";
 print OUT $openssl_thread_defines;
 print OUT $openssl_other_defines,"\n";
 
 print OUT "/* The OPENSSL_NO_* macros are also defined as NO_* if the application\n";
 print OUT "   asks for it.  This is a transient feature that is provided for those\n";
 print OUT "   who haven't had the time to do the appropriate changes in their\n";
 print OUT "   applications.  */\n";
 print OUT "#ifdef OPENSSL_ALGORITHM_DEFINES\n";
 print OUT $openssl_algorithm_defines_trans;
 print OUT "#endif\n\n";
 
 print OUT "#define OPENSSL_CPUID_OBJ\n\n" if ($cpuid_obj ne "mem_clr.o");
 
 while (<IN>)
 	{
 	if	(/^#define\s+OPENSSLDIR/)
 		{
 		my $foo = $openssldir;
 		$foo =~ s/\\/\\\\/g;
 		print OUT "#define OPENSSLDIR \"$foo\"\n";
 		}
 	elsif	(/^#define\s+ENGINESDIR/)
 		{
 		my $foo = "$prefix/$libdir/engines";
 		$foo =~ s/\\/\\\\/g;
 		print OUT "#define ENGINESDIR \"$foo\"\n";
 		}
 	elsif	(/^#((define)|(undef))\s+OPENSSL_EXPORT_VAR_AS_FUNCTION/)
 		{ printf OUT "#undef OPENSSL_EXPORT_VAR_AS_FUNCTION\n"
 			if $export_var_as_fn;
 		  printf OUT "#%s OPENSSL_EXPORT_VAR_AS_FUNCTION\n",
 			($export_var_as_fn)?"define":"undef"; }
 	elsif	(/^#define\s+OPENSSL_UNISTD/)
 		{
 		$unistd = "<unistd.h>" if $unistd eq "";
 		print OUT "#define OPENSSL_UNISTD $unistd\n";
 		}
 	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT_LONG/)
 		{ printf OUT "#%s SIXTY_FOUR_BIT_LONG\n",($b64l)?"define":"undef"; }
 	elsif	(/^#((define)|(undef))\s+SIXTY_FOUR_BIT/)
 		{ printf OUT "#%s SIXTY_FOUR_BIT\n",($b64)?"define":"undef"; }
 	elsif	(/^#((define)|(undef))\s+THIRTY_TWO_BIT/)
 		{ printf OUT "#%s THIRTY_TWO_BIT\n",($b32)?"define":"undef"; }
 	elsif	(/^#((define)|(undef))\s+SIXTEEN_BIT/)
 		{ printf OUT "#%s SIXTEEN_BIT\n",($b16)?"define":"undef"; }
 	elsif	(/^#((define)|(undef))\s+EIGHT_BIT/)
 		{ printf OUT "#%s EIGHT_BIT\n",($b8)?"define":"undef"; }
 	elsif	(/^#((define)|(undef))\s+BN_LLONG\s*$/)
 		{ printf OUT "#%s BN_LLONG\n",($bn_ll)?"define":"undef"; }
 	elsif	(/^\#define\s+DES_LONG\s+.*/)
 		{ printf OUT "#define DES_LONG unsigned %s\n",
 			($des_int)?'int':'long'; }
 	elsif	(/^\#(define|undef)\s+DES_PTR/)
 		{ printf OUT "#%s DES_PTR\n",($des_ptr)?'define':'undef'; }
 	elsif	(/^\#(define|undef)\s+DES_RISC1/)
 		{ printf OUT "#%s DES_RISC1\n",($des_risc1)?'define':'undef'; }
 	elsif	(/^\#(define|undef)\s+DES_RISC2/)
 		{ printf OUT "#%s DES_RISC2\n",($des_risc2)?'define':'undef'; }
 	elsif	(/^\#(define|undef)\s+DES_UNROLL/)
 		{ printf OUT "#%s DES_UNROLL\n",($des_unroll)?'define':'undef'; }
 	elsif	(/^#define\s+RC4_INT\s/)
 		{ printf OUT "#define RC4_INT unsigned %s\n",$type[$rc4_int]; }
 	elsif	(/^#undef\s+RC4_CHUNK/)
 		{
 		printf OUT "#undef RC4_CHUNK\n" if $rc4_chunk==0;
 		printf OUT "#define RC4_CHUNK unsigned long\n" if $rc4_chunk==1;
 		printf OUT "#define RC4_CHUNK unsigned long long\n" if $rc4_chunk==2;
 		}
 	elsif	(/^#((define)|(undef))\s+RC4_INDEX/)
 		{ printf OUT "#%s RC4_INDEX\n",($rc4_idx)?"define":"undef"; }
 	elsif (/^#(define|undef)\s+I386_ONLY/)
 		{ printf OUT "#%s I386_ONLY\n", ($processor eq "386")?
 			"define":"undef"; }
 	elsif	(/^#define\s+MD2_INT\s/)
 		{ printf OUT "#define MD2_INT unsigned %s\n",$type[$md2_int]; }
 	elsif	(/^#define\s+IDEA_INT\s/)
 		{printf OUT "#define IDEA_INT unsigned %s\n",$type[$idea_int];}
 	elsif	(/^#define\s+RC2_INT\s/)
 		{printf OUT "#define RC2_INT unsigned %s\n",$type[$rc2_int];}
 	elsif (/^#(define|undef)\s+BF_PTR/)
 		{
 		printf OUT "#undef BF_PTR\n" if $bf_ptr == 0;
 		printf OUT "#define BF_PTR\n" if $bf_ptr == 1;
 		printf OUT "#define BF_PTR2\n" if $bf_ptr == 2;
 	        }
 	else
 		{ print OUT $_; }
 	}
 close(IN);
 print OUT "#ifdef  __cplusplus\n";
 print OUT "}\n";
 print OUT "#endif\n";
 close(OUT);
 rename("crypto/opensslconf.h","crypto/opensslconf.h.bak") || die "unable to rename crypto/opensslconf.h\n" if -e "crypto/opensslconf.h";
 rename("crypto/opensslconf.h.new","crypto/opensslconf.h") || die "unable to rename crypto/opensslconf.h.new\n";
 
 
 # Fix the date
 
 print "SIXTY_FOUR_BIT_LONG mode\n" if $b64l;
 print "SIXTY_FOUR_BIT mode\n" if $b64;
 print "THIRTY_TWO_BIT mode\n" if $b32;
 print "SIXTEEN_BIT mode\n" if $b16;
 print "EIGHT_BIT mode\n" if $b8;
 print "DES_PTR used\n" if $des_ptr;
 print "DES_RISC1 used\n" if $des_risc1;
 print "DES_RISC2 used\n" if $des_risc2;
 print "DES_UNROLL used\n" if $des_unroll;
 print "DES_INT used\n" if $des_int;
 print "BN_LLONG mode\n" if $bn_ll;
 print "RC4 uses u$type[$rc4_int]\n" if $rc4_int != $def_int;
 print "RC4_INDEX mode\n" if $rc4_idx;
 print "RC4_CHUNK is undefined\n" if $rc4_chunk==0;
 print "RC4_CHUNK is unsigned long\n" if $rc4_chunk==1;
 print "RC4_CHUNK is unsigned long long\n" if $rc4_chunk==2;
 print "MD2 uses u$type[$md2_int]\n" if $md2_int != $def_int;
 print "IDEA uses u$type[$idea_int]\n" if $idea_int != $def_int;
 print "RC2 uses u$type[$rc2_int]\n" if $rc2_int != $def_int;
 print "BF_PTR used\n" if $bf_ptr == 1; 
 print "BF_PTR2 used\n" if $bf_ptr == 2; 
 
 if($IsMK1MF) {
 	open (OUT,">crypto/buildinf.h") || die "Can't open buildinf.h";
 	printf OUT <<EOF;
 #ifndef MK1MF_BUILD
   /* auto-generated by Configure for crypto/cversion.c:
    * for Unix builds, crypto/Makefile.ssl generates functional definitions;
    * Windows builds (and other mk1mf builds) compile cversion.c with
    * -DMK1MF_BUILD and use definitions added to this file by util/mk1mf.pl. */
   #error "Windows builds (PLATFORM=$target) use mk1mf.pl-created Makefiles"
 #endif
 EOF
 	close(OUT);
 } else {
 	my $make_command = "$make PERL=\'$perl\'";
 	my $make_targets = "";
 	$make_targets .= " links" if $symlink;
 	$make_targets .= " depend" if $depflags ne $default_depflags && $make_depend;
 	$make_targets .= " gentests" if $symlink;
 	(system $make_command.$make_targets) == 0 or exit $?
 		if $make_targets ne "";
 	if ( $perl =~ m@^/@) {
 	    &dofile("tools/c_rehash",$perl,'^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";', '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
 	    &dofile("apps/CA.pl",$perl,'^#!/', '#!%s');
 	} else {
 	    # No path for Perl known ...
 	    &dofile("tools/c_rehash",'/usr/local/bin/perl','^#!/', '#!%s','^my \$dir;$', 'my $dir = "' . $openssldir . '";',  '^my \$prefix;$', 'my $prefix = "' . $prefix . '";');
 	    &dofile("apps/CA.pl",'/usr/local/bin/perl','^#!/', '#!%s');
 	}
 	if ($depflags ne $default_depflags && !$make_depend) {
             $warn_make_depend++;
         }
 }
 
 # create the ms/version32.rc file if needed
 if ($IsMK1MF && ($target !~ /^netware/)) {
 	my ($v1, $v2, $v3, $v4);
 	if ($version_num =~ /(^[0-9a-f]{1})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/i) {
 		$v1=hex $1;
 		$v2=hex $2;
 		$v3=hex $3;
 		$v4=hex $4;
 	}
 	open (OUT,">ms/version32.rc") || die "Can't open ms/version32.rc";
 	print OUT <<EOF;
 #include <winver.h>
 
 LANGUAGE 0x09,0x01
 
 1 VERSIONINFO
   FILEVERSION $v1,$v2,$v3,$v4
   PRODUCTVERSION $v1,$v2,$v3,$v4
   FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
   FILEFLAGS 0x01L
 #else
   FILEFLAGS 0x00L
 #endif
   FILEOS VOS__WINDOWS32
   FILETYPE VFT_DLL
   FILESUBTYPE 0x0L
 BEGIN
     BLOCK "StringFileInfo"
     BEGIN
 	BLOCK "040904b0"
 	BEGIN
 	    // Required:	    
 	    VALUE "CompanyName", "The OpenSSL Project, http://www.openssl.org/\\0"
 	    VALUE "FileDescription", "OpenSSL Shared Library\\0"
 	    VALUE "FileVersion", "$version\\0"
 #if defined(CRYPTO)
 	    VALUE "InternalName", "libeay32\\0"
 	    VALUE "OriginalFilename", "libeay32.dll\\0"
 #elif defined(SSL)
 	    VALUE "InternalName", "ssleay32\\0"
 	    VALUE "OriginalFilename", "ssleay32.dll\\0"
 #endif
 	    VALUE "ProductName", "The OpenSSL Toolkit\\0"
 	    VALUE "ProductVersion", "$version\\0"
 	    // Optional:
 	    //VALUE "Comments", "\\0"
 	    VALUE "LegalCopyright", "Copyright � 1998-2005 The OpenSSL Project. Copyright � 1995-1998 Eric A. Young, Tim J. Hudson. All rights reserved.\\0"
 	    //VALUE "LegalTrademarks", "\\0"
 	    //VALUE "PrivateBuild", "\\0"
 	    //VALUE "SpecialBuild", "\\0"
 	END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 0x4b0
     END
 END
 EOF
 	close(OUT);
   }
   
 print <<EOF;
 
 Configured for $target.
 EOF
 
 print <<\EOF if (!$no_threads && !$threads);
 
 The library could not be configured for supporting multi-threaded
 applications as the compiler options required on this system are not known.
 See file INSTALL for details if you need multi-threading.
 EOF
 
 print <<\EOF if ($no_shared_warn);
 
 You gave the option 'shared', which is not supported on this platform, so
 we will pretend you gave the option 'no-shared'.  If you know how to implement
 shared libraries, please let us know (but please first make sure you have
 tried with a current version of OpenSSL).
 EOF
 
 print <<EOF if ($warn_make_depend);
 
 *** Because of configuration changes, you MUST do the following before
 *** building:
 
 	make depend
 EOF
 
 exit(0);
 
 sub usage
 	{
 	print STDERR $usage;
 	print STDERR "\npick os/compiler from:\n";
 	my $j=0;
 	my $i;
         my $k=0;
 	foreach $i (sort keys %table)
 		{
 		next if $i =~ /^debug/;
 		$k += length($i) + 1;
 		if ($k > 78)
 			{
 			print STDERR "\n";
 			$k=length($i);
 			}
 		print STDERR $i . " ";
 		}
 	foreach $i (sort keys %table)
 		{
 		next if $i !~ /^debug/;
 		$k += length($i) + 1;
 		if ($k > 78)
 			{
 			print STDERR "\n";
 			$k=length($i);
 			}
 		print STDERR $i . " ";
 		}
 	print STDERR "\n\nNOTE: If in doubt, on Unix-ish systems use './config'.\n";
 	exit(1);
 	}
 
 sub which
 	{
 	my($name)=@_;
 	my $path;
 	foreach $path (split /:/, $ENV{PATH})
 		{
 		if (-f "$path/$name$exe_ext" and -x _)
 			{
 			return "$path/$name$exe_ext" unless ($name eq "perl" and
 			 system("$path/$name$exe_ext -e " . '\'exit($]<5.0);\''));
 			}
 		}
 	}
 
 sub dofile
 	{
 	my $f; my $p; my %m; my @a; my $k; my $ff;
 	($f,$p,%m)=@_;
 
 	open(IN,"<$f.in") || open(IN,"<$f") || die "unable to open $f:$!\n";
 	@a=<IN>;
 	close(IN);
 	foreach $k (keys %m)
 		{
 		grep(/$k/ && ($_=sprintf($m{$k}."\n",$p)),@a);
 		}
 	open(OUT,">$f.new") || die "unable to open $f.new:$!\n";
 	print OUT @a;
 	close(OUT);
 	rename($f,"$f.bak") || die "unable to rename $f\n" if -e $f;
 	rename("$f.new",$f) || die "unable to rename $f.new\n";
 	}
 
 sub print_table_entry
 	{
 	my $target = shift;
 
 	(my $cc,my $cflags,my $unistd,my $thread_cflag,my $sys_id,my $lflags,
 	my $bn_ops,my $cpuid_obj,my $bn_obj,my $des_obj,my $aes_obj, my $bf_obj,
 	my $md5_obj,my $sha1_obj,my $cast_obj,my $rc4_obj,my $rmd160_obj,
 	my $rc5_obj,my $wp_obj,my $cmll_obj,my $modes_obj, my $engines_obj,
 	my $perlasm_scheme,my $dso_scheme,my $shared_target,my $shared_cflag,
 	my $shared_ldflag,my $shared_extension,my $ranlib,my $arflags,my $multilib)=
 	split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
 			
 	print <<EOF
 
 *** $target
 \$cc           = $cc
 \$cflags       = $cflags
 \$unistd       = $unistd
 \$thread_cflag = $thread_cflag
 \$sys_id       = $sys_id
 \$lflags       = $lflags
 \$bn_ops       = $bn_ops
 \$cpuid_obj    = $cpuid_obj
 \$bn_obj       = $bn_obj
 \$des_obj      = $des_obj
 \$aes_obj      = $aes_obj
 \$bf_obj       = $bf_obj
 \$md5_obj      = $md5_obj
 \$sha1_obj     = $sha1_obj
 \$cast_obj     = $cast_obj
 \$rc4_obj      = $rc4_obj
 \$rmd160_obj   = $rmd160_obj
 \$rc5_obj      = $rc5_obj
 \$wp_obj       = $wp_obj
 \$cmll_obj     = $cmll_obj
 \$modes_obj    = $modes_obj
 \$engines_obj  = $engines_obj
 \$perlasm_scheme = $perlasm_scheme
 \$dso_scheme   = $dso_scheme
 \$shared_target= $shared_target
 \$shared_cflag = $shared_cflag
 \$shared_ldflag = $shared_ldflag
 \$shared_extension = $shared_extension
 \$ranlib       = $ranlib
 \$arflags      = $arflags
 \$multilib     = $multilib
 EOF
 	}
 
 sub test_sanity
 	{
 	my $errorcnt = 0;
 
 	print STDERR "=" x 70, "\n";
 	print STDERR "=== SANITY TESTING!\n";
 	print STDERR "=== No configuration will be done, all other arguments will be ignored!\n";
 	print STDERR "=" x 70, "\n";
 
 	foreach $target (sort keys %table)
 		{
 		@fields = split(/\s*:\s*/,$table{$target} . ":" x 30 , -1);
 
 		if ($fields[$idx_dso_scheme-1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
 			{
 			$errorcnt++;
 			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
 			print STDERR "              in the previous field\n";
 			}
 		elsif ($fields[$idx_dso_scheme+1] =~ /^(beos|dl|dlfcn|win32|vms)$/)
 			{
 			$errorcnt++;
 			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] values\n";
 			print STDERR "              in the following field\n";
 			}
 		elsif ($fields[$idx_dso_scheme] !~ /^(beos|dl|dlfcn|win32|vms|)$/)
 			{
 			$errorcnt++;
 			print STDERR "SANITY ERROR: '$target' has the dso_scheme [$idx_dso_scheme] field = ",$fields[$idx_dso_scheme],"\n";
 			print STDERR "              valid values are 'beos', 'dl', 'dlfcn', 'win32' and 'vms'\n";
 			}
 		}
 	print STDERR "No sanity errors detected!\n" if $errorcnt == 0;
 	return $errorcnt;
 	}
Index: vendor-crypto/openssl/dist-1.0.1/FREEBSD-upgrade
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/FREEBSD-upgrade	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/FREEBSD-upgrade	(revision 306191)
@@ -1,83 +1,83 @@
 
 This contains various notes used to import a new OpenSSL version into
 the FreeBSD base system.  It is not expected to be complete but just to
 contain some hints for imports.  Note that this doesn't actually deal
 with getting OpenSSL to compile...
 
 XXX This file currently partly contain CVS and SVN instructions.
 
 First, read http://wiki.freebsd.org/SubversionPrimer/VendorImports
 
 # Xlist
 setenv XLIST /FreeBSD/work/openssl/svn-FREEBSD-files/FREEBSD-Xlist
 setenv FSVN "svn+ssh://svn.freebsd.org/base"
-setenv OSSLVER 1.0.1t
-# OSSLTAG format: v1_0_1t
+setenv OSSLVER 1.0.1u
+# OSSLTAG format: v1_0_1u
 
 ###setenv OSSLTAG v`echo ${OSSLVER} | tr . _`
 
 cd /FreeBSD/work/openssl/merge
 fetch http://www.openssl.org/source/openssl-${OSSLVER}.tar.gz \
     http://www.openssl.org/source/openssl-${OSSLVER}.tar.gz.asc
 gpg --verify openssl-${OSSLVER}.tar.gz.asc openssl-${OSSLVER}.tar.gz
 
 svn co $FSVN/vendor-crypto/openssl/dist-1.0.1 dist-1.0.1
 tar -x -X $XLIST -f openssl-${OSSLVER}.tar.gz
 
 cd dist-1.0.1
 svn list -R | egrep -v -e '/$' -e '^FREEBSD-(Xlist|upgrade)$' | sort >../old
 cd ../openssl-${OSSLVER}
 find . -type f -or -type l | cut -c 3- | sort >../new
 cd ..
 
 # See that files to remove makes sense
 comm -23 old new
 # See that files to add makes sense
 comm -13 old new
 
 tar -cf - -C openssl-${OSSLVER} . | tar -xf - -C dist-1.0.1
 cd dist-1.0.1
 comm -23 ../old ../new | xargs svn rm
 # Make sure to remove empty directories
 comm -13 ../old ../new | xargs svn --parents add
 
 svn stat
 svn ci
 svn cp ^/vendor-crypto/openssl/dist-1.0.1 ^/vendor-crypto/openssl/$OSSLVER
 
 # Merge to head
 mkdir ../head
 cd ../head
 svn co $FSVN/head/crypto/openssl crypto/openssl
 svn merge ^/vendor-crypto/openssl/dist-1.0.1 crypto/openssl
 
 # Resolve conflicts manually
 
 svn co $FSVN/head/secure/lib/libcrypto secure/lib/libcrypto
 svn co $FSVN/head/secure/lib/libssl secure/lib/libssl
 svn co $FSVN/head/secure/usr.bin/openssl secure/usr.bin/openssl
 
 cd secure/lib/libcrypto
 
 # Update version number and release date in Makefile.inc
 # Update all opensslconf-${MACHINE_CPUARCH}.h
 
 # Regen assembly files if necessary
 make -f Makefile.asm all
 mv *.[Ss] ${MACHINE_CPUARCH}
 make -f Makefile.asm clean
 
 # Regen manual pages
 make man-makefile-update && make man-update
 cd ../libssl
 make man-makefile-update && make man-update
 cd ../../usr.bin/openssl
 make man-makefile-update && make man-update
 cd ../../..
 
 # Commit!
 svn ci crypto/openssl secure/lib/libcrypto secure/lib/libssl secure/usr.bin/openssl
 
 					-- simon@, jkim@
 
 $FreeBSD$
Index: vendor-crypto/openssl/dist-1.0.1/Makefile
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/Makefile	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/Makefile	(revision 306191)
@@ -1,676 +1,676 @@
 ### Generated automatically from Makefile.org by Configure.
 
 ##
 ## Makefile for OpenSSL
 ##
 
-VERSION=1.0.1t
+VERSION=1.0.1u
 MAJOR=1
 MINOR=0.1
 SHLIB_VERSION_NUMBER=1.0.0
 SHLIB_VERSION_HISTORY=
 SHLIB_MAJOR=1
 SHLIB_MINOR=0.0
 SHLIB_EXT=
 PLATFORM=dist
 OPTIONS= no-ec_nistp_64_gcc_128 no-gmp no-jpake no-krb5 no-md2 no-rc5 no-rfc3779 no-sctp no-shared no-ssl2 no-store no-unit-test no-weak-ssl-ciphers no-zlib no-zlib-dynamic static-engine
 CONFIGURE_ARGS=dist
 SHLIB_TARGET=
 
 # HERE indicates where this Makefile lives.  This can be used to indicate
 # where sub-Makefiles are expected to be.  Currently has very limited usage,
 # and should probably not be bothered with at all.
 HERE=.
 
 # INSTALL_PREFIX is for package builders so that they can configure
 # for, say, /usr/ and yet have everything installed to /tmp/somedir/usr/.
 # Normally it is left empty.
 INSTALL_PREFIX=
 INSTALLTOP=/usr/local/ssl
 
 # Do not edit this manually. Use Configure --openssldir=DIR do change this!
 OPENSSLDIR=/usr/local/ssl
 
 # NO_IDEA - Define to build without the IDEA algorithm
 # NO_RC4  - Define to build without the RC4 algorithm
 # NO_RC2  - Define to build without the RC2 algorithm
 # THREADS - Define when building with threads, you will probably also need any
 #           system defines as well, i.e. _REENTERANT for Solaris 2.[34]
 # TERMIO  - Define the termio terminal subsystem, needed if sgtty is missing.
 # TERMIOS - Define the termios terminal subsystem, Silicon Graphics.
 # LONGCRYPT - Define to use HPUX 10.x's long password modification to crypt(3).
 # DEVRANDOM - Give this the value of the 'random device' if your OS supports
 #           one.  32 bytes will be read from this when the random
 #           number generator is initalised.
 # SSL_FORBID_ENULL - define if you want the server to be not able to use the
 #           NULL encryption ciphers.
 #
 # LOCK_DEBUG - turns on lots of lock debug output :-)
 # REF_CHECK - turn on some xyz_free() assertions.
 # REF_PRINT - prints some stuff on structure free.
 # CRYPTO_MDEBUG - turns on my 'memory leak' detecting stuff
 # MFUNC - Make all Malloc/Free/Realloc calls call
 #       CRYPTO_malloc/CRYPTO_free/CRYPTO_realloc which can be setup to
 #       call application defined callbacks via CRYPTO_set_mem_functions()
 # MD5_ASM needs to be defined to use the x86 assembler for MD5
 # SHA1_ASM needs to be defined to use the x86 assembler for SHA1
 # RMD160_ASM needs to be defined to use the x86 assembler for RIPEMD160
 # Do not define B_ENDIAN or L_ENDIAN if 'unsigned long' == 8.  It must
 # equal 4.
 # PKCS1_CHECK - pkcs1 tests.
 
 CC= cc
 CFLAG= -O
 DEPFLAG= -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_GMP -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SCTP -DOPENSSL_NO_SSL2 -DOPENSSL_NO_STORE -DOPENSSL_NO_UNIT_TEST -DOPENSSL_NO_WEAK_SSL_CIPHERS
 PEX_LIBS= 
 EX_LIBS= 
 EXE_EXT= 
 ARFLAGS= 
 AR= ar $(ARFLAGS) r
 RANLIB= /usr/bin/ranlib
 NM= nm
 PERL= /usr/bin/perl
 TAR= tar
 TARFLAGS= --no-recursion --record-size=10240
 MAKEDEPPROG=makedepend
 LIBDIR=lib
 
 # We let the C compiler driver to take care of .s files. This is done in
 # order to be excused from maintaining a separate set of architecture
 # dependent assembler flags. E.g. if you throw -mcpu=ultrasparc at SPARC
 # gcc, then the driver will automatically translate it to -xarch=v8plus
 # and pass it down to assembler.
 AS=$(CC) -c
 ASFLAG=$(CFLAG)
 
 # For x86 assembler: Set PROCESSOR to 386 if you want to support
 # the 80386.
 PROCESSOR= 
 
 # CPUID module collects small commonly used assembler snippets
 CPUID_OBJ= mem_clr.o
 BN_ASM= bn_asm.o
 DES_ENC= des_enc.o fcrypt_b.o
 AES_ENC= aes_core.o aes_cbc.o
 BF_ENC= bf_enc.o
 CAST_ENC= c_enc.o
 RC4_ENC= rc4_enc.o rc4_skey.o
 RC5_ENC= rc5_enc.o
 MD5_ASM_OBJ= 
 SHA1_ASM_OBJ= 
 RMD160_ASM_OBJ= 
 WP_ASM_OBJ= wp_block.o
 CMLL_ENC= camellia.o cmll_misc.o cmll_cbc.o
 MODES_ASM_OBJ= 
 ENGINES_ASM_OBJ= 
 PERLASM_SCHEME= 
 
 # KRB5 stuff
 KRB5_INCLUDES=
 LIBKRB5=
 
 # Zlib stuff
 ZLIB_INCLUDE=
 LIBZLIB=
 
 # TOP level FIPS install directory.
 FIPSDIR=/usr/local/ssl/fips-2.0
 
 # This is the location of fipscanister.o and friends.
 # The FIPS module build will place it $(INSTALLTOP)/lib
 # but since $(INSTALLTOP) can only take the default value
 # when the module is built it will be in /usr/local/ssl/lib
 # $(INSTALLTOP) for this build may be different so hard
 # code the path.
 
 FIPSLIBDIR=
 
 # The location of the library which contains fipscanister.o
 # normally it will be libcrypto unless fipsdso is set in which
 # case it will be libfips. If not compiling in FIPS mode at all
 # this is empty making it a useful test for a FIPS compile.
 
 FIPSCANLIB=
 
 # Shared library base address. Currently only used on Windows.
 #
 
 BASEADDR=0xFB00000
 
 DIRS=   crypto ssl engines apps test tools
 ENGDIRS= ccgost
 SHLIBDIRS= crypto ssl
 
 # dirs in crypto to build
 SDIRS=  \
 	objects \
 	md4 md5 sha mdc2 hmac ripemd whrlpool \
 	des aes rc2 rc4 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 \
 	cms pqueue ts srp cmac
 # keep in mind that the above list is adjusted by ./Configure
 # according to no-xxx arguments...
 
 # tests to perform.  "alltests" is a special word indicating that all tests
 # should be performed.
 TESTS = alltests
 
 MAKEFILE= Makefile
 
 MANDIR=$(OPENSSLDIR)/man
 MAN1=1
 MAN3=3
 MANSUFFIX=
 HTMLSUFFIX=html
 HTMLDIR=$(OPENSSLDIR)/html
 SHELL=/bin/sh
 
 TOP=    .
 ONEDIRS=out tmp
 EDIRS=  times doc bugs util include certs ms shlib mt demos perl sf dep VMS
 WDIRS=  windows
 LIBS=   libcrypto.a libssl.a
 SHARED_CRYPTO=libcrypto$(SHLIB_EXT)
 SHARED_SSL=libssl$(SHLIB_EXT)
 SHARED_LIBS=
 SHARED_LIBS_LINK_EXTS=
 SHARED_LDFLAGS=
 
 GENERAL=        Makefile
 BASENAME=       openssl
 NAME=           $(BASENAME)-$(VERSION)
 TARFILE=        ../$(NAME).tar
 EXHEADER=       e_os2.h
 HEADER=         e_os.h
 
 all: Makefile build_all
 
 # as we stick to -e, CLEARENV ensures that local variables in lower
 # Makefiles remain local and variable. $${VAR+VAR} is tribute to Korn
 # shell, which [annoyingly enough] terminates unset with error if VAR
 # is not present:-( TOP= && unset TOP is tribute to HP-UX /bin/sh,
 # which terminates unset with error if no variable was present:-(
 CLEARENV=	TOP= && unset TOP $${LIB+LIB} $${LIBS+LIBS}	\
 		$${INCLUDE+INCLUDE} $${INCLUDES+INCLUDES}	\
 		$${DIR+DIR} $${DIRS+DIRS} $${SRC+SRC}		\
 		$${LIBSRC+LIBSRC} $${LIBOBJ+LIBOBJ} $${ALL+ALL}	\
 		$${EXHEADER+EXHEADER} $${HEADER+HEADER}		\
 		$${GENERAL+GENERAL} $${CFLAGS+CFLAGS}		\
 		$${ASFLAGS+ASFLAGS} $${AFLAGS+AFLAGS}		\
 		$${LDCMD+LDCMD} $${LDFLAGS+LDFLAGS} $${SCRIPTS+SCRIPTS}	\
 		$${SHAREDCMD+SHAREDCMD} $${SHAREDFLAGS+SHAREDFLAGS}	\
 		$${SHARED_LIB+SHARED_LIB} $${LIBEXTRAS+LIBEXTRAS}
 
 BUILDENV=	PLATFORM='$(PLATFORM)' PROCESSOR='$(PROCESSOR)' \
 		CC='$(CC)' CFLAG='$(CFLAG)' 			\
 		AS='$(CC)' ASFLAG='$(CFLAG) -c'			\
 		AR='$(AR)' NM='$(NM)' RANLIB='$(RANLIB)'	\
 		CROSS_COMPILE='$(CROSS_COMPILE)'	\
 		PERL='$(PERL)' ENGDIRS='$(ENGDIRS)'		\
 		SDIRS='$(SDIRS)' LIBRPATH='$(INSTALLTOP)/$(LIBDIR)'	\
 		INSTALL_PREFIX='$(INSTALL_PREFIX)'		\
 		INSTALLTOP='$(INSTALLTOP)' OPENSSLDIR='$(OPENSSLDIR)'	\
 		LIBDIR='$(LIBDIR)'				\
 		MAKEDEPEND='$$$${TOP}/util/domd $$$${TOP} -MD $(MAKEDEPPROG)' \
 		DEPFLAG='-DOPENSSL_NO_DEPRECATED $(DEPFLAG)'	\
 		MAKEDEPPROG='$(MAKEDEPPROG)'			\
 		SHARED_LDFLAGS='$(SHARED_LDFLAGS)'		\
 		KRB5_INCLUDES='$(KRB5_INCLUDES)' LIBKRB5='$(LIBKRB5)'	\
 		ZLIB_INCLUDE='$(ZLIB_INCLUDE)' LIBZLIB='$(LIBZLIB)'	\
 		EXE_EXT='$(EXE_EXT)' SHARED_LIBS='$(SHARED_LIBS)'	\
 		SHLIB_EXT='$(SHLIB_EXT)' SHLIB_TARGET='$(SHLIB_TARGET)'	\
 		PEX_LIBS='$(PEX_LIBS)' EX_LIBS='$(EX_LIBS)'	\
 		CPUID_OBJ='$(CPUID_OBJ)'			\
 		BN_ASM='$(BN_ASM)' DES_ENC='$(DES_ENC)' 	\
 		AES_ENC='$(AES_ENC)' CMLL_ENC='$(CMLL_ENC)'	\
 		BF_ENC='$(BF_ENC)' CAST_ENC='$(CAST_ENC)'	\
 		RC4_ENC='$(RC4_ENC)' RC5_ENC='$(RC5_ENC)'	\
 		SHA1_ASM_OBJ='$(SHA1_ASM_OBJ)'			\
 		MD5_ASM_OBJ='$(MD5_ASM_OBJ)'			\
 		RMD160_ASM_OBJ='$(RMD160_ASM_OBJ)'		\
 		WP_ASM_OBJ='$(WP_ASM_OBJ)'			\
 		MODES_ASM_OBJ='$(MODES_ASM_OBJ)'		\
 		ENGINES_ASM_OBJ='$(ENGINES_ASM_OBJ)'		\
 		PERLASM_SCHEME='$(PERLASM_SCHEME)'		\
 		FIPSLIBDIR='${FIPSLIBDIR}'			\
 		FIPSDIR='${FIPSDIR}'				\
 		FIPSCANLIB="$${FIPSCANLIB:-$(FIPSCANLIB)}"	\
 		THIS=$${THIS:-$@} MAKEFILE=Makefile MAKEOVERRIDES=
 # MAKEOVERRIDES= effectively "equalizes" GNU-ish and SysV-ish make flavors,
 # which in turn eliminates ambiguities in variable treatment with -e.
 
 # BUILD_CMD is a generic macro to build a given target in a given
 # subdirectory.  The target must be given through the shell variable
 # `target' and the subdirectory to build in must be given through `dir'.
 # This macro shouldn't be used directly, use RECURSIVE_BUILD_CMD or
 # BUILD_ONE_CMD instead.
 #
 # BUILD_ONE_CMD is a macro to build a given target in a given
 # subdirectory if that subdirectory is part of $(DIRS).  It requires
 # exactly the same shell variables as BUILD_CMD.
 #
 # RECURSIVE_BUILD_CMD is a macro to build a given target in all
 # subdirectories defined in $(DIRS).  It requires that the target
 # is given through the shell variable `target'.
 BUILD_CMD=  if [ -d "$$dir" ]; then \
 	    (	cd $$dir && echo "making $$target in $$dir..." && \
 		$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. DIR=$$dir $$target \
 	    ) || exit 1; \
 	    fi
 RECURSIVE_BUILD_CMD=for dir in $(DIRS); do $(BUILD_CMD); done
 BUILD_ONE_CMD=\
 	if expr " $(DIRS) " : ".* $$dir " >/dev/null 2>&1; then \
 		$(BUILD_CMD); \
 	fi
 
 reflect:
 	@[ -n "$(THIS)" ] && $(CLEARENV) && $(MAKE) $(THIS) -e $(BUILDENV)
 
 sub_all: build_all
 
 build_all: build_libs build_apps build_tests build_tools
 
 build_libs: build_libcrypto build_libssl openssl.pc
 
 build_libcrypto: build_crypto build_engines libcrypto.pc
 build_libssl: build_ssl libssl.pc
 
 build_crypto:
 	@dir=crypto; target=all; $(BUILD_ONE_CMD)
 build_ssl: build_crypto
 	@dir=ssl; target=all; $(BUILD_ONE_CMD)
 build_engines: build_crypto
 	@dir=engines; target=all; $(BUILD_ONE_CMD)
 build_apps: build_libs
 	@dir=apps; target=all; $(BUILD_ONE_CMD)
 build_tests: build_libs
 	@dir=test; target=all; $(BUILD_ONE_CMD)
 build_tools: build_libs
 	@dir=tools; target=all; $(BUILD_ONE_CMD)
 
 all_testapps: build_libs build_testapps
 build_testapps:
 	@dir=crypto; target=testapps; $(BUILD_ONE_CMD)
 
 fips_premain_dso$(EXE_EXT): libcrypto.a
 	[ -z "$(FIPSCANLIB)" ] || $(CC) $(CFLAG) -Iinclude \
 		-DFINGERPRINT_PREMAIN_DSO_LOAD -o $@  \
 		$(FIPSLIBDIR)fips_premain.c $(FIPSLIBDIR)fipscanister.o \
 		libcrypto.a $(EX_LIBS)
 
 libcrypto$(SHLIB_EXT): libcrypto.a fips_premain_dso$(EXE_EXT)
 	@if [ "$(SHLIB_TARGET)" != "" ]; then \
 		if [ "$(FIPSCANLIB)" = "libcrypto" ]; then \
 			FIPSLD_LIBCRYPTO=libcrypto.a ; \
 			FIPSLD_CC="$(CC)"; CC=$(FIPSDIR)/bin/fipsld; \
 			export CC FIPSLD_CC FIPSLD_LIBCRYPTO; \
 		fi; \
 		$(MAKE) -e SHLIBDIRS=crypto  CC="$${CC:-$(CC)}" build-shared && \
 		(touch -c fips_premain_dso$(EXE_EXT) || :); \
 	else \
 		echo "There's no support for shared libraries on this platform" >&2; \
 		exit 1; \
 	fi
 
 libssl$(SHLIB_EXT): libcrypto$(SHLIB_EXT) libssl.a
 	@if [ "$(SHLIB_TARGET)" != "" ]; then \
 		$(MAKE) SHLIBDIRS=ssl SHLIBDEPS='-lcrypto' build-shared; \
 	else \
 		echo "There's no support for shared libraries on this platform" >&2; \
 		exit 1; \
 	fi
 
 clean-shared:
 	@set -e; for i in $(SHLIBDIRS); do \
 		if [ -n "$(SHARED_LIBS_LINK_EXTS)" ]; then \
 			tmp="$(SHARED_LIBS_LINK_EXTS)"; \
 			for j in $${tmp:-x}; do \
 				( set -x; rm -f lib$$i$$j ); \
 			done; \
 		fi; \
 		( set -x; rm -f lib$$i$(SHLIB_EXT) ); \
 		if [ "$(PLATFORM)" = "Cygwin" ]; then \
 			( set -x; rm -f cyg$$i$(SHLIB_EXT) lib$$i$(SHLIB_EXT).a ); \
 		fi; \
 	done
 
 link-shared:
 	@ set -e; for i in $(SHLIBDIRS); do \
 		$(MAKE) -f $(HERE)/Makefile.shared -e $(BUILDENV) \
 			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
 			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
 			symlink.$(SHLIB_TARGET); \
 		libs="$$libs -l$$i"; \
 	done
 
 build-shared: do_$(SHLIB_TARGET) link-shared
 
 do_$(SHLIB_TARGET):
 	@ set -e; libs='-L. $(SHLIBDEPS)'; for i in $(SHLIBDIRS); do \
 		if [ "$$i" = "ssl" -a -n "$(LIBKRB5)" ]; then \
 			libs="$(LIBKRB5) $$libs"; \
 		fi; \
 		$(CLEARENV) && $(MAKE) -f Makefile.shared -e $(BUILDENV) \
 			LIBNAME=$$i LIBVERSION=$(SHLIB_MAJOR).$(SHLIB_MINOR) \
 			LIBCOMPATVERSIONS=";$(SHLIB_VERSION_HISTORY)" \
 			LIBDEPS="$$libs $(EX_LIBS)" \
 			link_a.$(SHLIB_TARGET); \
 		libs="-l$$i $$libs"; \
 	done
 
 libcrypto.pc: Makefile
 	@ ( echo 'prefix=$(INSTALLTOP)'; \
 	    echo 'exec_prefix=$${prefix}'; \
 	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
 	    echo 'includedir=$${prefix}/include'; \
 	    echo ''; \
 	    echo 'Name: OpenSSL-libcrypto'; \
 	    echo 'Description: OpenSSL cryptography library'; \
 	    echo 'Version: '$(VERSION); \
 	    echo 'Requires: '; \
 	    echo 'Libs: -L$${libdir} -lcrypto'; \
 	    echo 'Libs.private: $(EX_LIBS)'; \
 	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libcrypto.pc
 
 libssl.pc: Makefile
 	@ ( echo 'prefix=$(INSTALLTOP)'; \
 	    echo 'exec_prefix=$${prefix}'; \
 	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
 	    echo 'includedir=$${prefix}/include'; \
 	    echo ''; \
 	    echo 'Name: OpenSSL'; \
 	    echo 'Description: Secure Sockets Layer and cryptography libraries'; \
 	    echo 'Version: '$(VERSION); \
 	    echo 'Requires: '; \
 	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
 	    echo 'Libs.private: $(EX_LIBS)'; \
 	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > libssl.pc
 
 openssl.pc: Makefile
 	@ ( echo 'prefix=$(INSTALLTOP)'; \
 	    echo 'exec_prefix=$${prefix}'; \
 	    echo 'libdir=$${exec_prefix}/$(LIBDIR)'; \
 	    echo 'includedir=$${prefix}/include'; \
 	    echo ''; \
 	    echo 'Name: OpenSSL'; \
 	    echo 'Description: Secure Sockets Layer and cryptography libraries and tools'; \
 	    echo 'Version: '$(VERSION); \
 	    echo 'Requires: '; \
 	    echo 'Libs: -L$${libdir} -lssl -lcrypto'; \
 	    echo 'Libs.private: $(EX_LIBS)'; \
 	    echo 'Cflags: -I$${includedir} $(KRB5_INCLUDES)' ) > openssl.pc
 
 Makefile: Makefile.org Configure config
 	@echo "Makefile is older than Makefile.org, Configure or config."
 	@echo "Reconfigure the source tree (via './config' or 'perl Configure'), please."
 	@false
 
 libclean:
 	rm -f *.map *.so *.so.* *.dylib *.dll engines/*.so engines/*.dll engines/*.dylib *.a engines/*.a */lib */*/lib
 
 clean:	libclean
 	rm -f shlib/*.o *.o core a.out fluff rehash.time testlog make.log cctest cctest.c
 	@set -e; target=clean; $(RECURSIVE_BUILD_CMD)
 	rm -f $(LIBS)
 	rm -f openssl.pc libssl.pc libcrypto.pc
 	rm -f speed.* .pure
 	rm -f $(TARFILE)
 	@set -e; for i in $(ONEDIRS) ;\
 	do \
 	rm -fr $$i/*; \
 	done
 
 makefile.one: files
 	$(PERL) util/mk1mf.pl >makefile.one; \
 	sh util/do_ms.sh
 
 files:
 	$(PERL) $(TOP)/util/files.pl Makefile > $(TOP)/MINFO
 	@set -e; target=files; $(RECURSIVE_BUILD_CMD)
 
 links:
 	@$(PERL) $(TOP)/util/mkdir-p.pl include/openssl
 	@$(PERL) $(TOP)/util/mklink.pl include/openssl $(EXHEADER)
 	@set -e; target=links; $(RECURSIVE_BUILD_CMD)
 
 gentests:
 	@(cd test && echo "generating dummy tests (if needed)..." && \
 	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on generate );
 
 dclean:
 	rm -rf *.bak include/openssl certs/.0
 	@set -e; target=dclean; $(RECURSIVE_BUILD_CMD)
 
 rehash: rehash.time
 rehash.time: certs apps
 	@if [ -z "$(CROSS_COMPILE)" ]; then \
 		(OPENSSL="`pwd`/util/opensslwrap.sh"; \
 		[ -x "apps/openssl.exe" ] && OPENSSL="apps/openssl.exe" || :; \
 		OPENSSL_DEBUG_MEMORY=on; \
 		export OPENSSL OPENSSL_DEBUG_MEMORY; \
 		$(PERL) tools/c_rehash certs/demo) && \
 		touch rehash.time; \
 	else :; fi
 
 test:   tests
 
 tests: rehash
 	@(cd test && echo "testing..." && \
 	$(CLEARENV) && $(MAKE) -e $(BUILDENV) TOP=.. TESTS='$(TESTS)' OPENSSL_DEBUG_MEMORY=on OPENSSL_CONF=../apps/openssl.cnf tests );
 	OPENSSL_CONF=apps/openssl.cnf util/opensslwrap.sh version -a
 
 report:
 	@$(PERL) util/selftest.pl
 
 update: errors stacks util/libeay.num util/ssleay.num TABLE
 	@set -e; target=update; $(RECURSIVE_BUILD_CMD)
 
 depend:
 	@set -e; target=depend; $(RECURSIVE_BUILD_CMD)
 
 lint:
 	@set -e; target=lint; $(RECURSIVE_BUILD_CMD)
 
 tags:
 	rm -f TAGS
 	find . -name '[^.]*.[ch]' | xargs etags -a
 
 errors:
 	$(PERL) util/ck_errf.pl -strict */*.c */*/*.c
 	$(PERL) util/mkerr.pl -recurse -write
 	(cd engines; $(MAKE) PERL=$(PERL) errors)
 
 stacks:
 	$(PERL) util/mkstack.pl -write
 
 util/libeay.num::
 	$(PERL) util/mkdef.pl crypto update
 
 util/ssleay.num::
 	$(PERL) util/mkdef.pl ssl update
 
 TABLE: Configure
 	(echo 'Output of `Configure TABLE'"':"; \
 	$(PERL) Configure TABLE) > TABLE
 
 # Build distribution tar-file. As the list of files returned by "find" is
 # pretty long, on several platforms a "too many arguments" error or similar
 # would occur. Therefore the list of files is temporarily stored into a file
 # and read directly, requiring GNU-Tar. Call "make TAR=gtar dist" if the normal
 # tar does not support the --files-from option.
 TAR_COMMAND=$(TAR) $(TARFLAGS) --files-from $(TARFILE).list \
 	                       --owner 0 --group 0 \
 			       --transform 's|^|$(NAME)/|' \
 			       -cvf -
 
 $(TARFILE).list:
 	find * \! -name STATUS \! -name TABLE \! -name '*.o' \! -name '*.a' \
 	       \! -name '*.so' \! -name '*.so.*'  \! -name 'openssl' \
 	       \( \! -name '*test' -o -name bctest -o -name pod2mantest \) \
 	       \! -name '.#*' \! -name '*~' \! -type l \
 	    | sort > $(TARFILE).list
 
 tar: $(TARFILE).list
 	find . -type d -print | xargs chmod 755
 	find . -type f -print | xargs chmod a+r
 	find . -type f -perm -0100 -print | xargs chmod a+x
 	$(TAR_COMMAND) | gzip --best > $(TARFILE).gz
 	rm -f $(TARFILE).list
 	ls -l $(TARFILE).gz
 
 tar-snap: $(TARFILE).list
 	$(TAR_COMMAND) > $(TARFILE)
 	rm -f $(TARFILE).list
 	ls -l $(TARFILE)
 
 dist:   
 	$(PERL) Configure dist
 	@$(MAKE) SDIRS='$(SDIRS)' clean
 	@$(MAKE) TAR='$(TAR)' TARFLAGS='$(TARFLAGS)' $(DISTTARVARS) tar
 
 install: all install_docs install_sw
 
 install_sw:
 	@$(PERL) $(TOP)/util/mkdir-p.pl $(INSTALL_PREFIX)$(INSTALLTOP)/bin \
 		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR) \
 		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/engines \
 		$(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig \
 		$(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl \
 		$(INSTALL_PREFIX)$(OPENSSLDIR)/misc \
 		$(INSTALL_PREFIX)$(OPENSSLDIR)/certs \
 		$(INSTALL_PREFIX)$(OPENSSLDIR)/private
 	@set -e; headerlist="$(EXHEADER)"; for i in $$headerlist;\
 	do \
 	(cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
 	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
 	done;
 	@set -e; target=install; $(RECURSIVE_BUILD_CMD)
 	@set -e; liblist="$(LIBS)"; for i in $$liblist ;\
 	do \
 		if [ -f "$$i" ]; then \
 		(       echo installing $$i; \
 			cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 			$(RANLIB) $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 			chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 			mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i ); \
 		fi; \
 	done;
 	@set -e; if [ -n "$(SHARED_LIBS)" ]; then \
 		tmp="$(SHARED_LIBS)"; \
 		for i in $${tmp:-x}; \
 		do \
 			if [ -f "$$i" -o -f "$$i.a" ]; then \
 			(       echo installing $$i; \
 				if [ "$(PLATFORM)" != "Cygwin" ]; then \
 					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 					chmod 555 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
 				else \
 					c=`echo $$i | sed 's/^lib\(.*\)\.dll\.a/cyg\1-$(SHLIB_VERSION_NUMBER).dll/'`; \
 					cp $$c $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
 					chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new; \
 					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$c; \
 					cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 					chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new; \
 					mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/$$i; \
 				fi ); \
 				if expr $(PLATFORM) : 'mingw' > /dev/null; then \
 				(	case $$i in \
 						*crypto*) i=libeay32.dll;; \
 						*ssl*)    i=ssleay32.dll;; \
 					esac; \
 					echo installing $$i; \
 	 				cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
 	 				chmod 755 $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new; \
 	 				mv -f $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i.new $(INSTALL_PREFIX)$(INSTALLTOP)/bin/$$i ); \
 				fi; \
 			fi; \
 		done; \
 		(	here="`pwd`"; \
 			cd $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR); \
 			$(MAKE) -f $$here/Makefile HERE="$$here" link-shared ); \
 		if [ "$(INSTALLTOP)" != "/usr" ]; then \
 			echo 'OpenSSL shared libraries have been installed in:'; \
 			echo '  $(INSTALLTOP)'; \
 			echo ''; \
 			sed -e '1,/^$$/d' doc/openssl-shared.txt; \
 		fi; \
 	fi
 	cp libcrypto.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
 	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libcrypto.pc
 	cp libssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
 	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/libssl.pc
 	cp openssl.pc $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig
 	chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/$(LIBDIR)/pkgconfig/openssl.pc
 
 install_html_docs:
 	here="`pwd`"; \
 	for subdir in apps crypto ssl; do \
 		mkdir -p $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
 		for i in doc/$$subdir/*.pod; do \
 			fn=`basename $$i .pod`; \
 			echo "installing html/$$fn.$(HTMLSUFFIX)"; \
 			cat $$i \
 			| sed -r 's/L<([^)]*)(\([0-9]\))?\|([^)]*)(\([0-9]\))?>/L<\1|\3>/g' \
 			| pod2html --podroot=doc --htmlroot=.. --podpath=apps:crypto:ssl \
 			| sed -r 's/<!DOCTYPE.*//g' \
 			> $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir/$$fn.$(HTMLSUFFIX); \
 			$(PERL) util/extract-names.pl < $$i | \
 				grep -v $$filecase "^$$fn\$$" | \
 				(cd $(INSTALL_PREFIX)$(HTMLDIR)/$$subdir; \
 				 while read n; do \
 					PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$(HTMLSUFFIX) "$$n".$(HTMLSUFFIX); \
 				 done); \
 		done; \
 	done
 
 install_docs:
 	@$(PERL) $(TOP)/util/mkdir-p.pl \
 		$(INSTALL_PREFIX)$(MANDIR)/man1 \
 		$(INSTALL_PREFIX)$(MANDIR)/man3 \
 		$(INSTALL_PREFIX)$(MANDIR)/man5 \
 		$(INSTALL_PREFIX)$(MANDIR)/man7
 	@pod2man="`cd ./util; ./pod2mantest $(PERL)`"; \
 	here="`pwd`"; \
 	filecase=; \
 	if [ "$(PLATFORM)" = "DJGPP" -o "$(PLATFORM)" = "Cygwin" -o "$(PLATFORM)" = "mingw" ]; then \
 		filecase=-i; \
 	fi; \
 	set -e; for i in doc/apps/*.pod; do \
 		fn=`basename $$i .pod`; \
 		sec=`$(PERL) util/extract-section.pl 1 < $$i`; \
 		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
 		(cd `$(PERL) util/dirname.pl $$i`; \
 		sh -c "$$pod2man \
 			--section=$$sec --center=OpenSSL \
 			--release=$(VERSION) `basename $$i`") \
 			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
 		$(PERL) util/extract-names.pl < $$i | \
 			(grep -v $$filecase "^$$fn\$$"; true) | \
 			(grep -v "[	]"; true) | \
 			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
 			 while read n; do \
 				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
 			 done); \
 	done; \
 	set -e; for i in doc/crypto/*.pod doc/ssl/*.pod; do \
 		fn=`basename $$i .pod`; \
 		sec=`$(PERL) util/extract-section.pl 3 < $$i`; \
 		echo "installing man$$sec/$$fn.$${sec}$(MANSUFFIX)"; \
 		(cd `$(PERL) util/dirname.pl $$i`; \
 		sh -c "$$pod2man \
 			--section=$$sec --center=OpenSSL \
 			--release=$(VERSION) `basename $$i`") \
 			>  $(INSTALL_PREFIX)$(MANDIR)/man$$sec/$$fn.$${sec}$(MANSUFFIX); \
 		$(PERL) util/extract-names.pl < $$i | \
 			(grep -v $$filecase "^$$fn\$$"; true) | \
 			(grep -v "[	]"; true) | \
 			(cd $(INSTALL_PREFIX)$(MANDIR)/man$$sec/; \
 			 while read n; do \
 				PLATFORM=$(PLATFORM) $$here/util/point.sh $$fn.$${sec}$(MANSUFFIX) "$$n".$${sec}$(MANSUFFIX); \
 			 done); \
 	done
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
Index: vendor-crypto/openssl/dist-1.0.1/NEWS
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/NEWS	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/NEWS	(revision 306191)
@@ -1,757 +1,771 @@
 
   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.1t and OpenSSL 1.0.1u [22 Sep 2016]
+
+      o OCSP Status Request extension unbounded memory growth (CVE-2016-6304)
+      o SWEET32 Mitigation (CVE-2016-2183)
+      o OOB write in MDC2_Update() (CVE-2016-6303)
+      o Malformed SHA512 ticket DoS (CVE-2016-6302)
+      o OOB write in BN_bn2dec() (CVE-2016-2182)
+      o OOB read in TS_OBJ_print_bio() (CVE-2016-2180)
+      o Pointer arithmetic undefined behaviour (CVE-2016-2177)
+      o Constant time flag not preserved in DSA signing (CVE-2016-2178)
+      o DTLS buffered message DoS (CVE-2016-2179)
+      o DTLS replay protection DoS (CVE-2016-2181)
+      o Certificate message OOB reads (CVE-2016-6306)
+
   Major changes between OpenSSL 1.0.1s and OpenSSL 1.0.1t [3 May 2016]
 
       o Prevent padding oracle in AES-NI CBC MAC check (CVE-2016-2107)
       o Fix EVP_EncodeUpdate overflow (CVE-2016-2105)
       o Fix EVP_EncryptUpdate overflow (CVE-2016-2106)
       o Prevent ASN.1 BIO excessive memory allocation (CVE-2016-2109)
       o EBCDIC overread (CVE-2016-2176)
       o Modify behavior of ALPN to invoke callback after SNI/servername
         callback, such that updates to the SSL_CTX affect ALPN.
       o Remove LOW from the DEFAULT cipher list.  This removes singles DES from
         the default.
       o Only remove the SSLv2 methods with the no-ssl2-method option.
 
   Major changes between OpenSSL 1.0.1r and OpenSSL 1.0.1s [1 Mar 2016]
 
       o Disable weak ciphers in SSLv3 and up in default builds of OpenSSL.
       o Disable SSLv2 default build, default negotiation and weak ciphers
         (CVE-2016-0800)
       o Fix a double-free in DSA code (CVE-2016-0705)
       o Disable SRP fake user seed to address a server memory leak
         (CVE-2016-0798)
       o Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption
         (CVE-2016-0797)
       o Fix memory issues in BIO_*printf functions (CVE-2016-0799)
       o Fix side channel attack on modular exponentiation (CVE-2016-0702)
 
   Major changes between OpenSSL 1.0.1q and OpenSSL 1.0.1r [28 Jan 2016]
 
       o Protection for DH small subgroup attacks
       o SSLv2 doesn't block disabled ciphers (CVE-2015-3197)
 
   Major changes between OpenSSL 1.0.1p and OpenSSL 1.0.1q [3 Dec 2015]
 
       o Certificate verify crash with missing PSS parameter (CVE-2015-3194)
       o X509_ATTRIBUTE memory leak (CVE-2015-3195)
       o Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs
       o In DSA_generate_parameters_ex, if the provided seed is too short,
         return an error
 
   Major changes between OpenSSL 1.0.1o and OpenSSL 1.0.1p [9 Jul 2015]
 
       o Alternate chains certificate forgery (CVE-2015-1793)
       o Race condition handling PSK identify hint (CVE-2015-3196)
 
   Major changes between OpenSSL 1.0.1n and OpenSSL 1.0.1o [12 Jun 2015]
 
       o Fix HMAC ABI incompatibility
 
   Major changes between OpenSSL 1.0.1m and OpenSSL 1.0.1n [11 Jun 2015]
 
       o Malformed ECParameters causes infinite loop (CVE-2015-1788)
       o Exploitable out-of-bounds read in X509_cmp_time (CVE-2015-1789)
       o PKCS7 crash with missing EnvelopedContent (CVE-2015-1790)
       o CMS verify infinite loop with unknown hash function (CVE-2015-1792)
       o Race condition handling NewSessionTicket (CVE-2015-1791)
 
   Major changes between OpenSSL 1.0.1l and OpenSSL 1.0.1m [19 Mar 2015]
 
       o Segmentation fault in ASN1_TYPE_cmp fix (CVE-2015-0286)
       o ASN.1 structure reuse memory corruption fix (CVE-2015-0287)
       o PKCS7 NULL pointer dereferences fix (CVE-2015-0289)
       o DoS via reachable assert in SSLv2 servers fix (CVE-2015-0293)
       o Use After Free following d2i_ECPrivatekey error fix (CVE-2015-0209)
       o X509_to_X509_REQ NULL pointer deref fix (CVE-2015-0288)
       o Removed the export ciphers from the DEFAULT ciphers
 
   Major changes between OpenSSL 1.0.1k and OpenSSL 1.0.1l [15 Jan 2015]
 
       o Build fixes for the Windows and OpenVMS platforms
 
   Major changes between OpenSSL 1.0.1j and OpenSSL 1.0.1k [8 Jan 2015]
 
       o Fix for CVE-2014-3571
       o Fix for CVE-2015-0206
       o Fix for CVE-2014-3569
       o Fix for CVE-2014-3572
       o Fix for CVE-2015-0204
       o Fix for CVE-2015-0205
       o Fix for CVE-2014-8275
       o Fix for CVE-2014-3570
 
   Major changes between OpenSSL 1.0.1i and OpenSSL 1.0.1j [15 Oct 2014]
 
       o Fix for CVE-2014-3513
       o Fix for CVE-2014-3567
       o Mitigation for CVE-2014-3566 (SSL protocol vulnerability)
       o Fix for CVE-2014-3568
 
   Major changes between OpenSSL 1.0.1h and OpenSSL 1.0.1i [6 Aug 2014]
 
       o Fix for CVE-2014-3512
       o Fix for CVE-2014-3511
       o Fix for CVE-2014-3510
       o Fix for CVE-2014-3507
       o Fix for CVE-2014-3506
       o Fix for CVE-2014-3505
       o Fix for CVE-2014-3509
       o Fix for CVE-2014-5139
       o Fix for CVE-2014-3508
 
   Major changes between OpenSSL 1.0.1g and OpenSSL 1.0.1h [5 Jun 2014]
 
       o Fix for CVE-2014-0224
       o Fix for CVE-2014-0221
       o Fix for CVE-2014-0198
       o Fix for CVE-2014-0195
       o Fix for CVE-2014-3470
       o Fix for CVE-2010-5298
 
   Major changes between OpenSSL 1.0.1f and OpenSSL 1.0.1g [7 Apr 2014]
 
       o Fix for CVE-2014-0160
       o Add TLS padding extension workaround for broken servers.
       o Fix for CVE-2014-0076
 
   Major changes between OpenSSL 1.0.1e and OpenSSL 1.0.1f [6 Jan 2014]
 
       o Don't include gmt_unix_time in TLS server and client random values
       o Fix for TLS record tampering bug CVE-2013-4353
       o Fix for TLS version checking bug CVE-2013-6449
       o Fix for DTLS retransmission bug CVE-2013-6450
 
   Major changes between OpenSSL 1.0.1d and OpenSSL 1.0.1e [11 Feb 2013]:
 
       o Corrected fix for CVE-2013-0169
 
   Major changes between OpenSSL 1.0.1c and OpenSSL 1.0.1d [4 Feb 2013]:
 
       o Fix renegotiation in TLS 1.1, 1.2 by using the correct TLS version.
       o Include the fips configuration module.
       o Fix OCSP bad key DoS attack CVE-2013-0166
       o Fix for SSL/TLS/DTLS CBC plaintext recovery attack CVE-2013-0169
       o Fix for TLS AESNI record handling flaw CVE-2012-2686
 
   Major changes between OpenSSL 1.0.1b and OpenSSL 1.0.1c [10 May 2012]:
 
       o Fix TLS/DTLS record length checking bug CVE-2012-2333
       o Don't attempt to use non-FIPS composite ciphers in FIPS mode.
 
   Major changes between OpenSSL 1.0.1a and OpenSSL 1.0.1b [26 Apr 2012]:
 
       o Fix compilation error on non-x86 platforms.
       o Make FIPS capable OpenSSL ciphers work in non-FIPS mode.
       o Fix SSL_OP_NO_TLSv1_1 clash with SSL_OP_ALL in OpenSSL 1.0.0
 
   Major changes between OpenSSL 1.0.1 and OpenSSL 1.0.1a [19 Apr 2012]:
 
       o Fix for ASN1 overflow bug CVE-2012-2110
       o Workarounds for some servers that hang on long client hellos.
       o Fix SEGV in AES code.
 
   Major changes between OpenSSL 1.0.0h and OpenSSL 1.0.1 [14 Mar 2012]:
 
       o TLS/DTLS heartbeat support.
       o SCTP support.
       o RFC 5705 TLS key material exporter.
       o RFC 5764 DTLS-SRTP negotiation.
       o Next Protocol Negotiation.
       o PSS signatures in certificates, requests and CRLs.
       o Support for password based recipient info for CMS.
       o Support TLS v1.2 and TLS v1.1.
       o Preliminary FIPS capability for unvalidated 2.0 FIPS module.
       o SRP support.
 
   Major changes between OpenSSL 1.0.0g and OpenSSL 1.0.0h [12 Mar 2012]:
 
       o Fix for CMS/PKCS#7 MMA CVE-2012-0884
       o Corrected fix for CVE-2011-4619
       o Various DTLS fixes.
 
   Major changes between OpenSSL 1.0.0f and OpenSSL 1.0.0g [18 Jan 2012]:
 
       o Fix for DTLS DoS issue CVE-2012-0050
 
   Major changes between OpenSSL 1.0.0e and OpenSSL 1.0.0f [4 Jan 2012]:
 
       o Fix for DTLS plaintext recovery attack CVE-2011-4108
       o Clear block padding bytes of SSL 3.0 records CVE-2011-4576
       o Only allow one SGC handshake restart for SSL/TLS CVE-2011-4619
       o Check parameters are not NULL in GOST ENGINE CVE-2012-0027
       o Check for malformed RFC3779 data CVE-2011-4577
 
   Major changes between OpenSSL 1.0.0d and OpenSSL 1.0.0e [6 Sep 2011]:
 
       o Fix for CRL vulnerability issue CVE-2011-3207
       o Fix for ECDH crashes CVE-2011-3210
       o Protection against EC timing attacks.
       o Support ECDH ciphersuites for certificates using SHA2 algorithms.
       o Various DTLS fixes.
 
   Major changes between OpenSSL 1.0.0c and OpenSSL 1.0.0d [8 Feb 2011]:
 
       o Fix for security issue CVE-2011-0014
 
   Major changes between OpenSSL 1.0.0b and OpenSSL 1.0.0c [2 Dec 2010]:
 
       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 [16 Nov 2010]:
 
       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 [1 Jun 2010]:
 
       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 [29 Mar 2010]:
 
       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.8m and OpenSSL 0.9.8n [24 Mar 2010]:
 
       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 [25 Feb 2010]:
 
       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 [5 Nov 2009]:
 
       o Temporary work around for CVE-2009-3555: disable renegotiation.
 
   Major changes between OpenSSL 0.9.8j and OpenSSL 0.9.8k [25 Mar 2009]:
 
       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 [7 Jan 2009]:
 
       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 [28 May 2008]:
 
       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 [19 Oct 2007]:
 
       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 [11 Oct 2007]:
 
       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 [23 Feb 2007]:
 
       o Various ciphersuite selection fixes.
       o RFC3779 support.
 
   Major changes between OpenSSL 0.9.8c and OpenSSL 0.9.8d [28 Sep 2006]:
 
       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 [5 Sep 2006]:
 
       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 [4 May 2006]:
 
       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 [11 Oct 2005]:
 
       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 [5 Jul 2005]:
 
       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 [23 Feb 2007]:
 
       o FIPS 1.1.1 module linking.
       o Various ciphersuite selection fixes.
 
   Major changes between OpenSSL 0.9.7k and OpenSSL 0.9.7l [28 Sep 2006]:
 
       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 [5 Sep 2006]:
 
       o Fix Daniel Bleichenbacher forged signature attack, CVE-2006-4339
 
   Major changes between OpenSSL 0.9.7i and OpenSSL 0.9.7j [4 May 2006]:
 
       o Visual C++ 2005 fixes.
       o Update Windows build system for FIPS.
 
   Major changes between OpenSSL 0.9.7h and OpenSSL 0.9.7i [14 Oct 2005]:
 
       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 [11 Oct 2005]:
 
       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 [11 Apr 2005]:
 
       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 [22 Mar 2005]:
 
       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 [25 Oct 2004]:
 
       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 [17 Mar 2004]:
 
       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 [30 Sep 2003]:
 
       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 [10 Apr 2003]:
 
       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 [19 Feb 2003]:
 
       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 [30 Dec 2002]:
 
       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 [30 Sep 2003]:
 
       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 [10 Apr 2003]:
 
       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 [19 Feb 2003]:
 
       o Important security related bugfixes.
 
   Major changes between OpenSSL 0.9.6g and OpenSSL 0.9.6h [5 Dec 2002]:
 
       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 [9 Aug 2002]:
 
       o Important building fixes on Unix.
 
   Major changes between OpenSSL 0.9.6e and OpenSSL 0.9.6f [8 Aug 2002]:
 
       o Various important bugfixes.
 
   Major changes between OpenSSL 0.9.6d and OpenSSL 0.9.6e [30 Jul 2002]:
 
       o Important security related bugfixes.
       o Various SSL/TLS library bugfixes.
 
   Major changes between OpenSSL 0.9.6c and OpenSSL 0.9.6d [9 May 2002]:
 
       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 [21 Dec 2001]:
 
       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 [9 Jul 2001]:
 
       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 [5 Apr 2001]:
 
       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 [10 Oct 2000]:
 
       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 [1 Apr 2000]:
 
       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 [25 May 2000]:
 
       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 [9 Aug 1999]:
 
       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 [24 May 1999]:
       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 [22 Mar 1999]:
       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 [23 Dec 1998]:
       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
 
Index: vendor-crypto/openssl/dist-1.0.1/README
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/README	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/README	(revision 306191)
@@ -1,119 +1,119 @@
 
- OpenSSL 1.0.1t 3 May 2016
+ OpenSSL 1.0.1u 22 Sep 2016
 
  Copyright (c) 1998-2015 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 (SSLv3) and Transport Layer Security (TLS) protocols as
  well as a full-strength general purpose cryptograpic 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 descended from the SSLeay library developed by Eric A. Young
  and Tim J. Hudson.  The OpenSSL toolkit is licensed under a dual-license (the
  OpenSSL license plus the SSLeay license), which 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:
      Provides the client and server-side implementations for SSLv3 and TLS.
 
  libcrypto.a:
      Provides general cryptographic and X.509 support needed by SSL/TLS but
      not logically part of it.
 
  openssl:
      A command line tool that can be used for:
         Creation of key parameters
         Creation of X.509 certificates, CSRs and CRLs
         Calculation of message digests
         Encryption and decryption
         SSL/TLS client and server tests
         Handling of S/MIME signed or encrypted mail
         And more...
 
  INSTALLATION
  ------------
 
  See the appropriate file:
         INSTALL         Linux, Unix, etc.
         INSTALL.DJGPP   DOS platform with DJGPP
         INSTALL.NW      Netware
         INSTALL.OS2     OS/2
         INSTALL.VMS     VMS
         INSTALL.W32     Windows (32bit)
         INSTALL.W64     Windows (64bit)
         INSTALL.WCE     Windows CE
 
  SUPPORT
  -------
 
  See the OpenSSL website www.openssl.org for details on 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)
 
  Email the report to:
 
     rt@openssl.org
 
  In order to avoid spam, this is a moderated mailing list, and it might
  take a day for the ticket to show up.  (We also scan posts to make sure
  that security disclosures aren't publically posted by mistake.) Mail
  to this address is recorded in the public RT (request tracker) database
  (see https://www.openssl.org/community/index.html#bugs for details) and
  also forwarded the public openssl-dev mailing list.  Confidential mail
  may be sent to openssl-security@openssl.org (PGP key available from the
  key servers).
 
  Please do NOT use this 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.
 
  You can also make GitHub pull requests. If you do this, please also send
  mail to rt@openssl.org with a link to the PR so that we can more easily
  keep track of it.
 
  HOW TO CONTRIBUTE TO OpenSSL
  ----------------------------
 
  See CONTRIBUTING
 
  LEGALITIES
  ----------
 
  A number of nations, in particular the U.S., restrict the use or export
  of cryptography. If you are potentially subject to such restrictions
  you should seek competent professional legal advice before attempting to
  develop or distribute cryptographic code.
Index: vendor-crypto/openssl/dist-1.0.1/apps/apps.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/apps/apps.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/apps/apps.c	(revision 306191)
@@ -1,2978 +1,2980 @@
 /* apps/apps.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).
  *
  */
 
 #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
 /*
  * On VMS, you need to define this to get the declaration of fileno().  The
  * value 2 is to make sure no function defined in POSIX-2 is left undefined.
  */
 # define _POSIX_C_SOURCE 2
 #endif
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <ctype.h>
 #include <errno.h>
 #include <assert.h>
 #include <openssl/err.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
 #include <openssl/ui.h>
 #include <openssl/safestack.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 #ifndef OPENSSL_NO_RSA
 # include <openssl/rsa.h>
 #endif
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_JPAKE
 # include <openssl/jpake.h>
 #endif
 
 #define NON_MAIN
 #include "apps.h"
 #undef NON_MAIN
 
 #ifdef _WIN32
 static int WIN32_rename(const char *from, const char *to);
 # define rename(from,to) WIN32_rename((from),(to))
 #endif
 
 typedef struct {
     const char *name;
     unsigned long flag;
     unsigned long mask;
 } NAME_EX_TBL;
 
 static UI_METHOD *ui_method = NULL;
 
 static int set_table_opts(unsigned long *flags, const char *arg,
                           const NAME_EX_TBL * in_tbl);
 static int set_multi_opts(unsigned long *flags, const char *arg,
                           const NAME_EX_TBL * in_tbl);
 
 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
 /* Looks like this stuff is worth moving into separate function */
 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
                                    const char *key_descrip, int format);
 #endif
 
 int app_init(long mesgwin);
 #ifdef undef                    /* never finished - probably never will be
                                  * :-) */
 int args_from_file(char *file, int *argc, char **argv[])
 {
     FILE *fp;
     int num, i;
     unsigned int len;
     static char *buf = NULL;
     static char **arg = NULL;
     char *p;
 
     fp = fopen(file, "r");
     if (fp == NULL)
         return (0);
 
     if (fseek(fp, 0, SEEK_END) == 0)
         len = ftell(fp), rewind(fp);
     else
         len = -1;
     if (len <= 0) {
         fclose(fp);
         return (0);
     }
 
     *argc = 0;
     *argv = NULL;
 
     if (buf != NULL)
         OPENSSL_free(buf);
     buf = (char *)OPENSSL_malloc(len + 1);
     if (buf == NULL)
         return (0);
 
     len = fread(buf, 1, len, fp);
     if (len <= 1)
         return (0);
     buf[len] = '\0';
 
     i = 0;
     for (p = buf; *p; p++)
         if (*p == '\n')
             i++;
     if (arg != NULL)
         OPENSSL_free(arg);
     arg = (char **)OPENSSL_malloc(sizeof(char *) * (i * 2));
 
     *argv = arg;
     num = 0;
     p = buf;
     for (;;) {
         if (!*p)
             break;
         if (*p == '#') {        /* comment line */
             while (*p && (*p != '\n'))
                 p++;
             continue;
         }
         /* else we have a line */
         *(arg++) = p;
         num++;
         while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
             p++;
         if (!*p)
             break;
         if (*p == '\n') {
             *(p++) = '\0';
             continue;
         }
         /* else it is a tab or space */
         p++;
         while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
             p++;
         if (!*p)
             break;
         if (*p == '\n') {
             p++;
             continue;
         }
         *(arg++) = p++;
         num++;
         while (*p && (*p != '\n'))
             p++;
         if (!*p)
             break;
         /* else *p == '\n' */
         *(p++) = '\0';
     }
     *argc = num;
     return (1);
 }
 #endif
 
 int str2fmt(char *s)
 {
     if (s == NULL)
         return FORMAT_UNDEF;
     if ((*s == 'D') || (*s == 'd'))
         return (FORMAT_ASN1);
     else if ((*s == 'T') || (*s == 't'))
         return (FORMAT_TEXT);
     else if ((*s == 'N') || (*s == 'n'))
         return (FORMAT_NETSCAPE);
     else if ((*s == 'S') || (*s == 's'))
         return (FORMAT_SMIME);
     else if ((*s == 'M') || (*s == 'm'))
         return (FORMAT_MSBLOB);
     else if ((*s == '1')
              || (strcmp(s, "PKCS12") == 0) || (strcmp(s, "pkcs12") == 0)
              || (strcmp(s, "P12") == 0) || (strcmp(s, "p12") == 0))
         return (FORMAT_PKCS12);
     else if ((*s == 'E') || (*s == 'e'))
         return (FORMAT_ENGINE);
     else if ((*s == 'P') || (*s == 'p')) {
         if (s[1] == 'V' || s[1] == 'v')
             return FORMAT_PVK;
         else
             return (FORMAT_PEM);
     } else
         return (FORMAT_UNDEF);
 }
 
 #if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_NETWARE)
 void program_name(char *in, char *out, int size)
 {
     int i, n;
     char *p = NULL;
 
     n = strlen(in);
     /* find the last '/', '\' or ':' */
     for (i = n - 1; i > 0; i--) {
         if ((in[i] == '/') || (in[i] == '\\') || (in[i] == ':')) {
             p = &(in[i + 1]);
             break;
         }
     }
     if (p == NULL)
         p = in;
     n = strlen(p);
 
 # if defined(OPENSSL_SYS_NETWARE)
     /* strip off trailing .nlm if present. */
     if ((n > 4) && (p[n - 4] == '.') &&
         ((p[n - 3] == 'n') || (p[n - 3] == 'N')) &&
         ((p[n - 2] == 'l') || (p[n - 2] == 'L')) &&
         ((p[n - 1] == 'm') || (p[n - 1] == 'M')))
         n -= 4;
 # else
     /* strip off trailing .exe if present. */
     if ((n > 4) && (p[n - 4] == '.') &&
         ((p[n - 3] == 'e') || (p[n - 3] == 'E')) &&
         ((p[n - 2] == 'x') || (p[n - 2] == 'X')) &&
         ((p[n - 1] == 'e') || (p[n - 1] == 'E')))
         n -= 4;
 # endif
 
     if (n > size - 1)
         n = size - 1;
 
     for (i = 0; i < n; i++) {
         if ((p[i] >= 'A') && (p[i] <= 'Z'))
             out[i] = p[i] - 'A' + 'a';
         else
             out[i] = p[i];
     }
     out[n] = '\0';
 }
 #else
 # ifdef OPENSSL_SYS_VMS
 void program_name(char *in, char *out, int size)
 {
     char *p = in, *q;
     char *chars = ":]>";
 
     while (*chars != '\0') {
         q = strrchr(p, *chars);
         if (q > p)
             p = q + 1;
         chars++;
     }
 
     q = strrchr(p, '.');
     if (q == NULL)
         q = p + strlen(p);
     strncpy(out, p, size - 1);
     if (q - p >= size) {
         out[size - 1] = '\0';
     } else {
         out[q - p] = '\0';
     }
 }
 # else
 void program_name(char *in, char *out, int size)
 {
     char *p;
 
     p = strrchr(in, '/');
     if (p != NULL)
         p++;
     else
         p = in;
     BUF_strlcpy(out, p, size);
 }
 # endif
 #endif
 
 int chopup_args(ARGS *arg, char *buf, int *argc, char **argv[])
 {
     int num, i;
     char *p;
 
     *argc = 0;
     *argv = NULL;
 
     i = 0;
     if (arg->count == 0) {
         arg->count = 20;
         arg->data = (char **)OPENSSL_malloc(sizeof(char *) * arg->count);
         if (arg->data == NULL)
             return 0;
     }
     for (i = 0; i < arg->count; i++)
         arg->data[i] = NULL;
 
     num = 0;
     p = buf;
     for (;;) {
         /* first scan over white space */
         if (!*p)
             break;
         while (*p && ((*p == ' ') || (*p == '\t') || (*p == '\n')))
             p++;
         if (!*p)
             break;
 
         /* The start of something good :-) */
         if (num >= arg->count) {
             char **tmp_p;
             int tlen = arg->count + 20;
             tmp_p = (char **)OPENSSL_realloc(arg->data,
                                              sizeof(char *) * tlen);
             if (tmp_p == NULL)
                 return 0;
             arg->data = tmp_p;
             arg->count = tlen;
             /* initialize newly allocated data */
             for (i = num; i < arg->count; i++)
                 arg->data[i] = NULL;
         }
         arg->data[num++] = p;
 
         /* now look for the end of this */
         if ((*p == '\'') || (*p == '\"')) { /* scan for closing quote */
             i = *(p++);
             arg->data[num - 1]++; /* jump over quote */
             while (*p && (*p != i))
                 p++;
             *p = '\0';
         } else {
             while (*p && ((*p != ' ') && (*p != '\t') && (*p != '\n')))
                 p++;
 
             if (*p == '\0')
                 p--;
             else
                 *p = '\0';
         }
         p++;
     }
     *argc = num;
     *argv = arg->data;
     return (1);
 }
 
 #ifndef APP_INIT
 int app_init(long mesgwin)
 {
     return (1);
 }
 #endif
 
 int dump_cert_text(BIO *out, X509 *x)
 {
     char *p;
 
     p = X509_NAME_oneline(X509_get_subject_name(x), NULL, 0);
     BIO_puts(out, "subject=");
     BIO_puts(out, p);
     OPENSSL_free(p);
 
     p = X509_NAME_oneline(X509_get_issuer_name(x), NULL, 0);
     BIO_puts(out, "\nissuer=");
     BIO_puts(out, p);
     BIO_puts(out, "\n");
     OPENSSL_free(p);
 
     return 0;
 }
 
 static int ui_open(UI *ui)
 {
     return UI_method_get_opener(UI_OpenSSL())(ui);
 }
 
 static int ui_read(UI *ui, UI_STRING *uis)
 {
     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
         && UI_get0_user_data(ui)) {
         switch (UI_get_string_type(uis)) {
         case UIT_PROMPT:
         case UIT_VERIFY:
             {
                 const char *password =
                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
                 if (password && password[0] != '\0') {
                     UI_set_result(ui, uis, password);
                     return 1;
                 }
             }
         default:
             break;
         }
     }
     return UI_method_get_reader(UI_OpenSSL())(ui, uis);
 }
 
 static int ui_write(UI *ui, UI_STRING *uis)
 {
     if (UI_get_input_flags(uis) & UI_INPUT_FLAG_DEFAULT_PWD
         && UI_get0_user_data(ui)) {
         switch (UI_get_string_type(uis)) {
         case UIT_PROMPT:
         case UIT_VERIFY:
             {
                 const char *password =
                     ((PW_CB_DATA *)UI_get0_user_data(ui))->password;
                 if (password && password[0] != '\0')
                     return 1;
             }
         default:
             break;
         }
     }
     return UI_method_get_writer(UI_OpenSSL())(ui, uis);
 }
 
 static int ui_close(UI *ui)
 {
     return UI_method_get_closer(UI_OpenSSL())(ui);
 }
 
 int setup_ui_method(void)
 {
     ui_method = UI_create_method("OpenSSL application user interface");
     UI_method_set_opener(ui_method, ui_open);
     UI_method_set_reader(ui_method, ui_read);
     UI_method_set_writer(ui_method, ui_write);
     UI_method_set_closer(ui_method, ui_close);
     return 0;
 }
 
 void destroy_ui_method(void)
 {
     if (ui_method) {
         UI_destroy_method(ui_method);
         ui_method = NULL;
     }
 }
 
 int password_callback(char *buf, int bufsiz, int verify, PW_CB_DATA *cb_tmp)
 {
     UI *ui = NULL;
     int res = 0;
     const char *prompt_info = NULL;
     const char *password = NULL;
     PW_CB_DATA *cb_data = (PW_CB_DATA *)cb_tmp;
 
     if (cb_data) {
         if (cb_data->password)
             password = cb_data->password;
         if (cb_data->prompt_info)
             prompt_info = cb_data->prompt_info;
     }
 
     if (password) {
         res = strlen(password);
         if (res > bufsiz)
             res = bufsiz;
         memcpy(buf, password, res);
         return res;
     }
 
     ui = UI_new_method(ui_method);
     if (ui) {
         int ok = 0;
         char *buff = NULL;
         int ui_flags = 0;
         char *prompt = NULL;
 
         prompt = UI_construct_prompt(ui, "pass phrase", prompt_info);
         if (!prompt) {
             BIO_printf(bio_err, "Out of memory\n");
             UI_free(ui);
             return 0;
         }
 
         ui_flags |= UI_INPUT_FLAG_DEFAULT_PWD;
         UI_ctrl(ui, UI_CTRL_PRINT_ERRORS, 1, 0, 0);
 
         if (ok >= 0)
             ok = UI_add_input_string(ui, prompt, ui_flags, buf,
                                      PW_MIN_LENGTH, bufsiz - 1);
         if (ok >= 0 && verify) {
             buff = (char *)OPENSSL_malloc(bufsiz);
             if (!buff) {
                 BIO_printf(bio_err, "Out of memory\n");
                 UI_free(ui);
                 OPENSSL_free(prompt);
                 return 0;
             }
             ok = UI_add_verify_string(ui, prompt, ui_flags, buff,
                                       PW_MIN_LENGTH, bufsiz - 1, buf);
         }
         if (ok >= 0)
             do {
                 ok = UI_process(ui);
             }
             while (ok < 0 && UI_ctrl(ui, UI_CTRL_IS_REDOABLE, 0, 0, 0));
 
         if (buff) {
             OPENSSL_cleanse(buff, (unsigned int)bufsiz);
             OPENSSL_free(buff);
         }
 
         if (ok >= 0)
             res = strlen(buf);
         if (ok == -1) {
             BIO_printf(bio_err, "User interface error\n");
             ERR_print_errors(bio_err);
             OPENSSL_cleanse(buf, (unsigned int)bufsiz);
             res = 0;
         }
         if (ok == -2) {
             BIO_printf(bio_err, "aborted!\n");
             OPENSSL_cleanse(buf, (unsigned int)bufsiz);
             res = 0;
         }
         UI_free(ui);
         OPENSSL_free(prompt);
     }
     return res;
 }
 
 static char *app_get_pass(BIO *err, char *arg, int keepbio);
 
 int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2)
 {
     int same;
     if (!arg2 || !arg1 || strcmp(arg1, arg2))
         same = 0;
     else
         same = 1;
     if (arg1) {
         *pass1 = app_get_pass(err, arg1, same);
         if (!*pass1)
             return 0;
     } else if (pass1)
         *pass1 = NULL;
     if (arg2) {
         *pass2 = app_get_pass(err, arg2, same ? 2 : 0);
         if (!*pass2)
             return 0;
     } else if (pass2)
         *pass2 = NULL;
     return 1;
 }
 
 static char *app_get_pass(BIO *err, char *arg, int keepbio)
 {
     char *tmp, tpass[APP_PASS_LEN];
     static BIO *pwdbio = NULL;
     int i;
     if (!strncmp(arg, "pass:", 5))
         return BUF_strdup(arg + 5);
     if (!strncmp(arg, "env:", 4)) {
         tmp = getenv(arg + 4);
         if (!tmp) {
             BIO_printf(err, "Can't read environment variable %s\n", arg + 4);
             return NULL;
         }
         return BUF_strdup(tmp);
     }
     if (!keepbio || !pwdbio) {
         if (!strncmp(arg, "file:", 5)) {
             pwdbio = BIO_new_file(arg + 5, "r");
             if (!pwdbio) {
                 BIO_printf(err, "Can't open file %s\n", arg + 5);
                 return NULL;
             }
 #if !defined(_WIN32)
             /*
              * Under _WIN32, which covers even Win64 and CE, file
              * descriptors referenced by BIO_s_fd are not inherited
              * by child process and therefore below is not an option.
              * It could have been an option if bss_fd.c was operating
              * on real Windows descriptors, such as those obtained
              * with CreateFile.
              */
         } else if (!strncmp(arg, "fd:", 3)) {
             BIO *btmp;
             i = atoi(arg + 3);
             if (i >= 0)
                 pwdbio = BIO_new_fd(i, BIO_NOCLOSE);
             if ((i < 0) || !pwdbio) {
                 BIO_printf(err, "Can't access file descriptor %s\n", arg + 3);
                 return NULL;
             }
             /*
              * Can't do BIO_gets on an fd BIO so add a buffering BIO
              */
             btmp = BIO_new(BIO_f_buffer());
             pwdbio = BIO_push(btmp, pwdbio);
 #endif
         } else if (!strcmp(arg, "stdin")) {
             pwdbio = BIO_new_fp(stdin, BIO_NOCLOSE);
             if (!pwdbio) {
                 BIO_printf(err, "Can't open BIO for stdin\n");
                 return NULL;
             }
         } else {
             BIO_printf(err, "Invalid password argument \"%s\"\n", arg);
             return NULL;
         }
     }
     i = BIO_gets(pwdbio, tpass, APP_PASS_LEN);
     if (keepbio != 1) {
         BIO_free_all(pwdbio);
         pwdbio = NULL;
     }
     if (i <= 0) {
         BIO_printf(err, "Error reading password from BIO\n");
         return NULL;
     }
     tmp = strchr(tpass, '\n');
     if (tmp)
         *tmp = 0;
     return BUF_strdup(tpass);
 }
 
 int add_oid_section(BIO *err, CONF *conf)
 {
     char *p;
     STACK_OF(CONF_VALUE) *sktmp;
     CONF_VALUE *cnf;
     int i;
     if (!(p = NCONF_get_string(conf, NULL, "oid_section"))) {
         ERR_clear_error();
         return 1;
     }
     if (!(sktmp = NCONF_get_section(conf, p))) {
         BIO_printf(err, "problem loading oid section %s\n", p);
         return 0;
     }
     for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
         cnf = sk_CONF_VALUE_value(sktmp, i);
         if (OBJ_create(cnf->value, cnf->name, cnf->name) == NID_undef) {
             BIO_printf(err, "problem creating object %s=%s\n",
                        cnf->name, cnf->value);
             return 0;
         }
     }
     return 1;
 }
 
 static int load_pkcs12(BIO *err, BIO *in, const char *desc,
                        pem_password_cb *pem_cb, void *cb_data,
                        EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca)
 {
     const char *pass;
     char tpass[PEM_BUFSIZE];
     int len, ret = 0;
     PKCS12 *p12;
     p12 = d2i_PKCS12_bio(in, NULL);
     if (p12 == NULL) {
         BIO_printf(err, "Error loading PKCS12 file for %s\n", desc);
         goto die;
     }
     /* See if an empty password will do */
     if (PKCS12_verify_mac(p12, "", 0) || PKCS12_verify_mac(p12, NULL, 0))
         pass = "";
     else {
         if (!pem_cb)
             pem_cb = (pem_password_cb *)password_callback;
         len = pem_cb(tpass, PEM_BUFSIZE, 0, cb_data);
         if (len < 0) {
             BIO_printf(err, "Passpharse callback error for %s\n", desc);
             goto die;
         }
         if (len < PEM_BUFSIZE)
             tpass[len] = 0;
         if (!PKCS12_verify_mac(p12, tpass, len)) {
             BIO_printf(err,
                        "Mac verify error (wrong password?) in PKCS12 file for %s\n",
                        desc);
             goto die;
         }
         pass = tpass;
     }
     ret = PKCS12_parse(p12, pass, pkey, cert, ca);
  die:
     if (p12)
         PKCS12_free(p12);
     return ret;
 }
 
 X509 *load_cert(BIO *err, const char *file, int format,
                 const char *pass, ENGINE *e, const char *cert_descrip)
 {
     X509 *x = NULL;
     BIO *cert;
 
     if ((cert = BIO_new(BIO_s_file())) == NULL) {
         ERR_print_errors(err);
         goto end;
     }
 
     if (file == NULL) {
 #ifdef _IONBF
 # ifndef OPENSSL_NO_SETVBUF_IONBF
         setvbuf(stdin, NULL, _IONBF, 0);
 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
 #endif
         BIO_set_fp(cert, stdin, BIO_NOCLOSE);
     } else {
         if (BIO_read_filename(cert, file) <= 0) {
             BIO_printf(err, "Error opening %s %s\n", cert_descrip, file);
             ERR_print_errors(err);
             goto end;
         }
     }
 
     if (format == FORMAT_ASN1)
         x = d2i_X509_bio(cert, NULL);
     else if (format == FORMAT_NETSCAPE) {
         NETSCAPE_X509 *nx;
         nx = ASN1_item_d2i_bio(ASN1_ITEM_rptr(NETSCAPE_X509), cert, NULL);
         if (nx == NULL)
             goto end;
 
         if ((strncmp(NETSCAPE_CERT_HDR, (char *)nx->header->data,
                      nx->header->length) != 0)) {
             NETSCAPE_X509_free(nx);
             BIO_printf(err, "Error reading header on certificate\n");
             goto end;
         }
         x = nx->cert;
         nx->cert = NULL;
         NETSCAPE_X509_free(nx);
     } else if (format == FORMAT_PEM)
         x = PEM_read_bio_X509_AUX(cert, NULL,
                                   (pem_password_cb *)password_callback, NULL);
     else if (format == FORMAT_PKCS12) {
         if (!load_pkcs12(err, cert, cert_descrip, NULL, NULL, NULL, &x, NULL))
             goto end;
     } else {
         BIO_printf(err, "bad input format specified for %s\n", cert_descrip);
         goto end;
     }
  end:
     if (x == NULL) {
         BIO_printf(err, "unable to load certificate\n");
         ERR_print_errors(err);
     }
     if (cert != NULL)
         BIO_free(cert);
     return (x);
 }
 
 EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
                    const char *pass, ENGINE *e, const char *key_descrip)
 {
     BIO *key = NULL;
     EVP_PKEY *pkey = NULL;
     PW_CB_DATA cb_data;
 
     cb_data.password = pass;
     cb_data.prompt_info = file;
 
     if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
         BIO_printf(err, "no keyfile specified\n");
         goto end;
     }
 #ifndef OPENSSL_NO_ENGINE
     if (format == FORMAT_ENGINE) {
         if (!e)
             BIO_printf(err, "no engine specified\n");
         else {
             pkey = ENGINE_load_private_key(e, file, ui_method, &cb_data);
             if (!pkey) {
                 BIO_printf(err, "cannot load %s from engine\n", key_descrip);
                 ERR_print_errors(err);
             }
         }
         goto end;
     }
 #endif
     key = BIO_new(BIO_s_file());
     if (key == NULL) {
         ERR_print_errors(err);
         goto end;
     }
     if (file == NULL && maybe_stdin) {
 #ifdef _IONBF
 # ifndef OPENSSL_NO_SETVBUF_IONBF
         setvbuf(stdin, NULL, _IONBF, 0);
 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
 #endif
         BIO_set_fp(key, stdin, BIO_NOCLOSE);
     } else if (BIO_read_filename(key, file) <= 0) {
         BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
         ERR_print_errors(err);
         goto end;
     }
     if (format == FORMAT_ASN1) {
         pkey = d2i_PrivateKey_bio(key, NULL);
     } else if (format == FORMAT_PEM) {
         pkey = PEM_read_bio_PrivateKey(key, NULL,
                                        (pem_password_cb *)password_callback,
                                        &cb_data);
     }
 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
     else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
         pkey = load_netscape_key(err, key, file, key_descrip, format);
 #endif
     else if (format == FORMAT_PKCS12) {
         if (!load_pkcs12(err, key, key_descrip,
                          (pem_password_cb *)password_callback, &cb_data,
                          &pkey, NULL, NULL))
             goto end;
     }
 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
     else if (format == FORMAT_MSBLOB)
         pkey = b2i_PrivateKey_bio(key);
     else if (format == FORMAT_PVK)
         pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
                            &cb_data);
 #endif
     else {
         BIO_printf(err, "bad input format specified for key file\n");
         goto end;
     }
  end:
     if (key != NULL)
         BIO_free(key);
     if (pkey == NULL) {
         BIO_printf(err, "unable to load %s\n", key_descrip);
         ERR_print_errors(err);
     }
     return (pkey);
 }
 
 EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
                       const char *pass, ENGINE *e, const char *key_descrip)
 {
     BIO *key = NULL;
     EVP_PKEY *pkey = NULL;
     PW_CB_DATA cb_data;
 
     cb_data.password = pass;
     cb_data.prompt_info = file;
 
     if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE)) {
         BIO_printf(err, "no keyfile specified\n");
         goto end;
     }
 #ifndef OPENSSL_NO_ENGINE
     if (format == FORMAT_ENGINE) {
         if (!e)
             BIO_printf(bio_err, "no engine specified\n");
         else
             pkey = ENGINE_load_public_key(e, file, ui_method, &cb_data);
         goto end;
     }
 #endif
     key = BIO_new(BIO_s_file());
     if (key == NULL) {
         ERR_print_errors(err);
         goto end;
     }
     if (file == NULL && maybe_stdin) {
 #ifdef _IONBF
 # ifndef OPENSSL_NO_SETVBUF_IONBF
         setvbuf(stdin, NULL, _IONBF, 0);
 # endif                         /* ndef OPENSSL_NO_SETVBUF_IONBF */
 #endif
         BIO_set_fp(key, stdin, BIO_NOCLOSE);
     } else if (BIO_read_filename(key, file) <= 0) {
         BIO_printf(err, "Error opening %s %s\n", key_descrip, file);
         ERR_print_errors(err);
         goto end;
     }
     if (format == FORMAT_ASN1) {
         pkey = d2i_PUBKEY_bio(key, NULL);
     }
 #ifndef OPENSSL_NO_RSA
     else if (format == FORMAT_ASN1RSA) {
         RSA *rsa;
         rsa = d2i_RSAPublicKey_bio(key, NULL);
         if (rsa) {
             pkey = EVP_PKEY_new();
             if (pkey)
                 EVP_PKEY_set1_RSA(pkey, rsa);
             RSA_free(rsa);
         } else
             pkey = NULL;
     } else if (format == FORMAT_PEMRSA) {
         RSA *rsa;
         rsa = PEM_read_bio_RSAPublicKey(key, NULL,
                                         (pem_password_cb *)password_callback,
                                         &cb_data);
         if (rsa) {
             pkey = EVP_PKEY_new();
             if (pkey)
                 EVP_PKEY_set1_RSA(pkey, rsa);
             RSA_free(rsa);
         } else
             pkey = NULL;
     }
 #endif
     else if (format == FORMAT_PEM) {
         pkey = PEM_read_bio_PUBKEY(key, NULL,
                                    (pem_password_cb *)password_callback,
                                    &cb_data);
     }
 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
     else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
         pkey = load_netscape_key(err, key, file, key_descrip, format);
 #endif
 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
     else if (format == FORMAT_MSBLOB)
         pkey = b2i_PublicKey_bio(key);
 #endif
     else {
         BIO_printf(err, "bad input format specified for key file\n");
         goto end;
     }
  end:
     if (key != NULL)
         BIO_free(key);
     if (pkey == NULL)
         BIO_printf(err, "unable to load %s\n", key_descrip);
     return (pkey);
 }
 
 #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
 static EVP_PKEY *load_netscape_key(BIO *err, BIO *key, const char *file,
                                    const char *key_descrip, int format)
 {
     EVP_PKEY *pkey;
     BUF_MEM *buf;
     RSA *rsa;
     const unsigned char *p;
     int size, i;
 
     buf = BUF_MEM_new();
     pkey = EVP_PKEY_new();
     size = 0;
     if (buf == NULL || pkey == NULL)
         goto error;
     for (;;) {
         if (!BUF_MEM_grow_clean(buf, size + 1024 * 10))
             goto error;
         i = BIO_read(key, &(buf->data[size]), 1024 * 10);
         size += i;
         if (i == 0)
             break;
         if (i < 0) {
             BIO_printf(err, "Error reading %s %s", key_descrip, file);
             goto error;
         }
     }
     p = (unsigned char *)buf->data;
     rsa = d2i_RSA_NET(NULL, &p, (long)size, NULL,
                       (format == FORMAT_IISSGC ? 1 : 0));
     if (rsa == NULL)
         goto error;
     BUF_MEM_free(buf);
     EVP_PKEY_set1_RSA(pkey, rsa);
     return pkey;
  error:
     BUF_MEM_free(buf);
     EVP_PKEY_free(pkey);
     return NULL;
 }
 #endif                          /* ndef OPENSSL_NO_RC4 */
 
 static int load_certs_crls(BIO *err, const char *file, int format,
                            const char *pass, ENGINE *e, const char *desc,
                            STACK_OF(X509) **pcerts,
                            STACK_OF(X509_CRL) **pcrls)
 {
     int i;
     BIO *bio;
     STACK_OF(X509_INFO) *xis = NULL;
     X509_INFO *xi;
     PW_CB_DATA cb_data;
     int rv = 0;
 
     cb_data.password = pass;
     cb_data.prompt_info = file;
 
     if (format != FORMAT_PEM) {
         BIO_printf(err, "bad input format specified for %s\n", desc);
         return 0;
     }
 
     if (file == NULL)
         bio = BIO_new_fp(stdin, BIO_NOCLOSE);
     else
         bio = BIO_new_file(file, "r");
 
     if (bio == NULL) {
         BIO_printf(err, "Error opening %s %s\n", desc, file ? file : "stdin");
         ERR_print_errors(err);
         return 0;
     }
 
     xis = PEM_X509_INFO_read_bio(bio, NULL,
                                  (pem_password_cb *)password_callback,
                                  &cb_data);
 
     BIO_free(bio);
 
     if (pcerts) {
         *pcerts = sk_X509_new_null();
         if (!*pcerts)
             goto end;
     }
 
     if (pcrls) {
         *pcrls = sk_X509_CRL_new_null();
         if (!*pcrls)
             goto end;
     }
 
     for (i = 0; i < sk_X509_INFO_num(xis); i++) {
         xi = sk_X509_INFO_value(xis, i);
         if (xi->x509 && pcerts) {
             if (!sk_X509_push(*pcerts, xi->x509))
                 goto end;
             xi->x509 = NULL;
         }
         if (xi->crl && pcrls) {
             if (!sk_X509_CRL_push(*pcrls, xi->crl))
                 goto end;
             xi->crl = NULL;
         }
     }
 
     if (pcerts && sk_X509_num(*pcerts) > 0)
         rv = 1;
 
     if (pcrls && sk_X509_CRL_num(*pcrls) > 0)
         rv = 1;
 
  end:
 
     if (xis)
         sk_X509_INFO_pop_free(xis, X509_INFO_free);
 
     if (rv == 0) {
         if (pcerts) {
             sk_X509_pop_free(*pcerts, X509_free);
             *pcerts = NULL;
         }
         if (pcrls) {
             sk_X509_CRL_pop_free(*pcrls, X509_CRL_free);
             *pcrls = NULL;
         }
         BIO_printf(err, "unable to load %s\n",
                    pcerts ? "certificates" : "CRLs");
         ERR_print_errors(err);
     }
     return rv;
 }
 
 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
                            const char *pass, ENGINE *e, const char *desc)
 {
     STACK_OF(X509) *certs;
     if (!load_certs_crls(err, file, format, pass, e, desc, &certs, NULL))
         return NULL;
     return certs;
 }
 
 STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
                               const char *pass, ENGINE *e, const char *desc)
 {
     STACK_OF(X509_CRL) *crls;
     if (!load_certs_crls(err, file, format, pass, e, desc, NULL, &crls))
         return NULL;
     return crls;
 }
 
 #define X509V3_EXT_UNKNOWN_MASK         (0xfL << 16)
 /* Return error for unknown extensions */
 #define X509V3_EXT_DEFAULT              0
 /* Print error for unknown extensions */
 #define X509V3_EXT_ERROR_UNKNOWN        (1L << 16)
 /* ASN1 parse unknown extensions */
 #define X509V3_EXT_PARSE_UNKNOWN        (2L << 16)
 /* BIO_dump unknown extensions */
 #define X509V3_EXT_DUMP_UNKNOWN         (3L << 16)
 
 #define X509_FLAG_CA (X509_FLAG_NO_ISSUER | X509_FLAG_NO_PUBKEY | \
                          X509_FLAG_NO_HEADER | X509_FLAG_NO_VERSION)
 
 int set_cert_ex(unsigned long *flags, const char *arg)
 {
     static const NAME_EX_TBL cert_tbl[] = {
         {"compatible", X509_FLAG_COMPAT, 0xffffffffl},
         {"ca_default", X509_FLAG_CA, 0xffffffffl},
         {"no_header", X509_FLAG_NO_HEADER, 0},
         {"no_version", X509_FLAG_NO_VERSION, 0},
         {"no_serial", X509_FLAG_NO_SERIAL, 0},
         {"no_signame", X509_FLAG_NO_SIGNAME, 0},
         {"no_validity", X509_FLAG_NO_VALIDITY, 0},
         {"no_subject", X509_FLAG_NO_SUBJECT, 0},
         {"no_issuer", X509_FLAG_NO_ISSUER, 0},
         {"no_pubkey", X509_FLAG_NO_PUBKEY, 0},
         {"no_extensions", X509_FLAG_NO_EXTENSIONS, 0},
         {"no_sigdump", X509_FLAG_NO_SIGDUMP, 0},
         {"no_aux", X509_FLAG_NO_AUX, 0},
         {"no_attributes", X509_FLAG_NO_ATTRIBUTES, 0},
         {"ext_default", X509V3_EXT_DEFAULT, X509V3_EXT_UNKNOWN_MASK},
         {"ext_error", X509V3_EXT_ERROR_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
         {"ext_parse", X509V3_EXT_PARSE_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
         {"ext_dump", X509V3_EXT_DUMP_UNKNOWN, X509V3_EXT_UNKNOWN_MASK},
         {NULL, 0, 0}
     };
     return set_multi_opts(flags, arg, cert_tbl);
 }
 
 int set_name_ex(unsigned long *flags, const char *arg)
 {
     static const NAME_EX_TBL ex_tbl[] = {
         {"esc_2253", ASN1_STRFLGS_ESC_2253, 0},
         {"esc_ctrl", ASN1_STRFLGS_ESC_CTRL, 0},
         {"esc_msb", ASN1_STRFLGS_ESC_MSB, 0},
         {"use_quote", ASN1_STRFLGS_ESC_QUOTE, 0},
         {"utf8", ASN1_STRFLGS_UTF8_CONVERT, 0},
         {"ignore_type", ASN1_STRFLGS_IGNORE_TYPE, 0},
         {"show_type", ASN1_STRFLGS_SHOW_TYPE, 0},
         {"dump_all", ASN1_STRFLGS_DUMP_ALL, 0},
         {"dump_nostr", ASN1_STRFLGS_DUMP_UNKNOWN, 0},
         {"dump_der", ASN1_STRFLGS_DUMP_DER, 0},
         {"compat", XN_FLAG_COMPAT, 0xffffffffL},
         {"sep_comma_plus", XN_FLAG_SEP_COMMA_PLUS, XN_FLAG_SEP_MASK},
         {"sep_comma_plus_space", XN_FLAG_SEP_CPLUS_SPC, XN_FLAG_SEP_MASK},
         {"sep_semi_plus_space", XN_FLAG_SEP_SPLUS_SPC, XN_FLAG_SEP_MASK},
         {"sep_multiline", XN_FLAG_SEP_MULTILINE, XN_FLAG_SEP_MASK},
         {"dn_rev", XN_FLAG_DN_REV, 0},
         {"nofname", XN_FLAG_FN_NONE, XN_FLAG_FN_MASK},
         {"sname", XN_FLAG_FN_SN, XN_FLAG_FN_MASK},
         {"lname", XN_FLAG_FN_LN, XN_FLAG_FN_MASK},
         {"align", XN_FLAG_FN_ALIGN, 0},
         {"oid", XN_FLAG_FN_OID, XN_FLAG_FN_MASK},
         {"space_eq", XN_FLAG_SPC_EQ, 0},
         {"dump_unknown", XN_FLAG_DUMP_UNKNOWN_FIELDS, 0},
         {"RFC2253", XN_FLAG_RFC2253, 0xffffffffL},
         {"oneline", XN_FLAG_ONELINE, 0xffffffffL},
         {"multiline", XN_FLAG_MULTILINE, 0xffffffffL},
         {"ca_default", XN_FLAG_MULTILINE, 0xffffffffL},
         {NULL, 0, 0}
     };
     if (set_multi_opts(flags, arg, ex_tbl) == 0)
         return 0;
     if ((*flags & XN_FLAG_SEP_MASK) == 0)
         *flags |= XN_FLAG_SEP_CPLUS_SPC;
     return 1;
 }
 
 int set_ext_copy(int *copy_type, const char *arg)
 {
     if (!strcasecmp(arg, "none"))
         *copy_type = EXT_COPY_NONE;
     else if (!strcasecmp(arg, "copy"))
         *copy_type = EXT_COPY_ADD;
     else if (!strcasecmp(arg, "copyall"))
         *copy_type = EXT_COPY_ALL;
     else
         return 0;
     return 1;
 }
 
 int copy_extensions(X509 *x, X509_REQ *req, int copy_type)
 {
     STACK_OF(X509_EXTENSION) *exts = NULL;
     X509_EXTENSION *ext, *tmpext;
     ASN1_OBJECT *obj;
     int i, idx, ret = 0;
     if (!x || !req || (copy_type == EXT_COPY_NONE))
         return 1;
     exts = X509_REQ_get_extensions(req);
 
     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
         ext = sk_X509_EXTENSION_value(exts, i);
         obj = X509_EXTENSION_get_object(ext);
         idx = X509_get_ext_by_OBJ(x, obj, -1);
         /* Does extension exist? */
         if (idx != -1) {
             /* If normal copy don't override existing extension */
             if (copy_type == EXT_COPY_ADD)
                 continue;
             /* Delete all extensions of same type */
             do {
                 tmpext = X509_get_ext(x, idx);
                 X509_delete_ext(x, idx);
                 X509_EXTENSION_free(tmpext);
                 idx = X509_get_ext_by_OBJ(x, obj, -1);
             } while (idx != -1);
         }
         if (!X509_add_ext(x, ext, -1))
             goto end;
     }
 
     ret = 1;
 
  end:
 
     sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
 
     return ret;
 }
 
 static int set_multi_opts(unsigned long *flags, const char *arg,
                           const NAME_EX_TBL * in_tbl)
 {
     STACK_OF(CONF_VALUE) *vals;
     CONF_VALUE *val;
     int i, ret = 1;
     if (!arg)
         return 0;
     vals = X509V3_parse_list(arg);
     for (i = 0; i < sk_CONF_VALUE_num(vals); i++) {
         val = sk_CONF_VALUE_value(vals, i);
         if (!set_table_opts(flags, val->name, in_tbl))
             ret = 0;
     }
     sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
     return ret;
 }
 
 static int set_table_opts(unsigned long *flags, const char *arg,
                           const NAME_EX_TBL * in_tbl)
 {
     char c;
     const NAME_EX_TBL *ptbl;
     c = arg[0];
 
     if (c == '-') {
         c = 0;
         arg++;
     } else if (c == '+') {
         c = 1;
         arg++;
     } else
         c = 1;
 
     for (ptbl = in_tbl; ptbl->name; ptbl++) {
         if (!strcasecmp(arg, ptbl->name)) {
             *flags &= ~ptbl->mask;
             if (c)
                 *flags |= ptbl->flag;
             else
                 *flags &= ~ptbl->flag;
             return 1;
         }
     }
     return 0;
 }
 
 void print_name(BIO *out, const char *title, X509_NAME *nm,
                 unsigned long lflags)
 {
     char *buf;
     char mline = 0;
     int indent = 0;
 
     if (title)
         BIO_puts(out, title);
     if ((lflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
         mline = 1;
         indent = 4;
     }
     if (lflags == XN_FLAG_COMPAT) {
         buf = X509_NAME_oneline(nm, 0, 0);
         BIO_puts(out, buf);
         BIO_puts(out, "\n");
         OPENSSL_free(buf);
     } else {
         if (mline)
             BIO_puts(out, "\n");
         X509_NAME_print_ex(out, nm, indent, lflags);
         BIO_puts(out, "\n");
     }
 }
 
 X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath)
 {
     X509_STORE *store;
     X509_LOOKUP *lookup;
     if (!(store = X509_STORE_new()))
         goto end;
     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
     if (lookup == NULL)
         goto end;
     if (CAfile) {
         if (!X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM)) {
             BIO_printf(bp, "Error loading file %s\n", CAfile);
             goto end;
         }
     } else
         X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
 
     lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
     if (lookup == NULL)
         goto end;
     if (CApath) {
         if (!X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM)) {
             BIO_printf(bp, "Error loading directory %s\n", CApath);
             goto end;
         }
     } else
         X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
 
     ERR_clear_error();
     return store;
  end:
     X509_STORE_free(store);
     return NULL;
 }
 
 #ifndef OPENSSL_NO_ENGINE
 /* Try to load an engine in a shareable library */
 static ENGINE *try_load_engine(BIO *err, const char *engine, int debug)
 {
     ENGINE *e = ENGINE_by_id("dynamic");
     if (e) {
         if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine, 0)
             || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
             ENGINE_free(e);
             e = NULL;
         }
     }
     return e;
 }
 
 ENGINE *setup_engine(BIO *err, const char *engine, int debug)
 {
     ENGINE *e = NULL;
 
     if (engine) {
         if (strcmp(engine, "auto") == 0) {
             BIO_printf(err, "enabling auto ENGINE support\n");
             ENGINE_register_all_complete();
             return NULL;
         }
         if ((e = ENGINE_by_id(engine)) == NULL
             && (e = try_load_engine(err, engine, debug)) == NULL) {
             BIO_printf(err, "invalid engine \"%s\"\n", engine);
             ERR_print_errors(err);
             return NULL;
         }
         if (debug) {
             ENGINE_ctrl(e, ENGINE_CTRL_SET_LOGSTREAM, 0, err, 0);
         }
         ENGINE_ctrl_cmd(e, "SET_USER_INTERFACE", 0, ui_method, 0, 1);
         if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
             BIO_printf(err, "can't use that engine\n");
             ERR_print_errors(err);
             ENGINE_free(e);
             return NULL;
         }
 
         BIO_printf(err, "engine \"%s\" set.\n", ENGINE_get_id(e));
 
         /* Free our "structural" reference. */
         ENGINE_free(e);
     }
     return e;
 }
 #endif
 
 int load_config(BIO *err, CONF *cnf)
 {
     static int load_config_called = 0;
     if (load_config_called)
         return 1;
     load_config_called = 1;
     if (!cnf)
         cnf = config;
     if (!cnf)
         return 1;
 
     OPENSSL_load_builtin_modules();
 
     if (CONF_modules_load(cnf, NULL, 0) <= 0) {
         BIO_printf(err, "Error configuring OpenSSL\n");
         ERR_print_errors(err);
         return 0;
     }
     return 1;
 }
 
 char *make_config_name()
 {
     const char *t = X509_get_default_cert_area();
     size_t len;
     char *p;
 
     len = strlen(t) + strlen(OPENSSL_CONF) + 2;
     p = OPENSSL_malloc(len);
     if (p == NULL)
         return NULL;
     BUF_strlcpy(p, t, len);
 #ifndef OPENSSL_SYS_VMS
     BUF_strlcat(p, "/", len);
 #endif
     BUF_strlcat(p, OPENSSL_CONF, len);
 
     return p;
 }
 
 static unsigned long index_serial_hash(const OPENSSL_CSTRING *a)
 {
     const char *n;
 
     n = a[DB_serial];
     while (*n == '0')
         n++;
     return (lh_strhash(n));
 }
 
 static int index_serial_cmp(const OPENSSL_CSTRING *a,
                             const OPENSSL_CSTRING *b)
 {
     const char *aa, *bb;
 
     for (aa = a[DB_serial]; *aa == '0'; aa++) ;
     for (bb = b[DB_serial]; *bb == '0'; bb++) ;
     return (strcmp(aa, bb));
 }
 
 static int index_name_qual(char **a)
 {
     return (a[0][0] == 'V');
 }
 
 static unsigned long index_name_hash(const OPENSSL_CSTRING *a)
 {
     return (lh_strhash(a[DB_name]));
 }
 
 int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b)
 {
     return (strcmp(a[DB_name], b[DB_name]));
 }
 
 static IMPLEMENT_LHASH_HASH_FN(index_serial, OPENSSL_CSTRING)
 static IMPLEMENT_LHASH_COMP_FN(index_serial, OPENSSL_CSTRING)
 static IMPLEMENT_LHASH_HASH_FN(index_name, OPENSSL_CSTRING)
 static IMPLEMENT_LHASH_COMP_FN(index_name, OPENSSL_CSTRING)
 #undef BSIZE
 #define BSIZE 256
 BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai)
 {
     BIO *in = NULL;
     BIGNUM *ret = NULL;
     MS_STATIC char buf[1024];
     ASN1_INTEGER *ai = NULL;
 
     ai = ASN1_INTEGER_new();
     if (ai == NULL)
         goto err;
 
     if ((in = BIO_new(BIO_s_file())) == NULL) {
         ERR_print_errors(bio_err);
         goto err;
     }
 
     if (BIO_read_filename(in, serialfile) <= 0) {
         if (!create) {
             perror(serialfile);
             goto err;
         } else {
             ret = BN_new();
             if (ret == NULL || !rand_serial(ret, ai))
                 BIO_printf(bio_err, "Out of memory\n");
         }
     } else {
         if (!a2i_ASN1_INTEGER(in, ai, buf, 1024)) {
             BIO_printf(bio_err, "unable to load number from %s\n",
                        serialfile);
             goto err;
         }
         ret = ASN1_INTEGER_to_BN(ai, NULL);
         if (ret == NULL) {
             BIO_printf(bio_err,
                        "error converting number from bin to BIGNUM\n");
             goto err;
         }
     }
 
     if (ret && retai) {
         *retai = ai;
         ai = NULL;
     }
  err:
     if (in != NULL)
         BIO_free(in);
     if (ai != NULL)
         ASN1_INTEGER_free(ai);
     return (ret);
 }
 
 int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
                 ASN1_INTEGER **retai)
 {
     char buf[1][BSIZE];
     BIO *out = NULL;
     int ret = 0;
     ASN1_INTEGER *ai = NULL;
     int j;
 
     if (suffix == NULL)
         j = strlen(serialfile);
     else
         j = strlen(serialfile) + strlen(suffix) + 1;
     if (j >= BSIZE) {
         BIO_printf(bio_err, "file name too long\n");
         goto err;
     }
 
     if (suffix == NULL)
         BUF_strlcpy(buf[0], serialfile, BSIZE);
     else {
 #ifndef OPENSSL_SYS_VMS
         j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, suffix);
 #else
         j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, suffix);
 #endif
     }
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
 #endif
     out = BIO_new(BIO_s_file());
     if (out == NULL) {
         ERR_print_errors(bio_err);
         goto err;
     }
     if (BIO_write_filename(out, buf[0]) <= 0) {
         perror(serialfile);
         goto err;
     }
 
     if ((ai = BN_to_ASN1_INTEGER(serial, NULL)) == NULL) {
         BIO_printf(bio_err, "error converting serial to ASN.1 format\n");
         goto err;
     }
     i2a_ASN1_INTEGER(out, ai);
     BIO_puts(out, "\n");
     ret = 1;
     if (retai) {
         *retai = ai;
         ai = NULL;
     }
  err:
     if (out != NULL)
         BIO_free_all(out);
     if (ai != NULL)
         ASN1_INTEGER_free(ai);
     return (ret);
 }
 
 int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix)
 {
     char buf[5][BSIZE];
     int i, j;
 
     i = strlen(serialfile) + strlen(old_suffix);
     j = strlen(serialfile) + strlen(new_suffix);
     if (i > j)
         j = i;
     if (j + 1 >= BSIZE) {
         BIO_printf(bio_err, "file name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", serialfile, new_suffix);
 #else
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", serialfile, new_suffix);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", serialfile, old_suffix);
 #else
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", serialfile, old_suffix);
 #endif
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
                serialfile, buf[1]);
 #endif
     if (rename(serialfile, buf[1]) < 0 && errno != ENOENT
 #ifdef ENOTDIR
         && errno != ENOTDIR
 #endif
         ) {
         BIO_printf(bio_err,
                    "unable to rename %s to %s\n", serialfile, buf[1]);
         perror("reason");
         goto err;
     }
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n",
                buf[0], serialfile);
 #endif
     if (rename(buf[0], serialfile) < 0) {
         BIO_printf(bio_err,
                    "unable to rename %s to %s\n", buf[0], serialfile);
         perror("reason");
         rename(buf[1], serialfile);
         goto err;
     }
     return 1;
  err:
     return 0;
 }
 
 int rand_serial(BIGNUM *b, ASN1_INTEGER *ai)
 {
     BIGNUM *btmp;
     int ret = 0;
     if (b)
         btmp = b;
     else
         btmp = BN_new();
 
     if (!btmp)
         return 0;
 
     if (!BN_pseudo_rand(btmp, SERIAL_RAND_BITS, 0, 0))
         goto error;
     if (ai && !BN_to_ASN1_INTEGER(btmp, ai))
         goto error;
 
     ret = 1;
 
  error:
 
     if (!b)
         BN_free(btmp);
 
     return ret;
 }
 
 CA_DB *load_index(char *dbfile, DB_ATTR *db_attr)
 {
     CA_DB *retdb = NULL;
     TXT_DB *tmpdb = NULL;
     BIO *in = BIO_new(BIO_s_file());
     CONF *dbattr_conf = NULL;
     char buf[1][BSIZE];
     long errorline = -1;
 
     if (in == NULL) {
         ERR_print_errors(bio_err);
         goto err;
     }
     if (BIO_read_filename(in, dbfile) <= 0) {
         perror(dbfile);
         BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
         goto err;
     }
     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
         goto err;
 
 #ifndef OPENSSL_SYS_VMS
     BIO_snprintf(buf[0], sizeof buf[0], "%s.attr", dbfile);
 #else
     BIO_snprintf(buf[0], sizeof buf[0], "%s-attr", dbfile);
 #endif
     dbattr_conf = NCONF_new(NULL);
     if (NCONF_load(dbattr_conf, buf[0], &errorline) <= 0) {
         if (errorline > 0) {
             BIO_printf(bio_err,
                        "error on line %ld of db attribute file '%s'\n",
                        errorline, buf[0]);
             goto err;
         } else {
             NCONF_free(dbattr_conf);
             dbattr_conf = NULL;
         }
     }
 
     if ((retdb = OPENSSL_malloc(sizeof(CA_DB))) == NULL) {
         fprintf(stderr, "Out of memory\n");
         goto err;
     }
 
     retdb->db = tmpdb;
     tmpdb = NULL;
     if (db_attr)
         retdb->attributes = *db_attr;
     else {
         retdb->attributes.unique_subject = 1;
     }
 
     if (dbattr_conf) {
         char *p = NCONF_get_string(dbattr_conf, NULL, "unique_subject");
         if (p) {
 #ifdef RL_DEBUG
             BIO_printf(bio_err,
                        "DEBUG[load_index]: unique_subject = \"%s\"\n", p);
 #endif
             retdb->attributes.unique_subject = parse_yesno(p, 1);
         }
     }
 
  err:
     if (dbattr_conf)
         NCONF_free(dbattr_conf);
     if (tmpdb)
         TXT_DB_free(tmpdb);
     if (in)
         BIO_free_all(in);
     return retdb;
 }
 
 int index_index(CA_DB *db)
 {
     if (!TXT_DB_create_index(db->db, DB_serial, NULL,
                              LHASH_HASH_FN(index_serial),
                              LHASH_COMP_FN(index_serial))) {
         BIO_printf(bio_err,
                    "error creating serial number index:(%ld,%ld,%ld)\n",
                    db->db->error, db->db->arg1, db->db->arg2);
         return 0;
     }
 
     if (db->attributes.unique_subject
         && !TXT_DB_create_index(db->db, DB_name, index_name_qual,
                                 LHASH_HASH_FN(index_name),
                                 LHASH_COMP_FN(index_name))) {
         BIO_printf(bio_err, "error creating name index:(%ld,%ld,%ld)\n",
                    db->db->error, db->db->arg1, db->db->arg2);
         return 0;
     }
     return 1;
 }
 
 int save_index(const char *dbfile, const char *suffix, CA_DB *db)
 {
     char buf[3][BSIZE];
     BIO *out = BIO_new(BIO_s_file());
     int j;
 
     if (out == NULL) {
         ERR_print_errors(bio_err);
         goto err;
     }
 
     j = strlen(dbfile) + strlen(suffix);
     if (j + 6 >= BSIZE) {
         BIO_printf(bio_err, "file name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr", dbfile);
 #else
     j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr", dbfile);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.attr.%s", dbfile, suffix);
 #else
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-attr-%s", dbfile, suffix);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, suffix);
 #else
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, suffix);
 #endif
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[0]);
 #endif
     if (BIO_write_filename(out, buf[0]) <= 0) {
         perror(dbfile);
         BIO_printf(bio_err, "unable to open '%s'\n", dbfile);
         goto err;
     }
     j = TXT_DB_write(out, db->db);
     if (j <= 0)
         goto err;
 
     BIO_free(out);
 
     out = BIO_new(BIO_s_file());
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: writing \"%s\"\n", buf[1]);
 #endif
     if (BIO_write_filename(out, buf[1]) <= 0) {
         perror(buf[2]);
         BIO_printf(bio_err, "unable to open '%s'\n", buf[2]);
         goto err;
     }
     BIO_printf(out, "unique_subject = %s\n",
                db->attributes.unique_subject ? "yes" : "no");
     BIO_free(out);
 
     return 1;
  err:
     return 0;
 }
 
 int rotate_index(const char *dbfile, const char *new_suffix,
                  const char *old_suffix)
 {
     char buf[5][BSIZE];
     int i, j;
 
     i = strlen(dbfile) + strlen(old_suffix);
     j = strlen(dbfile) + strlen(new_suffix);
     if (i > j)
         j = i;
     if (j + 6 >= BSIZE) {
         BIO_printf(bio_err, "file name too long\n");
         goto err;
     }
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[4], sizeof buf[4], "%s.attr", dbfile);
 #else
     j = BIO_snprintf(buf[4], sizeof buf[4], "%s-attr", dbfile);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[2], sizeof buf[2], "%s.attr.%s", dbfile, new_suffix);
 #else
     j = BIO_snprintf(buf[2], sizeof buf[2], "%s-attr-%s", dbfile, new_suffix);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s.%s", dbfile, new_suffix);
 #else
     j = BIO_snprintf(buf[0], sizeof buf[0], "%s-%s", dbfile, new_suffix);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s.%s", dbfile, old_suffix);
 #else
     j = BIO_snprintf(buf[1], sizeof buf[1], "%s-%s", dbfile, old_suffix);
 #endif
 #ifndef OPENSSL_SYS_VMS
     j = BIO_snprintf(buf[3], sizeof buf[3], "%s.attr.%s", dbfile, old_suffix);
 #else
     j = BIO_snprintf(buf[3], sizeof buf[3], "%s-attr-%s", dbfile, old_suffix);
 #endif
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", dbfile, buf[1]);
 #endif
     if (rename(dbfile, buf[1]) < 0 && errno != ENOENT
 #ifdef ENOTDIR
         && errno != ENOTDIR
 #endif
         ) {
         BIO_printf(bio_err, "unable to rename %s to %s\n", dbfile, buf[1]);
         perror("reason");
         goto err;
     }
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[0], dbfile);
 #endif
     if (rename(buf[0], dbfile) < 0) {
         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[0], dbfile);
         perror("reason");
         rename(buf[1], dbfile);
         goto err;
     }
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[4], buf[3]);
 #endif
     if (rename(buf[4], buf[3]) < 0 && errno != ENOENT
 #ifdef ENOTDIR
         && errno != ENOTDIR
 #endif
         ) {
         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[4], buf[3]);
         perror("reason");
         rename(dbfile, buf[0]);
         rename(buf[1], dbfile);
         goto err;
     }
 #ifdef RL_DEBUG
     BIO_printf(bio_err, "DEBUG: renaming \"%s\" to \"%s\"\n", buf[2], buf[4]);
 #endif
     if (rename(buf[2], buf[4]) < 0) {
         BIO_printf(bio_err, "unable to rename %s to %s\n", buf[2], buf[4]);
         perror("reason");
         rename(buf[3], buf[4]);
         rename(dbfile, buf[0]);
         rename(buf[1], dbfile);
         goto err;
     }
     return 1;
  err:
     return 0;
 }
 
 void free_index(CA_DB *db)
 {
     if (db) {
         if (db->db)
             TXT_DB_free(db->db);
         OPENSSL_free(db);
     }
 }
 
 int parse_yesno(const char *str, int def)
 {
     int ret = def;
     if (str) {
         switch (*str) {
         case 'f':              /* false */
         case 'F':              /* FALSE */
         case 'n':              /* no */
         case 'N':              /* NO */
         case '0':              /* 0 */
             ret = 0;
             break;
         case 't':              /* true */
         case 'T':              /* TRUE */
         case 'y':              /* yes */
         case 'Y':              /* YES */
         case '1':              /* 1 */
             ret = 1;
             break;
         default:
             ret = def;
             break;
         }
     }
     return ret;
 }
 
 /*
  * subject is expected to be in the format /type0=value0/type1=value1/type2=...
  * where characters may be escaped by \
  */
 X509_NAME *parse_name(char *subject, long chtype, int multirdn)
 {
     size_t buflen = strlen(subject) + 1; /* to copy the types and values
                                           * into. due to escaping, the copy
                                           * can only become shorter */
     char *buf = OPENSSL_malloc(buflen);
     size_t max_ne = buflen / 2 + 1; /* maximum number of name elements */
     char **ne_types = OPENSSL_malloc(max_ne * sizeof(char *));
     char **ne_values = OPENSSL_malloc(max_ne * sizeof(char *));
     int *mval = OPENSSL_malloc(max_ne * sizeof(int));
 
     char *sp = subject, *bp = buf;
     int i, ne_num = 0;
 
     X509_NAME *n = NULL;
     int nid;
 
     if (!buf || !ne_types || !ne_values || !mval) {
         BIO_printf(bio_err, "malloc error\n");
         goto error;
     }
 
     if (*subject != '/') {
         BIO_printf(bio_err, "Subject does not start with '/'.\n");
         goto error;
     }
     sp++;                       /* skip leading / */
 
     /* no multivalued RDN by default */
     mval[ne_num] = 0;
 
     while (*sp) {
         /* collect type */
         ne_types[ne_num] = bp;
         while (*sp) {
             if (*sp == '\\') {  /* is there anything to escape in the
                                  * type...? */
                 if (*++sp)
                     *bp++ = *sp++;
                 else {
                     BIO_printf(bio_err,
                                "escape character at end of string\n");
                     goto error;
                 }
             } else if (*sp == '=') {
                 sp++;
                 *bp++ = '\0';
                 break;
             } else
                 *bp++ = *sp++;
         }
         if (!*sp) {
             BIO_printf(bio_err,
                        "end of string encountered while processing type of subject name element #%d\n",
                        ne_num);
             goto error;
         }
         ne_values[ne_num] = bp;
         while (*sp) {
             if (*sp == '\\') {
                 if (*++sp)
                     *bp++ = *sp++;
                 else {
                     BIO_printf(bio_err,
                                "escape character at end of string\n");
                     goto error;
                 }
             } else if (*sp == '/') {
                 sp++;
                 /* no multivalued RDN by default */
                 mval[ne_num + 1] = 0;
                 break;
             } else if (*sp == '+' && multirdn) {
                 /*
                  * a not escaped + signals a mutlivalued RDN
                  */
                 sp++;
                 mval[ne_num + 1] = -1;
                 break;
             } else
                 *bp++ = *sp++;
         }
         *bp++ = '\0';
         ne_num++;
     }
 
     if (!(n = X509_NAME_new()))
         goto error;
 
     for (i = 0; i < ne_num; i++) {
         if ((nid = OBJ_txt2nid(ne_types[i])) == NID_undef) {
             BIO_printf(bio_err,
                        "Subject Attribute %s has no known NID, skipped\n",
                        ne_types[i]);
             continue;
         }
 
         if (!*ne_values[i]) {
             BIO_printf(bio_err,
                        "No value provided for Subject Attribute %s, skipped\n",
                        ne_types[i]);
             continue;
         }
 
         if (!X509_NAME_add_entry_by_NID
             (n, nid, chtype, (unsigned char *)ne_values[i], -1, -1, mval[i]))
             goto error;
     }
 
     OPENSSL_free(ne_values);
     OPENSSL_free(ne_types);
     OPENSSL_free(buf);
     OPENSSL_free(mval);
     return n;
 
  error:
     X509_NAME_free(n);
     if (ne_values)
         OPENSSL_free(ne_values);
     if (ne_types)
         OPENSSL_free(ne_types);
     if (mval)
         OPENSSL_free(mval);
     if (buf)
         OPENSSL_free(buf);
     return NULL;
 }
 
 int args_verify(char ***pargs, int *pargc,
                 int *badarg, BIO *err, X509_VERIFY_PARAM **pm)
 {
     ASN1_OBJECT *otmp = NULL;
     unsigned long flags = 0;
     int i;
     int purpose = 0, depth = -1;
     char **oldargs = *pargs;
     char *arg = **pargs, *argn = (*pargs)[1];
     time_t at_time = 0;
     if (!strcmp(arg, "-policy")) {
         if (!argn)
             *badarg = 1;
         else {
             otmp = OBJ_txt2obj(argn, 0);
             if (!otmp) {
                 BIO_printf(err, "Invalid Policy \"%s\"\n", argn);
                 *badarg = 1;
             }
         }
         (*pargs)++;
     } else if (strcmp(arg, "-purpose") == 0) {
         X509_PURPOSE *xptmp;
         if (!argn)
             *badarg = 1;
         else {
             i = X509_PURPOSE_get_by_sname(argn);
             if (i < 0) {
                 BIO_printf(err, "unrecognized purpose\n");
                 *badarg = 1;
             } else {
                 xptmp = X509_PURPOSE_get0(i);
                 purpose = X509_PURPOSE_get_id(xptmp);
             }
         }
         (*pargs)++;
     } else if (strcmp(arg, "-verify_depth") == 0) {
         if (!argn)
             *badarg = 1;
         else {
             depth = atoi(argn);
             if (depth < 0) {
                 BIO_printf(err, "invalid depth\n");
                 *badarg = 1;
             }
         }
         (*pargs)++;
     } else if (strcmp(arg, "-attime") == 0) {
         if (!argn)
             *badarg = 1;
         else {
             long timestamp;
             /*
              * interpret the -attime argument as seconds since Epoch
              */
             if (sscanf(argn, "%li", &timestamp) != 1) {
                 BIO_printf(bio_err, "Error parsing timestamp %s\n", argn);
                 *badarg = 1;
             }
             /* on some platforms time_t may be a float */
             at_time = (time_t)timestamp;
         }
         (*pargs)++;
     } else if (!strcmp(arg, "-ignore_critical"))
         flags |= X509_V_FLAG_IGNORE_CRITICAL;
     else if (!strcmp(arg, "-issuer_checks"))
         flags |= X509_V_FLAG_CB_ISSUER_CHECK;
     else if (!strcmp(arg, "-crl_check"))
         flags |= X509_V_FLAG_CRL_CHECK;
     else if (!strcmp(arg, "-crl_check_all"))
         flags |= X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL;
     else if (!strcmp(arg, "-policy_check"))
         flags |= X509_V_FLAG_POLICY_CHECK;
     else if (!strcmp(arg, "-explicit_policy"))
         flags |= X509_V_FLAG_EXPLICIT_POLICY;
     else if (!strcmp(arg, "-inhibit_any"))
         flags |= X509_V_FLAG_INHIBIT_ANY;
     else if (!strcmp(arg, "-inhibit_map"))
         flags |= X509_V_FLAG_INHIBIT_MAP;
     else if (!strcmp(arg, "-x509_strict"))
         flags |= X509_V_FLAG_X509_STRICT;
     else if (!strcmp(arg, "-extended_crl"))
         flags |= X509_V_FLAG_EXTENDED_CRL_SUPPORT;
     else if (!strcmp(arg, "-use_deltas"))
         flags |= X509_V_FLAG_USE_DELTAS;
     else if (!strcmp(arg, "-policy_print"))
         flags |= X509_V_FLAG_NOTIFY_POLICY;
     else if (!strcmp(arg, "-check_ss_sig"))
         flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
     else if (!strcmp(arg, "-no_alt_chains"))
         flags |= X509_V_FLAG_NO_ALT_CHAINS;
+    else if (!strcmp(arg, "-allow_proxy_certs"))
+        flags |= X509_V_FLAG_ALLOW_PROXY_CERTS;
     else
         return 0;
 
     if (*badarg) {
         if (*pm)
             X509_VERIFY_PARAM_free(*pm);
         *pm = NULL;
         goto end;
     }
 
     if (!*pm && !(*pm = X509_VERIFY_PARAM_new())) {
         *badarg = 1;
         goto end;
     }
 
     if (otmp)
         X509_VERIFY_PARAM_add0_policy(*pm, otmp);
     if (flags)
         X509_VERIFY_PARAM_set_flags(*pm, flags);
 
     if (purpose)
         X509_VERIFY_PARAM_set_purpose(*pm, purpose);
 
     if (depth >= 0)
         X509_VERIFY_PARAM_set_depth(*pm, depth);
 
     if (at_time)
         X509_VERIFY_PARAM_set_time(*pm, at_time);
 
  end:
 
     (*pargs)++;
 
     if (pargc)
         *pargc -= *pargs - oldargs;
 
     return 1;
 
 }
 
 /*
  * Read whole contents of a BIO into an allocated memory buffer and return
  * it.
  */
 
 int bio_to_mem(unsigned char **out, int maxlen, BIO *in)
 {
     BIO *mem;
     int len, ret;
     unsigned char tbuf[1024];
     mem = BIO_new(BIO_s_mem());
     if (!mem)
         return -1;
     for (;;) {
         if ((maxlen != -1) && maxlen < 1024)
             len = maxlen;
         else
             len = 1024;
         len = BIO_read(in, tbuf, len);
         if (len <= 0)
             break;
         if (BIO_write(mem, tbuf, len) != len) {
             BIO_free(mem);
             return -1;
         }
         maxlen -= len;
 
         if (maxlen == 0)
             break;
     }
     ret = BIO_get_mem_data(mem, (char **)out);
     BIO_set_flags(mem, BIO_FLAGS_MEM_RDONLY);
     BIO_free(mem);
     return ret;
 }
 
 int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value)
 {
     int rv;
     char *stmp, *vtmp = NULL;
     stmp = BUF_strdup(value);
     if (!stmp)
         return -1;
     vtmp = strchr(stmp, ':');
     if (vtmp) {
         *vtmp = 0;
         vtmp++;
     }
     rv = EVP_PKEY_CTX_ctrl_str(ctx, stmp, vtmp);
     OPENSSL_free(stmp);
     return rv;
 }
 
 static void nodes_print(BIO *out, const char *name,
                         STACK_OF(X509_POLICY_NODE) *nodes)
 {
     X509_POLICY_NODE *node;
     int i;
     BIO_printf(out, "%s Policies:", name);
     if (nodes) {
         BIO_puts(out, "\n");
         for (i = 0; i < sk_X509_POLICY_NODE_num(nodes); i++) {
             node = sk_X509_POLICY_NODE_value(nodes, i);
             X509_POLICY_NODE_print(out, node, 2);
         }
     } else
         BIO_puts(out, " <empty>\n");
 }
 
 void policies_print(BIO *out, X509_STORE_CTX *ctx)
 {
     X509_POLICY_TREE *tree;
     int explicit_policy;
     int free_out = 0;
     if (out == NULL) {
         out = BIO_new_fp(stderr, BIO_NOCLOSE);
         free_out = 1;
     }
     tree = X509_STORE_CTX_get0_policy_tree(ctx);
     explicit_policy = X509_STORE_CTX_get_explicit_policy(ctx);
 
     BIO_printf(out, "Require explicit Policy: %s\n",
                explicit_policy ? "True" : "False");
 
     nodes_print(out, "Authority", X509_policy_tree_get0_policies(tree));
     nodes_print(out, "User", X509_policy_tree_get0_user_policies(tree));
     if (free_out)
         BIO_free(out);
 }
 
 #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
 
 static JPAKE_CTX *jpake_init(const char *us, const char *them,
                              const char *secret)
 {
     BIGNUM *p = NULL;
     BIGNUM *g = NULL;
     BIGNUM *q = NULL;
     BIGNUM *bnsecret = BN_new();
     JPAKE_CTX *ctx;
 
     /* Use a safe prime for p (that we found earlier) */
     BN_hex2bn(&p,
               "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F");
     g = BN_new();
     BN_set_word(g, 2);
     q = BN_new();
     BN_rshift1(q, p);
 
     BN_bin2bn((const unsigned char *)secret, strlen(secret), bnsecret);
 
     ctx = JPAKE_CTX_new(us, them, p, g, q, bnsecret);
     BN_free(bnsecret);
     BN_free(q);
     BN_free(g);
     BN_free(p);
 
     return ctx;
 }
 
 static void jpake_send_part(BIO *conn, const JPAKE_STEP_PART *p)
 {
     BN_print(conn, p->gx);
     BIO_puts(conn, "\n");
     BN_print(conn, p->zkpx.gr);
     BIO_puts(conn, "\n");
     BN_print(conn, p->zkpx.b);
     BIO_puts(conn, "\n");
 }
 
 static void jpake_send_step1(BIO *bconn, JPAKE_CTX *ctx)
 {
     JPAKE_STEP1 s1;
 
     JPAKE_STEP1_init(&s1);
     JPAKE_STEP1_generate(&s1, ctx);
     jpake_send_part(bconn, &s1.p1);
     jpake_send_part(bconn, &s1.p2);
     (void)BIO_flush(bconn);
     JPAKE_STEP1_release(&s1);
 }
 
 static void jpake_send_step2(BIO *bconn, JPAKE_CTX *ctx)
 {
     JPAKE_STEP2 s2;
 
     JPAKE_STEP2_init(&s2);
     JPAKE_STEP2_generate(&s2, ctx);
     jpake_send_part(bconn, &s2);
     (void)BIO_flush(bconn);
     JPAKE_STEP2_release(&s2);
 }
 
 static void jpake_send_step3a(BIO *bconn, JPAKE_CTX *ctx)
 {
     JPAKE_STEP3A s3a;
 
     JPAKE_STEP3A_init(&s3a);
     JPAKE_STEP3A_generate(&s3a, ctx);
     BIO_write(bconn, s3a.hhk, sizeof s3a.hhk);
     (void)BIO_flush(bconn);
     JPAKE_STEP3A_release(&s3a);
 }
 
 static void jpake_send_step3b(BIO *bconn, JPAKE_CTX *ctx)
 {
     JPAKE_STEP3B s3b;
 
     JPAKE_STEP3B_init(&s3b);
     JPAKE_STEP3B_generate(&s3b, ctx);
     BIO_write(bconn, s3b.hk, sizeof s3b.hk);
     (void)BIO_flush(bconn);
     JPAKE_STEP3B_release(&s3b);
 }
 
 static void readbn(BIGNUM **bn, BIO *bconn)
 {
     char buf[10240];
     int l;
 
     l = BIO_gets(bconn, buf, sizeof buf);
     assert(l > 0);
     assert(buf[l - 1] == '\n');
     buf[l - 1] = '\0';
     BN_hex2bn(bn, buf);
 }
 
 static void jpake_receive_part(JPAKE_STEP_PART *p, BIO *bconn)
 {
     readbn(&p->gx, bconn);
     readbn(&p->zkpx.gr, bconn);
     readbn(&p->zkpx.b, bconn);
 }
 
 static void jpake_receive_step1(JPAKE_CTX *ctx, BIO *bconn)
 {
     JPAKE_STEP1 s1;
 
     JPAKE_STEP1_init(&s1);
     jpake_receive_part(&s1.p1, bconn);
     jpake_receive_part(&s1.p2, bconn);
     if (!JPAKE_STEP1_process(ctx, &s1)) {
         ERR_print_errors(bio_err);
         exit(1);
     }
     JPAKE_STEP1_release(&s1);
 }
 
 static void jpake_receive_step2(JPAKE_CTX *ctx, BIO *bconn)
 {
     JPAKE_STEP2 s2;
 
     JPAKE_STEP2_init(&s2);
     jpake_receive_part(&s2, bconn);
     if (!JPAKE_STEP2_process(ctx, &s2)) {
         ERR_print_errors(bio_err);
         exit(1);
     }
     JPAKE_STEP2_release(&s2);
 }
 
 static void jpake_receive_step3a(JPAKE_CTX *ctx, BIO *bconn)
 {
     JPAKE_STEP3A s3a;
     int l;
 
     JPAKE_STEP3A_init(&s3a);
     l = BIO_read(bconn, s3a.hhk, sizeof s3a.hhk);
     assert(l == sizeof s3a.hhk);
     if (!JPAKE_STEP3A_process(ctx, &s3a)) {
         ERR_print_errors(bio_err);
         exit(1);
     }
     JPAKE_STEP3A_release(&s3a);
 }
 
 static void jpake_receive_step3b(JPAKE_CTX *ctx, BIO *bconn)
 {
     JPAKE_STEP3B s3b;
     int l;
 
     JPAKE_STEP3B_init(&s3b);
     l = BIO_read(bconn, s3b.hk, sizeof s3b.hk);
     assert(l == sizeof s3b.hk);
     if (!JPAKE_STEP3B_process(ctx, &s3b)) {
         ERR_print_errors(bio_err);
         exit(1);
     }
     JPAKE_STEP3B_release(&s3b);
 }
 
 void jpake_client_auth(BIO *out, BIO *conn, const char *secret)
 {
     JPAKE_CTX *ctx;
     BIO *bconn;
 
     BIO_puts(out, "Authenticating with JPAKE\n");
 
     ctx = jpake_init("client", "server", secret);
 
     bconn = BIO_new(BIO_f_buffer());
     BIO_push(bconn, conn);
 
     jpake_send_step1(bconn, ctx);
     jpake_receive_step1(ctx, bconn);
     jpake_send_step2(bconn, ctx);
     jpake_receive_step2(ctx, bconn);
     jpake_send_step3a(bconn, ctx);
     jpake_receive_step3b(ctx, bconn);
 
     BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
 
     psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
 
     BIO_pop(bconn);
     BIO_free(bconn);
 
     JPAKE_CTX_free(ctx);
 }
 
 void jpake_server_auth(BIO *out, BIO *conn, const char *secret)
 {
     JPAKE_CTX *ctx;
     BIO *bconn;
 
     BIO_puts(out, "Authenticating with JPAKE\n");
 
     ctx = jpake_init("server", "client", secret);
 
     bconn = BIO_new(BIO_f_buffer());
     BIO_push(bconn, conn);
 
     jpake_receive_step1(ctx, bconn);
     jpake_send_step1(bconn, ctx);
     jpake_receive_step2(ctx, bconn);
     jpake_send_step2(bconn, ctx);
     jpake_receive_step3a(ctx, bconn);
     jpake_send_step3b(bconn, ctx);
 
     BIO_puts(out, "JPAKE authentication succeeded, setting PSK\n");
 
     psk_key = BN_bn2hex(JPAKE_get_shared_key(ctx));
 
     BIO_pop(bconn);
     BIO_free(bconn);
 
     JPAKE_CTX_free(ctx);
 }
 
 #endif
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
 /*-
  * next_protos_parse parses a comma separated list of strings into a string
  * in a format suitable for passing to SSL_CTX_set_next_protos_advertised.
  *   outlen: (output) set to the length of the resulting buffer on success.
  *   err: (maybe NULL) on failure, an error message line is written to this BIO.
  *   in: a NUL termianted string like "abc,def,ghi"
  *
  *   returns: a malloced buffer or NULL on failure.
  */
 unsigned char *next_protos_parse(unsigned short *outlen, const char *in)
 {
     size_t len;
     unsigned char *out;
     size_t i, start = 0;
 
     len = strlen(in);
     if (len >= 65535)
         return NULL;
 
     out = OPENSSL_malloc(strlen(in) + 1);
     if (!out)
         return NULL;
 
     for (i = 0; i <= len; ++i) {
         if (i == len || in[i] == ',') {
             if (i - start > 255) {
                 OPENSSL_free(out);
                 return NULL;
             }
             out[start] = i - start;
             start = i + 1;
         } else
             out[i + 1] = in[i];
     }
 
     *outlen = len + 1;
     return out;
 }
 #endif                          /* !OPENSSL_NO_TLSEXT &&
                                  * !OPENSSL_NO_NEXTPROTONEG */
 
 /*
  * Platform-specific sections
  */
 #if defined(_WIN32)
 # ifdef fileno
 #  undef fileno
 #  define fileno(a) (int)_fileno(a)
 # endif
 
 # include <windows.h>
 # include <tchar.h>
 
 static int WIN32_rename(const char *from, const char *to)
 {
     TCHAR *tfrom = NULL, *tto;
     DWORD err;
     int ret = 0;
 
     if (sizeof(TCHAR) == 1) {
         tfrom = (TCHAR *)from;
         tto = (TCHAR *)to;
     } else {                    /* UNICODE path */
 
         size_t i, flen = strlen(from) + 1, tlen = strlen(to) + 1;
         tfrom = (TCHAR *)malloc(sizeof(TCHAR) * (flen + tlen));
         if (tfrom == NULL)
             goto err;
         tto = tfrom + flen;
 # if !defined(_WIN32_WCE) || _WIN32_WCE>=101
         if (!MultiByteToWideChar(CP_ACP, 0, from, flen, (WCHAR *)tfrom, flen))
 # endif
             for (i = 0; i < flen; i++)
                 tfrom[i] = (TCHAR)from[i];
 # if !defined(_WIN32_WCE) || _WIN32_WCE>=101
         if (!MultiByteToWideChar(CP_ACP, 0, to, tlen, (WCHAR *)tto, tlen))
 # endif
             for (i = 0; i < tlen; i++)
                 tto[i] = (TCHAR)to[i];
     }
 
     if (MoveFile(tfrom, tto))
         goto ok;
     err = GetLastError();
     if (err == ERROR_ALREADY_EXISTS || err == ERROR_FILE_EXISTS) {
         if (DeleteFile(tto) && MoveFile(tfrom, tto))
             goto ok;
         err = GetLastError();
     }
     if (err == ERROR_FILE_NOT_FOUND || err == ERROR_PATH_NOT_FOUND)
         errno = ENOENT;
     else if (err == ERROR_ACCESS_DENIED)
         errno = EACCES;
     else
         errno = EINVAL;         /* we could map more codes... */
  err:
     ret = -1;
  ok:
     if (tfrom != NULL && tfrom != (TCHAR *)from)
         free(tfrom);
     return ret;
 }
 #endif
 
 /* app_tminterval section */
 #if defined(_WIN32)
 double app_tminterval(int stop, int usertime)
 {
     FILETIME now;
     double ret = 0;
     static ULARGE_INTEGER tmstart;
     static int warning = 1;
 # ifdef _WIN32_WINNT
     static HANDLE proc = NULL;
 
     if (proc == NULL) {
         if (check_winnt())
             proc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE,
                                GetCurrentProcessId());
         if (proc == NULL)
             proc = (HANDLE) - 1;
     }
 
     if (usertime && proc != (HANDLE) - 1) {
         FILETIME junk;
         GetProcessTimes(proc, &junk, &junk, &junk, &now);
     } else
 # endif
     {
         SYSTEMTIME systime;
 
         if (usertime && warning) {
             BIO_printf(bio_err, "To get meaningful results, run "
                        "this program on idle system.\n");
             warning = 0;
         }
         GetSystemTime(&systime);
         SystemTimeToFileTime(&systime, &now);
     }
 
     if (stop == TM_START) {
         tmstart.u.LowPart = now.dwLowDateTime;
         tmstart.u.HighPart = now.dwHighDateTime;
     } else {
         ULARGE_INTEGER tmstop;
 
         tmstop.u.LowPart = now.dwLowDateTime;
         tmstop.u.HighPart = now.dwHighDateTime;
 
         ret = (__int64)(tmstop.QuadPart - tmstart.QuadPart) * 1e-7;
     }
 
     return (ret);
 }
 
 #elif defined(OPENSSL_SYS_NETWARE)
 # include <time.h>
 
 double app_tminterval(int stop, int usertime)
 {
     double ret = 0;
     static clock_t tmstart;
     static int warning = 1;
 
     if (usertime && warning) {
         BIO_printf(bio_err, "To get meaningful results, run "
                    "this program on idle system.\n");
         warning = 0;
     }
 
     if (stop == TM_START)
         tmstart = clock();
     else
         ret = (clock() - tmstart) / (double)CLOCKS_PER_SEC;
 
     return (ret);
 }
 
 #elif defined(OPENSSL_SYSTEM_VXWORKS)
 # include <time.h>
 
 double app_tminterval(int stop, int usertime)
 {
     double ret = 0;
 # ifdef CLOCK_REALTIME
     static struct timespec tmstart;
     struct timespec now;
 # else
     static unsigned long tmstart;
     unsigned long now;
 # endif
     static int warning = 1;
 
     if (usertime && warning) {
         BIO_printf(bio_err, "To get meaningful results, run "
                    "this program on idle system.\n");
         warning = 0;
     }
 # ifdef CLOCK_REALTIME
     clock_gettime(CLOCK_REALTIME, &now);
     if (stop == TM_START)
         tmstart = now;
     else
         ret = ((now.tv_sec + now.tv_nsec * 1e-9)
                - (tmstart.tv_sec + tmstart.tv_nsec * 1e-9));
 # else
     now = tickGet();
     if (stop == TM_START)
         tmstart = now;
     else
         ret = (now - tmstart) / (double)sysClkRateGet();
 # endif
     return (ret);
 }
 
 #elif defined(OPENSSL_SYSTEM_VMS)
 # include <time.h>
 # include <times.h>
 
 double app_tminterval(int stop, int usertime)
 {
     static clock_t tmstart;
     double ret = 0;
     clock_t now;
 # ifdef __TMS
     struct tms rus;
 
     now = times(&rus);
     if (usertime)
         now = rus.tms_utime;
 # else
     if (usertime)
         now = clock();          /* sum of user and kernel times */
     else {
         struct timeval tv;
         gettimeofday(&tv, NULL);
         now = (clock_t)((unsigned long long)tv.tv_sec * CLK_TCK +
                         (unsigned long long)tv.tv_usec * (1000000 / CLK_TCK)
             );
     }
 # endif
     if (stop == TM_START)
         tmstart = now;
     else
         ret = (now - tmstart) / (double)(CLK_TCK);
 
     return (ret);
 }
 
 #elif defined(_SC_CLK_TCK)      /* by means of unistd.h */
 # include <sys/times.h>
 
 double app_tminterval(int stop, int usertime)
 {
     double ret = 0;
     struct tms rus;
     clock_t now = times(&rus);
     static clock_t tmstart;
 
     if (usertime)
         now = rus.tms_utime;
 
     if (stop == TM_START)
         tmstart = now;
     else {
         long int tck = sysconf(_SC_CLK_TCK);
         ret = (now - tmstart) / (double)tck;
     }
 
     return (ret);
 }
 
 #else
 # include <sys/time.h>
 # include <sys/resource.h>
 
 double app_tminterval(int stop, int usertime)
 {
     double ret = 0;
     struct rusage rus;
     struct timeval now;
     static struct timeval tmstart;
 
     if (usertime)
         getrusage(RUSAGE_SELF, &rus), now = rus.ru_utime;
     else
         gettimeofday(&now, NULL);
 
     if (stop == TM_START)
         tmstart = now;
     else
         ret = ((now.tv_sec + now.tv_usec * 1e-6)
                - (tmstart.tv_sec + tmstart.tv_usec * 1e-6));
 
     return ret;
 }
 #endif
 
 /* app_isdir section */
 #ifdef _WIN32
 int app_isdir(const char *name)
 {
     HANDLE hList;
     WIN32_FIND_DATA FileData;
 # if defined(UNICODE) || defined(_UNICODE)
     size_t i, len_0 = strlen(name) + 1;
 
     if (len_0 > sizeof(FileData.cFileName) / sizeof(FileData.cFileName[0]))
         return -1;
 
 #  if !defined(_WIN32_WCE) || _WIN32_WCE>=101
     if (!MultiByteToWideChar
         (CP_ACP, 0, name, len_0, FileData.cFileName, len_0))
 #  endif
         for (i = 0; i < len_0; i++)
             FileData.cFileName[i] = (WCHAR)name[i];
 
     hList = FindFirstFile(FileData.cFileName, &FileData);
 # else
     hList = FindFirstFile(name, &FileData);
 # endif
     if (hList == INVALID_HANDLE_VALUE)
         return -1;
     FindClose(hList);
     return ((FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0);
 }
 #else
 # include <sys/stat.h>
 # ifndef S_ISDIR
 #  if defined(_S_IFMT) && defined(_S_IFDIR)
 #   define S_ISDIR(a)   (((a) & _S_IFMT) == _S_IFDIR)
 #  else
 #   define S_ISDIR(a)   (((a) & S_IFMT) == S_IFDIR)
 #  endif
 # endif
 
 int app_isdir(const char *name)
 {
 # if defined(S_ISDIR)
     struct stat st;
 
     if (stat(name, &st) == 0)
         return S_ISDIR(st.st_mode);
     else
         return -1;
 # else
     return -1;
 # endif
 }
 #endif
 
 /* raw_read|write section */
 #if defined(_WIN32) && defined(STD_INPUT_HANDLE)
 int raw_read_stdin(void *buf, int siz)
 {
     DWORD n;
     if (ReadFile(GetStdHandle(STD_INPUT_HANDLE), buf, siz, &n, NULL))
         return (n);
     else
         return (-1);
 }
 #else
 int raw_read_stdin(void *buf, int siz)
 {
     return read(fileno(stdin), buf, siz);
 }
 #endif
 
 #if defined(_WIN32) && defined(STD_OUTPUT_HANDLE)
 int raw_write_stdout(const void *buf, int siz)
 {
     DWORD n;
     if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buf, siz, &n, NULL))
         return (n);
     else
         return (-1);
 }
 #else
 int raw_write_stdout(const void *buf, int siz)
 {
     return write(fileno(stdout), buf, siz);
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/apps/enc.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/apps/enc.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/apps/enc.c	(revision 306191)
@@ -1,715 +1,715 @@
 /* apps/enc.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.]
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/rand.h>
 #include <openssl/pem.h>
 #ifndef OPENSSL_NO_COMP
 # include <openssl/comp.h>
 #endif
 #include <ctype.h>
 
 int set_hex(char *in, unsigned char *out, int size);
 #undef SIZE
 #undef BSIZE
 #undef PROG
 
 #define SIZE    (512)
 #define BSIZE   (8*1024)
 #define PROG    enc_main
 
 static void show_ciphers(const OBJ_NAME *name, void *bio_)
 {
     BIO *bio = bio_;
     static int n;
 
     if (!islower((unsigned char)*name->name))
         return;
 
     BIO_printf(bio, "-%-25s", name->name);
     if (++n == 3) {
         BIO_printf(bio, "\n");
         n = 0;
     } else
         BIO_printf(bio, " ");
 }
 
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
 {
     static const char magic[] = "Salted__";
     char mbuf[sizeof magic - 1];
     char *strbuf = NULL;
     unsigned char *buff = NULL, *bufsize = NULL;
     int bsize = BSIZE, verbose = 0;
     int ret = 1, inl;
     int nopad = 0;
     unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
     unsigned char salt[PKCS5_SALT_LEN];
     char *str = NULL, *passarg = NULL, *pass = NULL;
     char *hkey = NULL, *hiv = NULL, *hsalt = NULL;
     char *md = NULL;
     int enc = 1, printkey = 0, i, base64 = 0;
 #ifdef ZLIB
     int do_zlib = 0;
     BIO *bzl = NULL;
 #endif
     int debug = 0, olb64 = 0, nosalt = 0;
     const EVP_CIPHER *cipher = NULL, *c;
     EVP_CIPHER_CTX *ctx = NULL;
     char *inf = NULL, *outf = NULL;
     BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL, *rbio =
         NULL, *wbio = NULL;
 #define PROG_NAME_SIZE  39
     char pname[PROG_NAME_SIZE + 1];
 #ifndef OPENSSL_NO_ENGINE
     char *engine = NULL;
 #endif
     const EVP_MD *dgst = NULL;
     int non_fips_allow = 0;
 
     apps_startup();
 
     if (bio_err == NULL)
         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
             BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
 
     if (!load_config(bio_err, NULL))
         goto end;
 
     /* first check the program name */
     program_name(argv[0], pname, sizeof pname);
     if (strcmp(pname, "base64") == 0)
         base64 = 1;
 #ifdef ZLIB
     if (strcmp(pname, "zlib") == 0)
         do_zlib = 1;
 #endif
 
     cipher = EVP_get_cipherbyname(pname);
 #ifdef ZLIB
     if (!do_zlib && !base64 && (cipher == NULL)
         && (strcmp(pname, "enc") != 0))
 #else
     if (!base64 && (cipher == NULL) && (strcmp(pname, "enc") != 0))
 #endif
     {
         BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
         goto bad;
     }
 
     argc--;
     argv++;
     while (argc >= 1) {
         if (strcmp(*argv, "-e") == 0)
             enc = 1;
         else if (strcmp(*argv, "-in") == 0) {
             if (--argc < 1)
                 goto bad;
             inf = *(++argv);
         } else if (strcmp(*argv, "-out") == 0) {
             if (--argc < 1)
                 goto bad;
             outf = *(++argv);
         } else if (strcmp(*argv, "-pass") == 0) {
             if (--argc < 1)
                 goto bad;
             passarg = *(++argv);
         }
 #ifndef OPENSSL_NO_ENGINE
         else if (strcmp(*argv, "-engine") == 0) {
             if (--argc < 1)
                 goto bad;
             engine = *(++argv);
         }
 #endif
         else if (strcmp(*argv, "-d") == 0)
             enc = 0;
         else if (strcmp(*argv, "-p") == 0)
             printkey = 1;
         else if (strcmp(*argv, "-v") == 0)
             verbose = 1;
         else if (strcmp(*argv, "-nopad") == 0)
             nopad = 1;
         else if (strcmp(*argv, "-salt") == 0)
             nosalt = 0;
         else if (strcmp(*argv, "-nosalt") == 0)
             nosalt = 1;
         else if (strcmp(*argv, "-debug") == 0)
             debug = 1;
         else if (strcmp(*argv, "-P") == 0)
             printkey = 2;
         else if (strcmp(*argv, "-A") == 0)
             olb64 = 1;
         else if (strcmp(*argv, "-a") == 0)
             base64 = 1;
         else if (strcmp(*argv, "-base64") == 0)
             base64 = 1;
 #ifdef ZLIB
         else if (strcmp(*argv, "-z") == 0)
             do_zlib = 1;
 #endif
         else if (strcmp(*argv, "-bufsize") == 0) {
             if (--argc < 1)
                 goto bad;
             bufsize = (unsigned char *)*(++argv);
         } else if (strcmp(*argv, "-k") == 0) {
             if (--argc < 1)
                 goto bad;
             str = *(++argv);
         } else if (strcmp(*argv, "-kfile") == 0) {
             static char buf[128];
             FILE *infile;
             char *file;
 
             if (--argc < 1)
                 goto bad;
             file = *(++argv);
             infile = fopen(file, "r");
             if (infile == NULL) {
                 BIO_printf(bio_err, "unable to read key from '%s'\n", file);
                 goto bad;
             }
             buf[0] = '\0';
             if (!fgets(buf, sizeof buf, infile)) {
                 BIO_printf(bio_err, "unable to read key from '%s'\n", file);
                 goto bad;
             }
             fclose(infile);
             i = strlen(buf);
             if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
                 buf[--i] = '\0';
             if ((i > 0) && ((buf[i - 1] == '\n') || (buf[i - 1] == '\r')))
                 buf[--i] = '\0';
             if (i < 1) {
                 BIO_printf(bio_err, "zero length password\n");
                 goto bad;
             }
             str = buf;
         } else if (strcmp(*argv, "-K") == 0) {
             if (--argc < 1)
                 goto bad;
             hkey = *(++argv);
         } else if (strcmp(*argv, "-S") == 0) {
             if (--argc < 1)
                 goto bad;
             hsalt = *(++argv);
         } else if (strcmp(*argv, "-iv") == 0) {
             if (--argc < 1)
                 goto bad;
             hiv = *(++argv);
         } else if (strcmp(*argv, "-md") == 0) {
             if (--argc < 1)
                 goto bad;
             md = *(++argv);
         } else if (strcmp(*argv, "-non-fips-allow") == 0)
             non_fips_allow = 1;
         else if ((argv[0][0] == '-') &&
                  ((c = EVP_get_cipherbyname(&(argv[0][1]))) != NULL)) {
             cipher = c;
         } else if (strcmp(*argv, "-none") == 0)
             cipher = NULL;
         else {
             BIO_printf(bio_err, "unknown option '%s'\n", *argv);
  bad:
             BIO_printf(bio_err, "options are\n");
             BIO_printf(bio_err, "%-14s input file\n", "-in <file>");
             BIO_printf(bio_err, "%-14s output file\n", "-out <file>");
             BIO_printf(bio_err, "%-14s pass phrase source\n", "-pass <arg>");
             BIO_printf(bio_err, "%-14s encrypt\n", "-e");
             BIO_printf(bio_err, "%-14s decrypt\n", "-d");
             BIO_printf(bio_err,
                        "%-14s base64 encode/decode, depending on encryption flag\n",
                        "-a/-base64");
             BIO_printf(bio_err, "%-14s passphrase is the next argument\n",
                        "-k");
             BIO_printf(bio_err,
                        "%-14s passphrase is the first line of the file argument\n",
                        "-kfile");
             BIO_printf(bio_err,
                        "%-14s the next argument is the md to use to create a key\n",
                        "-md");
             BIO_printf(bio_err,
                        "%-14s   from a passphrase.  One of md2, md5, sha or sha1\n",
                        "");
             BIO_printf(bio_err, "%-14s salt in hex is the next argument\n",
                        "-S");
             BIO_printf(bio_err, "%-14s key/iv in hex is the next argument\n",
                        "-K/-iv");
             BIO_printf(bio_err, "%-14s print the iv/key (then exit if -P)\n",
                        "-[pP]");
             BIO_printf(bio_err, "%-14s buffer size\n", "-bufsize <n>");
             BIO_printf(bio_err, "%-14s disable standard block padding\n",
                        "-nopad");
 #ifndef OPENSSL_NO_ENGINE
             BIO_printf(bio_err,
                        "%-14s use engine e, possibly a hardware device.\n",
                        "-engine e");
 #endif
 
             BIO_printf(bio_err, "Cipher Types\n");
             OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH,
                                    show_ciphers, bio_err);
             BIO_printf(bio_err, "\n");
 
             goto end;
         }
         argc--;
         argv++;
     }
 
 #ifndef OPENSSL_NO_ENGINE
     setup_engine(bio_err, engine, 0);
 #endif
 
     if (cipher && EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) {
         BIO_printf(bio_err,
                    "AEAD ciphers not supported by the enc utility\n");
         goto end;
     }
 
     if (cipher && (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)) {
         BIO_printf(bio_err,
                    "Ciphers in XTS mode are not supported by the enc utility\n");
         goto end;
     }
 
     if (md && (dgst = EVP_get_digestbyname(md)) == NULL) {
         BIO_printf(bio_err, "%s is an unsupported message digest type\n", md);
         goto end;
     }
 
     if (dgst == NULL) {
         dgst = EVP_md5();
     }
 
     if (bufsize != NULL) {
         unsigned long n;
 
         for (n = 0; *bufsize; bufsize++) {
             i = *bufsize;
             if ((i <= '9') && (i >= '0'))
                 n = n * 10 + i - '0';
             else if (i == 'k') {
                 n *= 1024;
                 bufsize++;
                 break;
             }
         }
         if (*bufsize != '\0') {
             BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
             goto end;
         }
 
         /* It must be large enough for a base64 encoded line */
         if (base64 && n < 80)
             n = 80;
 
         bsize = (int)n;
         if (verbose)
             BIO_printf(bio_err, "bufsize=%d\n", bsize);
     }
 
     strbuf = OPENSSL_malloc(SIZE);
     buff = (unsigned char *)OPENSSL_malloc(EVP_ENCODE_LENGTH(bsize));
     if ((buff == NULL) || (strbuf == NULL)) {
         BIO_printf(bio_err, "OPENSSL_malloc failure %ld\n",
                    (long)EVP_ENCODE_LENGTH(bsize));
         goto end;
     }
 
     in = BIO_new(BIO_s_file());
     out = BIO_new(BIO_s_file());
     if ((in == NULL) || (out == NULL)) {
         ERR_print_errors(bio_err);
         goto end;
     }
     if (debug) {
         BIO_set_callback(in, BIO_debug_callback);
         BIO_set_callback(out, BIO_debug_callback);
         BIO_set_callback_arg(in, (char *)bio_err);
         BIO_set_callback_arg(out, (char *)bio_err);
     }
 
     if (inf == NULL) {
 #ifndef OPENSSL_NO_SETVBUF_IONBF
         if (bufsize != NULL)
             setvbuf(stdin, (char *)NULL, _IONBF, 0);
 #endif                          /* ndef OPENSSL_NO_SETVBUF_IONBF */
         BIO_set_fp(in, stdin, BIO_NOCLOSE);
     } else {
         if (BIO_read_filename(in, inf) <= 0) {
             perror(inf);
             goto end;
         }
     }
 
     if (!str && passarg) {
         if (!app_passwd(bio_err, passarg, NULL, &pass, NULL)) {
             BIO_printf(bio_err, "Error getting password\n");
             goto end;
         }
         str = pass;
     }
 
     if ((str == NULL) && (cipher != NULL) && (hkey == NULL)) {
         for (;;) {
             char buf[200];
 
             BIO_snprintf(buf, sizeof buf, "enter %s %s password:",
                          OBJ_nid2ln(EVP_CIPHER_nid(cipher)),
                          (enc) ? "encryption" : "decryption");
             strbuf[0] = '\0';
             i = EVP_read_pw_string((char *)strbuf, SIZE, buf, enc);
             if (i == 0) {
                 if (strbuf[0] == '\0') {
                     ret = 1;
                     goto end;
                 }
                 str = strbuf;
                 break;
             }
             if (i < 0) {
                 BIO_printf(bio_err, "bad password read\n");
                 goto end;
             }
         }
     }
 
     if (outf == NULL) {
         BIO_set_fp(out, stdout, BIO_NOCLOSE);
 #ifndef OPENSSL_NO_SETVBUF_IONBF
         if (bufsize != NULL)
             setvbuf(stdout, (char *)NULL, _IONBF, 0);
 #endif                          /* ndef OPENSSL_NO_SETVBUF_IONBF */
 #ifdef OPENSSL_SYS_VMS
         {
             BIO *tmpbio = BIO_new(BIO_f_linebuffer());
             out = BIO_push(tmpbio, out);
         }
 #endif
     } else {
         if (BIO_write_filename(out, outf) <= 0) {
             perror(outf);
             goto end;
         }
     }
 
     rbio = in;
     wbio = out;
 
 #ifdef ZLIB
 
     if (do_zlib) {
         if ((bzl = BIO_new(BIO_f_zlib())) == NULL)
             goto end;
         if (enc)
             wbio = BIO_push(bzl, wbio);
         else
             rbio = BIO_push(bzl, rbio);
     }
 #endif
 
     if (base64) {
         if ((b64 = BIO_new(BIO_f_base64())) == NULL)
             goto end;
         if (debug) {
             BIO_set_callback(b64, BIO_debug_callback);
             BIO_set_callback_arg(b64, (char *)bio_err);
         }
         if (olb64)
             BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
         if (enc)
             wbio = BIO_push(b64, wbio);
         else
             rbio = BIO_push(b64, rbio);
     }
 
     if (cipher != NULL) {
         /*
          * Note that str is NULL if a key was passed on the command line, so
          * we get no salt in that case. Is this a bug?
          */
         if (str != NULL) {
             /*
              * Salt handling: if encrypting generate a salt and write to
              * output BIO. If decrypting read salt from input BIO.
              */
             unsigned char *sptr;
             if (nosalt)
                 sptr = NULL;
             else {
                 if (enc) {
                     if (hsalt) {
                         if (!set_hex(hsalt, salt, sizeof salt)) {
                             BIO_printf(bio_err, "invalid hex salt value\n");
                             goto end;
                         }
-                    } else if (RAND_pseudo_bytes(salt, sizeof salt) < 0)
+                    } else if (RAND_bytes(salt, sizeof salt) <= 0)
                         goto end;
                     /*
                      * If -P option then don't bother writing
                      */
                     if ((printkey != 2)
                         && (BIO_write(wbio, magic,
                                       sizeof magic - 1) != sizeof magic - 1
                             || BIO_write(wbio,
                                          (char *)salt,
                                          sizeof salt) != sizeof salt)) {
                         BIO_printf(bio_err, "error writing output file\n");
                         goto end;
                     }
                 } else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
                            || BIO_read(rbio,
                                        (unsigned char *)salt,
                                        sizeof salt) != sizeof salt) {
                     BIO_printf(bio_err, "error reading input file\n");
                     goto end;
                 } else if (memcmp(mbuf, magic, sizeof magic - 1)) {
                     BIO_printf(bio_err, "bad magic number\n");
                     goto end;
                 }
 
                 sptr = salt;
             }
 
             EVP_BytesToKey(cipher, dgst, sptr,
                            (unsigned char *)str, strlen(str), 1, key, iv);
             /*
              * zero the complete buffer or the string passed from the command
              * line bug picked up by Larry J. Hughes Jr. <hughes@indiana.edu>
              */
             if (str == strbuf)
                 OPENSSL_cleanse(str, SIZE);
             else
                 OPENSSL_cleanse(str, strlen(str));
         }
         if (hiv != NULL) {
             int siz = EVP_CIPHER_iv_length(cipher);
             if (siz == 0) {
                 BIO_printf(bio_err, "warning: iv not use by this cipher\n");
             } else if (!set_hex(hiv, iv, sizeof iv)) {
                 BIO_printf(bio_err, "invalid hex iv value\n");
                 goto end;
             }
         }
         if ((hiv == NULL) && (str == NULL)
             && EVP_CIPHER_iv_length(cipher) != 0) {
             /*
              * No IV was explicitly set and no IV was generated during
              * EVP_BytesToKey. Hence the IV is undefined, making correct
              * decryption impossible.
              */
             BIO_printf(bio_err, "iv undefined\n");
             goto end;
         }
         if ((hkey != NULL) && !set_hex(hkey, key, EVP_CIPHER_key_length(cipher))) {
             BIO_printf(bio_err, "invalid hex key value\n");
             goto end;
         }
 
         if ((benc = BIO_new(BIO_f_cipher())) == NULL)
             goto end;
 
         /*
          * Since we may be changing parameters work on the encryption context
          * rather than calling BIO_set_cipher().
          */
 
         BIO_get_cipher_ctx(benc, &ctx);
 
         if (non_fips_allow)
             EVP_CIPHER_CTX_set_flags(ctx, EVP_CIPH_FLAG_NON_FIPS_ALLOW);
 
         if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) {
             BIO_printf(bio_err, "Error setting cipher %s\n",
                        EVP_CIPHER_name(cipher));
             ERR_print_errors(bio_err);
             goto end;
         }
 
         if (nopad)
             EVP_CIPHER_CTX_set_padding(ctx, 0);
 
         if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc)) {
             BIO_printf(bio_err, "Error setting cipher %s\n",
                        EVP_CIPHER_name(cipher));
             ERR_print_errors(bio_err);
             goto end;
         }
 
         if (debug) {
             BIO_set_callback(benc, BIO_debug_callback);
             BIO_set_callback_arg(benc, (char *)bio_err);
         }
 
         if (printkey) {
             if (!nosalt) {
                 printf("salt=");
                 for (i = 0; i < (int)sizeof(salt); i++)
                     printf("%02X", salt[i]);
                 printf("\n");
             }
             if (cipher->key_len > 0) {
                 printf("key=");
                 for (i = 0; i < cipher->key_len; i++)
                     printf("%02X", key[i]);
                 printf("\n");
             }
             if (cipher->iv_len > 0) {
                 printf("iv =");
                 for (i = 0; i < cipher->iv_len; i++)
                     printf("%02X", iv[i]);
                 printf("\n");
             }
             if (printkey == 2) {
                 ret = 0;
                 goto end;
             }
         }
     }
 
     /* Only encrypt/decrypt as we write the file */
     if (benc != NULL)
         wbio = BIO_push(benc, wbio);
 
     for (;;) {
         inl = BIO_read(rbio, (char *)buff, bsize);
         if (inl <= 0)
             break;
         if (BIO_write(wbio, (char *)buff, inl) != inl) {
             BIO_printf(bio_err, "error writing output file\n");
             goto end;
         }
     }
     if (!BIO_flush(wbio)) {
         BIO_printf(bio_err, "bad decrypt\n");
         goto end;
     }
 
     ret = 0;
     if (verbose) {
         BIO_printf(bio_err, "bytes read   :%8ld\n", BIO_number_read(in));
         BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
     }
  end:
     ERR_print_errors(bio_err);
     if (strbuf != NULL)
         OPENSSL_free(strbuf);
     if (buff != NULL)
         OPENSSL_free(buff);
     if (in != NULL)
         BIO_free(in);
     if (out != NULL)
         BIO_free_all(out);
     if (benc != NULL)
         BIO_free(benc);
     if (b64 != NULL)
         BIO_free(b64);
 #ifdef ZLIB
     if (bzl != NULL)
         BIO_free(bzl);
 #endif
     if (pass)
         OPENSSL_free(pass);
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }
 
 int set_hex(char *in, unsigned char *out, int size)
 {
     int i, n;
     unsigned char j;
 
     n = strlen(in);
     if (n > (size * 2)) {
         BIO_printf(bio_err, "hex string is too long\n");
         return (0);
     }
     memset(out, 0, size);
     for (i = 0; i < n; i++) {
         j = (unsigned char)*in;
         *(in++) = '\0';
         if (j == 0)
             break;
         if ((j >= '0') && (j <= '9'))
             j -= '0';
         else if ((j >= 'A') && (j <= 'F'))
             j = j - 'A' + 10;
         else if ((j >= 'a') && (j <= 'f'))
             j = j - 'a' + 10;
         else {
             BIO_printf(bio_err, "non-hex digit\n");
             return (0);
         }
         if (i & 1)
             out[i / 2] |= j;
         else
             out[i / 2] = (j << 4);
     }
     return (1);
 }
Index: vendor-crypto/openssl/dist-1.0.1/apps/passwd.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/apps/passwd.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/apps/passwd.c	(revision 306191)
@@ -1,494 +1,494 @@
 /* apps/passwd.c */
 
 #if defined OPENSSL_NO_MD5 || defined CHARSET_EBCDIC
 # define NO_MD5CRYPT_1
 #endif
 
 #if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
 
 # include <assert.h>
 # include <string.h>
 
 # include "apps.h"
 
 # include <openssl/bio.h>
 # include <openssl/err.h>
 # include <openssl/evp.h>
 # include <openssl/rand.h>
 # ifndef OPENSSL_NO_DES
 #  include <openssl/des.h>
 # endif
 # ifndef NO_MD5CRYPT_1
 #  include <openssl/md5.h>
 # endif
 
 # undef PROG
 # define PROG passwd_main
 
 static unsigned const char cov_2char[64] = {
     /* from crypto/des/fcrypt.c */
     0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
     0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
     0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
     0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
     0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
     0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
     0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
     0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
 };
 
 static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
                      char *passwd, BIO *out, int quiet, int table,
                      int reverse, size_t pw_maxlen, int usecrypt, int use1,
                      int useapr1);
 
 /*-
  * -crypt        - standard Unix password algorithm (default)
  * -1            - MD5-based password algorithm
  * -apr1         - MD5-based password algorithm, Apache variant
  * -salt string  - salt
  * -in file      - read passwords from file
  * -stdin        - read passwords from stdin
  * -noverify     - never verify when reading password from terminal
  * -quiet        - no warnings
  * -table        - format output as table
  * -reverse      - switch table columns
  */
 
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
 {
     int ret = 1;
     char *infile = NULL;
     int in_stdin = 0;
     int in_noverify = 0;
     char *salt = NULL, *passwd = NULL, **passwds = NULL;
     char *salt_malloc = NULL, *passwd_malloc = NULL;
     size_t passwd_malloc_size = 0;
     int pw_source_defined = 0;
     BIO *in = NULL, *out = NULL;
     int i, badopt, opt_done;
     int passed_salt = 0, quiet = 0, table = 0, reverse = 0;
     int usecrypt = 0, use1 = 0, useapr1 = 0;
     size_t pw_maxlen = 0;
 
     apps_startup();
 
     if (bio_err == NULL)
         if ((bio_err = BIO_new(BIO_s_file())) != NULL)
             BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);
 
     if (!load_config(bio_err, NULL))
         goto err;
     out = BIO_new(BIO_s_file());
     if (out == NULL)
         goto err;
     BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
 # ifdef OPENSSL_SYS_VMS
     {
         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
         out = BIO_push(tmpbio, out);
     }
 # endif
 
     badopt = 0, opt_done = 0;
     i = 0;
     while (!badopt && !opt_done && argv[++i] != NULL) {
         if (strcmp(argv[i], "-crypt") == 0)
             usecrypt = 1;
         else if (strcmp(argv[i], "-1") == 0)
             use1 = 1;
         else if (strcmp(argv[i], "-apr1") == 0)
             useapr1 = 1;
         else if (strcmp(argv[i], "-salt") == 0) {
             if ((argv[i + 1] != NULL) && (salt == NULL)) {
                 passed_salt = 1;
                 salt = argv[++i];
             } else
                 badopt = 1;
         } else if (strcmp(argv[i], "-in") == 0) {
             if ((argv[i + 1] != NULL) && !pw_source_defined) {
                 pw_source_defined = 1;
                 infile = argv[++i];
             } else
                 badopt = 1;
         } else if (strcmp(argv[i], "-stdin") == 0) {
             if (!pw_source_defined) {
                 pw_source_defined = 1;
                 in_stdin = 1;
             } else
                 badopt = 1;
         } else if (strcmp(argv[i], "-noverify") == 0)
             in_noverify = 1;
         else if (strcmp(argv[i], "-quiet") == 0)
             quiet = 1;
         else if (strcmp(argv[i], "-table") == 0)
             table = 1;
         else if (strcmp(argv[i], "-reverse") == 0)
             reverse = 1;
         else if (argv[i][0] == '-')
             badopt = 1;
         else if (!pw_source_defined)
             /* non-option arguments, use as passwords */
         {
             pw_source_defined = 1;
             passwds = &argv[i];
             opt_done = 1;
         } else
             badopt = 1;
     }
 
     if (!usecrypt && !use1 && !useapr1) /* use default */
         usecrypt = 1;
     if (usecrypt + use1 + useapr1 > 1) /* conflict */
         badopt = 1;
 
     /* reject unsupported algorithms */
 # ifdef OPENSSL_NO_DES
     if (usecrypt)
         badopt = 1;
 # endif
 # ifdef NO_MD5CRYPT_1
     if (use1 || useapr1)
         badopt = 1;
 # endif
 
     if (badopt) {
         BIO_printf(bio_err, "Usage: passwd [options] [passwords]\n");
         BIO_printf(bio_err, "where options are\n");
 # ifndef OPENSSL_NO_DES
         BIO_printf(bio_err,
                    "-crypt             standard Unix password algorithm (default)\n");
 # endif
 # ifndef NO_MD5CRYPT_1
         BIO_printf(bio_err,
                    "-1                 MD5-based password algorithm\n");
         BIO_printf(bio_err,
                    "-apr1              MD5-based password algorithm, Apache variant\n");
 # endif
         BIO_printf(bio_err, "-salt string       use provided salt\n");
         BIO_printf(bio_err, "-in file           read passwords from file\n");
         BIO_printf(bio_err, "-stdin             read passwords from stdin\n");
         BIO_printf(bio_err,
                    "-noverify          never verify when reading password from terminal\n");
         BIO_printf(bio_err, "-quiet             no warnings\n");
         BIO_printf(bio_err, "-table             format output as table\n");
         BIO_printf(bio_err, "-reverse           switch table columns\n");
 
         goto err;
     }
 
     if ((infile != NULL) || in_stdin) {
         in = BIO_new(BIO_s_file());
         if (in == NULL)
             goto err;
         if (infile != NULL) {
             assert(in_stdin == 0);
             if (BIO_read_filename(in, infile) <= 0)
                 goto err;
         } else {
             assert(in_stdin);
             BIO_set_fp(in, stdin, BIO_NOCLOSE);
         }
     }
 
     if (usecrypt)
         pw_maxlen = 8;
     else if (use1 || useapr1)
         pw_maxlen = 256;        /* arbitrary limit, should be enough for most
                                  * passwords */
 
     if (passwds == NULL) {
         /* no passwords on the command line */
 
         passwd_malloc_size = pw_maxlen + 2;
         /*
          * longer than necessary so that we can warn about truncation
          */
         passwd = passwd_malloc = OPENSSL_malloc(passwd_malloc_size);
         if (passwd_malloc == NULL)
             goto err;
     }
 
     if ((in == NULL) && (passwds == NULL)) {
         /* build a null-terminated list */
         static char *passwds_static[2] = { NULL, NULL };
 
         passwds = passwds_static;
         if (in == NULL)
             if (EVP_read_pw_string
                 (passwd_malloc, passwd_malloc_size, "Password: ",
                  !(passed_salt || in_noverify)) != 0)
                 goto err;
         passwds[0] = passwd_malloc;
     }
 
     if (in == NULL) {
         assert(passwds != NULL);
         assert(*passwds != NULL);
 
         do {                    /* loop over list of passwords */
             passwd = *passwds++;
             if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
                            quiet, table, reverse, pw_maxlen, usecrypt, use1,
                            useapr1))
                 goto err;
         }
         while (*passwds != NULL);
     } else
         /* in != NULL */
     {
         int done;
 
         assert(passwd != NULL);
         do {
             int r = BIO_gets(in, passwd, pw_maxlen + 1);
             if (r > 0) {
                 char *c = (strchr(passwd, '\n'));
                 if (c != NULL)
                     *c = 0;     /* truncate at newline */
                 else {
                     /* ignore rest of line */
                     char trash[BUFSIZ];
                     do
                         r = BIO_gets(in, trash, sizeof trash);
                     while ((r > 0) && (!strchr(trash, '\n')));
                 }
 
                 if (!do_passwd(passed_salt, &salt, &salt_malloc, passwd, out,
                                quiet, table, reverse, pw_maxlen, usecrypt,
                                use1, useapr1))
                     goto err;
             }
             done = (r <= 0);
         }
         while (!done);
     }
     ret = 0;
 
  err:
     ERR_print_errors(bio_err);
     if (salt_malloc)
         OPENSSL_free(salt_malloc);
     if (passwd_malloc)
         OPENSSL_free(passwd_malloc);
     if (in)
         BIO_free(in);
     if (out)
         BIO_free_all(out);
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }
 
 # ifndef NO_MD5CRYPT_1
 /*
  * MD5-based password algorithm (should probably be available as a library
  * function; then the static buffer would not be acceptable). For magic
  * string "1", this should be compatible to the MD5-based BSD password
  * algorithm. For 'magic' string "apr1", this is compatible to the MD5-based
  * Apache password algorithm. (Apparently, the Apache password algorithm is
  * identical except that the 'magic' string was changed -- the laziest
  * application of the NIH principle I've ever encountered.)
  */
 static char *md5crypt(const char *passwd, const char *magic, const char *salt)
 {
     /* "$apr1$..salt..$.......md5hash..........\0" */
     static char out_buf[6 + 9 + 24 + 2];
     unsigned char buf[MD5_DIGEST_LENGTH];
     char *salt_out;
     int n;
     unsigned int i;
     EVP_MD_CTX md, md2;
     size_t passwd_len, salt_len;
 
     passwd_len = strlen(passwd);
     out_buf[0] = '$';
     out_buf[1] = 0;
     assert(strlen(magic) <= 4); /* "1" or "apr1" */
     strncat(out_buf, magic, 4);
     strncat(out_buf, "$", 1);
     strncat(out_buf, salt, 8);
     assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
     salt_out = out_buf + 2 + strlen(magic);
     salt_len = strlen(salt_out);
     assert(salt_len <= 8);
 
     EVP_MD_CTX_init(&md);
     EVP_DigestInit_ex(&md, EVP_md5(), NULL);
     EVP_DigestUpdate(&md, passwd, passwd_len);
     EVP_DigestUpdate(&md, "$", 1);
     EVP_DigestUpdate(&md, magic, strlen(magic));
     EVP_DigestUpdate(&md, "$", 1);
     EVP_DigestUpdate(&md, salt_out, salt_len);
 
     EVP_MD_CTX_init(&md2);
     EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
     EVP_DigestUpdate(&md2, passwd, passwd_len);
     EVP_DigestUpdate(&md2, salt_out, salt_len);
     EVP_DigestUpdate(&md2, passwd, passwd_len);
     EVP_DigestFinal_ex(&md2, buf, NULL);
 
     for (i = passwd_len; i > sizeof buf; i -= sizeof buf)
         EVP_DigestUpdate(&md, buf, sizeof buf);
     EVP_DigestUpdate(&md, buf, i);
 
     n = passwd_len;
     while (n) {
         EVP_DigestUpdate(&md, (n & 1) ? "\0" : passwd, 1);
         n >>= 1;
     }
     EVP_DigestFinal_ex(&md, buf, NULL);
 
     for (i = 0; i < 1000; i++) {
         EVP_DigestInit_ex(&md2, EVP_md5(), NULL);
         EVP_DigestUpdate(&md2, (i & 1) ? (unsigned const char *)passwd : buf,
                          (i & 1) ? passwd_len : sizeof buf);
         if (i % 3)
             EVP_DigestUpdate(&md2, salt_out, salt_len);
         if (i % 7)
             EVP_DigestUpdate(&md2, passwd, passwd_len);
         EVP_DigestUpdate(&md2, (i & 1) ? buf : (unsigned const char *)passwd,
                          (i & 1) ? sizeof buf : passwd_len);
         EVP_DigestFinal_ex(&md2, buf, NULL);
     }
     EVP_MD_CTX_cleanup(&md2);
 
     {
         /* transform buf into output string */
 
         unsigned char buf_perm[sizeof buf];
         int dest, source;
         char *output;
 
         /* silly output permutation */
         for (dest = 0, source = 0; dest < 14;
              dest++, source = (source + 6) % 17)
             buf_perm[dest] = buf[source];
         buf_perm[14] = buf[5];
         buf_perm[15] = buf[11];
 #  ifndef PEDANTIC              /* Unfortunately, this generates a "no
                                  * effect" warning */
         assert(16 == sizeof buf_perm);
 #  endif
 
         output = salt_out + salt_len;
         assert(output == out_buf + strlen(out_buf));
 
         *output++ = '$';
 
         for (i = 0; i < 15; i += 3) {
             *output++ = cov_2char[buf_perm[i + 2] & 0x3f];
             *output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
                                   (buf_perm[i + 2] >> 6)];
             *output++ = cov_2char[((buf_perm[i] & 3) << 4) |
                                   (buf_perm[i + 1] >> 4)];
             *output++ = cov_2char[buf_perm[i] >> 2];
         }
         assert(i == 15);
         *output++ = cov_2char[buf_perm[i] & 0x3f];
         *output++ = cov_2char[buf_perm[i] >> 6];
         *output = 0;
         assert(strlen(out_buf) < sizeof(out_buf));
     }
     EVP_MD_CTX_cleanup(&md);
 
     return out_buf;
 }
 # endif
 
 static int do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
                      char *passwd, BIO *out, int quiet, int table,
                      int reverse, size_t pw_maxlen, int usecrypt, int use1,
                      int useapr1)
 {
     char *hash = NULL;
 
     assert(salt_p != NULL);
     assert(salt_malloc_p != NULL);
 
     /* first make sure we have a salt */
     if (!passed_salt) {
 # ifndef OPENSSL_NO_DES
         if (usecrypt) {
             if (*salt_malloc_p == NULL) {
                 *salt_p = *salt_malloc_p = OPENSSL_malloc(3);
                 if (*salt_malloc_p == NULL)
                     goto err;
             }
-            if (RAND_pseudo_bytes((unsigned char *)*salt_p, 2) < 0)
+            if (RAND_bytes((unsigned char *)*salt_p, 2) <= 0)
                 goto err;
             (*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
             (*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
             (*salt_p)[2] = 0;
 #  ifdef CHARSET_EBCDIC
             ascii2ebcdic(*salt_p, *salt_p, 2); /* des_crypt will convert back
                                                 * to ASCII */
 #  endif
         }
 # endif                         /* !OPENSSL_NO_DES */
 
 # ifndef NO_MD5CRYPT_1
         if (use1 || useapr1) {
             int i;
 
             if (*salt_malloc_p == NULL) {
                 *salt_p = *salt_malloc_p = OPENSSL_malloc(9);
                 if (*salt_malloc_p == NULL)
                     goto err;
             }
-            if (RAND_pseudo_bytes((unsigned char *)*salt_p, 8) < 0)
+            if (RAND_bytes((unsigned char *)*salt_p, 8) <= 0)
                 goto err;
 
             for (i = 0; i < 8; i++)
                 (*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
             (*salt_p)[8] = 0;
         }
 # endif                         /* !NO_MD5CRYPT_1 */
     }
 
     assert(*salt_p != NULL);
 
     /* truncate password if necessary */
     if ((strlen(passwd) > pw_maxlen)) {
         if (!quiet)
             /*
              * XXX: really we should know how to print a size_t, not cast it
              */
             BIO_printf(bio_err,
                        "Warning: truncating password to %u characters\n",
                        (unsigned)pw_maxlen);
         passwd[pw_maxlen] = 0;
     }
     assert(strlen(passwd) <= pw_maxlen);
 
     /* now compute password hash */
 # ifndef OPENSSL_NO_DES
     if (usecrypt)
         hash = DES_crypt(passwd, *salt_p);
 # endif
 # ifndef NO_MD5CRYPT_1
     if (use1 || useapr1)
         hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p);
 # endif
     assert(hash != NULL);
 
     if (table && !reverse)
         BIO_printf(out, "%s\t%s\n", passwd, hash);
     else if (table && reverse)
         BIO_printf(out, "%s\t%s\n", hash, passwd);
     else
         BIO_printf(out, "%s\n", hash);
     return 1;
 
  err:
     return 0;
 }
 #else
 
 int MAIN(int argc, char **argv)
 {
     fputs("Program not available.\n", stderr)
         OPENSSL_EXIT(1);
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/apps/s_server.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/apps/s_server.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/apps/s_server.c	(revision 306191)
@@ -1,2989 +1,2989 @@
 /* apps/s_server.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-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
  *    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.
  * ECC cipher suite support in OpenSSL originally developed by
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 /*
  * Until the key-gen callbacks are modified to use newer prototypes, we allow
  * deprecated functions for openssl-internal code
  */
 #ifdef OPENSSL_NO_DEPRECATED
 # undef OPENSSL_NO_DEPRECATED
 #endif
 
 #include <assert.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <openssl/e_os2.h>
 #ifdef OPENSSL_NO_STDIO
 # define APPS_WIN16
 #endif
 
 /* conflicts with winsock2 stuff on netware */
 #if !defined(OPENSSL_SYS_NETWARE)
 # include <sys/types.h>
 #endif
 
 /*
  * With IPv6, it looks like Digital has mixed up the proper order of
  * recursive header file inclusion, resulting in the compiler complaining
  * that u_int isn't defined, but only if _POSIX_C_SOURCE is defined, which is
  * needed to have fileno() declared correctly...  So let's define u_int
  */
 #if defined(OPENSSL_SYS_VMS_DECC) && !defined(__U_INT)
 # define __U_INT
 typedef unsigned int u_int;
 #endif
 
 #include <openssl/lhash.h>
 #include <openssl/bn.h>
 #define USE_SOCKETS
 #include "apps.h"
 #include <openssl/err.h>
 #include <openssl/pem.h>
 #include <openssl/x509.h>
 #include <openssl/ssl.h>
 #include <openssl/rand.h>
 #include <openssl/ocsp.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 #ifndef OPENSSL_NO_RSA
 # include <openssl/rsa.h>
 #endif
 #ifndef OPENSSL_NO_SRP
 # include <openssl/srp.h>
 #endif
 #include "s_apps.h"
 #include "timeouts.h"
 
 #if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000)
 /* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */
 # undef FIONBIO
 #endif
 
 #if defined(OPENSSL_SYS_BEOS_R5)
 # include <fcntl.h>
 #endif
 
 #ifndef OPENSSL_NO_RSA
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength);
 #endif
 static int sv_body(char *hostname, int s, unsigned char *context);
 static int www_body(char *hostname, int s, unsigned char *context);
 static void close_accept_socket(void);
 static void sv_usage(void);
 static int init_ssl_connection(SSL *s);
 static void print_stats(BIO *bp, SSL_CTX *ctx);
 static int generate_session_id(const SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile);
 static DH *get_dh2048(void);
 #endif
 
 #ifdef MONOLITH
 static void s_server_init(void);
 #endif
 
 #ifndef OPENSSL_NO_DH
 static unsigned char dh2048_p[] = {
     0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6,
     0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1,
     0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9,
     0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD,
     0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17,
     0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F,
     0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD,
     0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30,
     0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E,
     0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4,
     0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58,
     0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B,
     0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C,
     0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B,
     0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD,
     0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C,
     0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C,
     0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29,
     0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B,
     0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C,
     0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55,
     0xE9,0x32,0x0B,0x3B,
 };
 
 static unsigned char dh2048_g[] = {
     0x02,
 };
 
 DH *get_dh2048()
 {
     DH *dh;
 
     if ((dh = DH_new()) == NULL)
         return NULL;
     dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
     dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
     if (dh->p == NULL || dh->g == NULL) {
         DH_free(dh);
         return NULL;
     }
     return dh;
 }
 #endif
 
 /* static int load_CA(SSL_CTX *ctx, char *file);*/
 
 #undef BUFSIZZ
 #define BUFSIZZ 16*1024
 static int bufsize = BUFSIZZ;
 static int accept_socket = -1;
 
 #define TEST_CERT       "server.pem"
 #ifndef OPENSSL_NO_TLSEXT
 # define TEST_CERT2      "server2.pem"
 #endif
 #undef PROG
 #define PROG            s_server_main
 
 extern int verify_depth, verify_return_error;
 
 static char *cipher = NULL;
 static int s_server_verify = SSL_VERIFY_NONE;
 static int s_server_session_id_context = 1; /* anything will do */
 static const char *s_cert_file = TEST_CERT, *s_key_file = NULL;
 #ifndef OPENSSL_NO_TLSEXT
 static const char *s_cert_file2 = TEST_CERT2, *s_key_file2 = NULL;
 #endif
 static char *s_dcert_file = NULL, *s_dkey_file = NULL;
 #ifdef FIONBIO
 static int s_nbio = 0;
 #endif
 static int s_nbio_test = 0;
 int s_crlf = 0;
 static SSL_CTX *ctx = NULL;
 #ifndef OPENSSL_NO_TLSEXT
 static SSL_CTX *ctx2 = NULL;
 #endif
 static int www = 0;
 
 static BIO *bio_s_out = NULL;
 static int s_debug = 0;
 #ifndef OPENSSL_NO_TLSEXT
 static int s_tlsextdebug = 0;
 static int s_tlsextstatus = 0;
 static int cert_status_cb(SSL *s, void *arg);
 #endif
 static int s_msg = 0;
 static int s_quiet = 0;
 
 static char *keymatexportlabel = NULL;
 static int keymatexportlen = 20;
 
 static int hack = 0;
 #ifndef OPENSSL_NO_ENGINE
 static char *engine_id = NULL;
 #endif
 static const char *session_id_prefix = NULL;
 
 static int enable_timeouts = 0;
 static long socket_mtu;
 #ifndef OPENSSL_NO_DTLS1
 static int cert_chain = 0;
 #endif
 
 #ifndef OPENSSL_NO_PSK
 static char *psk_identity = "Client_identity";
 char *psk_key = NULL;           /* by default PSK is not used */
 
 static unsigned int psk_server_cb(SSL *ssl, const char *identity,
                                   unsigned char *psk,
                                   unsigned int max_psk_len)
 {
     unsigned int psk_len = 0;
     int ret;
     BIGNUM *bn = NULL;
 
     if (s_debug)
         BIO_printf(bio_s_out, "psk_server_cb\n");
     if (!identity) {
         BIO_printf(bio_err, "Error: client did not send PSK identity\n");
         goto out_err;
     }
     if (s_debug)
         BIO_printf(bio_s_out, "identity_len=%d identity=%s\n",
                    (int)strlen(identity), identity);
 
     /* here we could lookup the given identity e.g. from a database */
     if (strcmp(identity, psk_identity) != 0) {
         BIO_printf(bio_s_out, "PSK error: client identity not found"
                    " (got '%s' expected '%s')\n", identity, psk_identity);
         goto out_err;
     }
     if (s_debug)
         BIO_printf(bio_s_out, "PSK client identity found\n");
 
     /* convert the PSK key to binary */
     ret = BN_hex2bn(&bn, psk_key);
     if (!ret) {
         BIO_printf(bio_err, "Could not convert PSK key '%s' to BIGNUM\n",
                    psk_key);
         if (bn)
             BN_free(bn);
         return 0;
     }
     if (BN_num_bytes(bn) > (int)max_psk_len) {
         BIO_printf(bio_err,
                    "psk buffer of callback is too small (%d) for key (%d)\n",
                    max_psk_len, BN_num_bytes(bn));
         BN_free(bn);
         return 0;
     }
 
     ret = BN_bn2bin(bn, psk);
     BN_free(bn);
 
     if (ret < 0)
         goto out_err;
     psk_len = (unsigned int)ret;
 
     if (s_debug)
         BIO_printf(bio_s_out, "fetched PSK len=%d\n", psk_len);
     return psk_len;
  out_err:
     if (s_debug)
         BIO_printf(bio_err, "Error in PSK server callback\n");
     return 0;
 }
 #endif
 
 #ifndef OPENSSL_NO_SRP
 /* This is a context that we pass to callbacks */
 typedef struct srpsrvparm_st {
     char *login;
     SRP_VBASE *vb;
     SRP_user_pwd *user;
 } srpsrvparm;
 
 /*
  * This callback pretends to require some asynchronous logic in order to
  * obtain a verifier. When the callback is called for a new connection we
  * return with a negative value. This will provoke the accept etc to return
  * with an LOOKUP_X509. The main logic of the reinvokes the suspended call
  * (which would normally occur after a worker has finished) and we set the
  * user parameters.
  */
 static int MS_CALLBACK ssl_srp_server_param_cb(SSL *s, int *ad, void *arg)
 {
     srpsrvparm *p = (srpsrvparm *) arg;
     int ret = SSL3_AL_FATAL;
 
     if (p->login == NULL && p->user == NULL) {
         p->login = SSL_get_srp_username(s);
         BIO_printf(bio_err, "SRP username = \"%s\"\n", p->login);
         return (-1);
     }
 
     if (p->user == NULL) {
         BIO_printf(bio_err, "User %s doesn't exist\n", p->login);
         goto err;
     }
 
     if (SSL_set_srp_server_param
         (s, p->user->N, p->user->g, p->user->s, p->user->v,
          p->user->info) < 0) {
         *ad = SSL_AD_INTERNAL_ERROR;
         goto err;
     }
     BIO_printf(bio_err,
                "SRP parameters set: username = \"%s\" info=\"%s\" \n",
                p->login, p->user->info);
     ret = SSL_ERROR_NONE;
 
 err:
     SRP_user_pwd_free(p->user);
     p->user = NULL;
     p->login = NULL;
     return ret;
 }
 
 #endif
 
 #ifdef MONOLITH
 static void s_server_init(void)
 {
     accept_socket = -1;
     cipher = NULL;
     s_server_verify = SSL_VERIFY_NONE;
     s_dcert_file = NULL;
     s_dkey_file = NULL;
     s_cert_file = TEST_CERT;
     s_key_file = NULL;
 # ifndef OPENSSL_NO_TLSEXT
     s_cert_file2 = TEST_CERT2;
     s_key_file2 = NULL;
     ctx2 = NULL;
 # endif
 # ifdef FIONBIO
     s_nbio = 0;
 # endif
     s_nbio_test = 0;
     ctx = NULL;
     www = 0;
 
     bio_s_out = NULL;
     s_debug = 0;
     s_msg = 0;
     s_quiet = 0;
     hack = 0;
 # ifndef OPENSSL_NO_ENGINE
     engine_id = NULL;
 # endif
 }
 #endif
 
 static void sv_usage(void)
 {
     BIO_printf(bio_err, "usage: s_server [args ...]\n");
     BIO_printf(bio_err, "\n");
     BIO_printf(bio_err,
                " -accept arg   - port to accept on (default is %d)\n", PORT);
     BIO_printf(bio_err, " -context arg  - set session ID context\n");
     BIO_printf(bio_err,
                " -verify arg   - turn on peer certificate verification\n");
     BIO_printf(bio_err,
                " -Verify arg   - turn on peer certificate verification, must have a cert.\n");
     BIO_printf(bio_err,
                " -verify_return_error - return verification errors\n");
     BIO_printf(bio_err, " -cert arg     - certificate file to use\n");
     BIO_printf(bio_err, "                 (default is %s)\n", TEST_CERT);
     BIO_printf(bio_err,
                " -crl_check    - check the peer certificate has not been revoked by its CA.\n"
                "                 The CRL(s) are appended to the certificate file\n");
     BIO_printf(bio_err,
                " -crl_check_all - check the peer certificate has not been revoked by its CA\n"
                "                 or any other CRL in the CA chain. CRL(s) are appened to the\n"
                "                 the certificate file.\n");
     BIO_printf(bio_err,
                " -certform arg - certificate format (PEM or DER) PEM default\n");
     BIO_printf(bio_err,
                " -key arg      - Private Key file to use, in cert file if\n");
     BIO_printf(bio_err, "                 not specified (default is %s)\n",
                TEST_CERT);
     BIO_printf(bio_err,
                " -keyform arg  - key format (PEM, DER or ENGINE) PEM default\n");
     BIO_printf(bio_err,
                " -pass arg     - private key file pass phrase source\n");
     BIO_printf(bio_err,
                " -dcert arg    - second certificate file to use (usually for DSA)\n");
     BIO_printf(bio_err,
                " -dcertform x  - second certificate format (PEM or DER) PEM default\n");
     BIO_printf(bio_err,
                " -dkey arg     - second private key file to use (usually for DSA)\n");
     BIO_printf(bio_err,
                " -dkeyform arg - second key format (PEM, DER or ENGINE) PEM default\n");
     BIO_printf(bio_err,
                " -dpass arg    - second private key file pass phrase source\n");
     BIO_printf(bio_err,
                " -dhparam arg  - DH parameter file to use, in cert file if not specified\n");
     BIO_printf(bio_err,
                "                 or a default set of parameters is used\n");
 #ifndef OPENSSL_NO_ECDH
     BIO_printf(bio_err,
                " -named_curve arg  - Elliptic curve name to use for ephemeral ECDH keys.\n"
                "                 Use \"openssl ecparam -list_curves\" for all names\n"
                "                 (default is nistp256).\n");
 #endif
 #ifdef FIONBIO
     BIO_printf(bio_err, " -nbio         - Run with non-blocking IO\n");
 #endif
     BIO_printf(bio_err,
                " -nbio_test    - test with the non-blocking test bio\n");
     BIO_printf(bio_err,
                " -crlf         - convert LF from terminal into CRLF\n");
     BIO_printf(bio_err, " -debug        - Print more output\n");
     BIO_printf(bio_err, " -msg          - Show protocol messages\n");
     BIO_printf(bio_err, " -state        - Print the SSL states\n");
     BIO_printf(bio_err, " -CApath arg   - PEM format directory of CA's\n");
     BIO_printf(bio_err, " -CAfile arg   - PEM format file of CA's\n");
     BIO_printf(bio_err,
                " -no_alt_chains - only ever use the first certificate chain found\n");
     BIO_printf(bio_err,
                " -nocert       - Don't use any certificates (Anon-DH)\n");
     BIO_printf(bio_err,
                " -cipher arg   - play with 'openssl ciphers' to see what goes here\n");
     BIO_printf(bio_err, " -serverpref   - Use server's cipher preferences\n");
     BIO_printf(bio_err, " -quiet        - No server output\n");
     BIO_printf(bio_err, " -no_tmp_rsa   - Do not generate a tmp RSA key\n");
 #ifndef OPENSSL_NO_PSK
     BIO_printf(bio_err, " -psk_hint arg - PSK identity hint to use\n");
     BIO_printf(bio_err, " -psk arg      - PSK in hex (without 0x)\n");
 # ifndef OPENSSL_NO_JPAKE
     BIO_printf(bio_err, " -jpake arg    - JPAKE secret to use\n");
 # endif
 #endif
 #ifndef OPENSSL_NO_SRP
     BIO_printf(bio_err, " -srpvfile file      - The verifier file for SRP\n");
     BIO_printf(bio_err,
                " -srpuserseed string - A seed string for a default user salt.\n");
 #endif
     BIO_printf(bio_err, " -ssl2         - Just talk SSLv2\n");
 #ifndef OPENSSL_NO_SSL3_METHOD
     BIO_printf(bio_err, " -ssl3         - Just talk SSLv3\n");
 #endif
     BIO_printf(bio_err, " -tls1_2       - Just talk TLSv1.2\n");
     BIO_printf(bio_err, " -tls1_1       - Just talk TLSv1.1\n");
     BIO_printf(bio_err, " -tls1         - Just talk TLSv1\n");
     BIO_printf(bio_err, " -dtls1        - Just talk DTLSv1\n");
     BIO_printf(bio_err, " -timeout      - Enable timeouts\n");
     BIO_printf(bio_err, " -mtu          - Set link layer MTU\n");
     BIO_printf(bio_err, " -chain        - Read a certificate chain\n");
     BIO_printf(bio_err, " -no_ssl2      - Just disable SSLv2\n");
     BIO_printf(bio_err, " -no_ssl3      - Just disable SSLv3\n");
     BIO_printf(bio_err, " -no_tls1      - Just disable TLSv1\n");
     BIO_printf(bio_err, " -no_tls1_1    - Just disable TLSv1.1\n");
     BIO_printf(bio_err, " -no_tls1_2    - Just disable TLSv1.2\n");
 #ifndef OPENSSL_NO_DH
     BIO_printf(bio_err, " -no_dhe       - Disable ephemeral DH\n");
 #endif
 #ifndef OPENSSL_NO_ECDH
     BIO_printf(bio_err, " -no_ecdhe     - Disable ephemeral ECDH\n");
 #endif
     BIO_printf(bio_err, " -bugs         - Turn on SSL bug compatibility\n");
     BIO_printf(bio_err,
                " -hack         - workaround for early Netscape code\n");
     BIO_printf(bio_err,
                " -www          - Respond to a 'GET /' with a status page\n");
     BIO_printf(bio_err,
                " -WWW          - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
     BIO_printf(bio_err,
                " -HTTP         - Respond to a 'GET /<path> HTTP/1.0' with file ./<path>\n");
     BIO_printf(bio_err,
                "                 with the assumption it contains a complete HTTP response.\n");
 #ifndef OPENSSL_NO_ENGINE
     BIO_printf(bio_err,
                " -engine id    - Initialise and use the specified engine\n");
 #endif
     BIO_printf(bio_err,
                " -id_prefix arg - Generate SSL/TLS session IDs prefixed by 'arg'\n");
     BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
                LIST_SEPARATOR_CHAR);
 #ifndef OPENSSL_NO_TLSEXT
     BIO_printf(bio_err,
                " -servername host - servername for HostName TLS extension\n");
     BIO_printf(bio_err,
                " -servername_fatal - on mismatch send fatal alert (default warning alert)\n");
     BIO_printf(bio_err,
                " -cert2 arg    - certificate file to use for servername\n");
     BIO_printf(bio_err, "                 (default is %s)\n", TEST_CERT2);
     BIO_printf(bio_err,
                " -key2 arg     - Private Key file to use for servername, in cert file if\n");
     BIO_printf(bio_err, "                 not specified (default is %s)\n",
                TEST_CERT2);
     BIO_printf(bio_err,
                " -tlsextdebug  - hex dump of all TLS extensions received\n");
     BIO_printf(bio_err,
                " -no_ticket    - disable use of RFC4507bis session tickets\n");
     BIO_printf(bio_err,
                " -legacy_renegotiation - enable use of legacy renegotiation (dangerous)\n");
 # ifndef OPENSSL_NO_NEXTPROTONEG
     BIO_printf(bio_err,
                " -nextprotoneg arg - set the advertised protocols for the NPN extension (comma-separated list)\n");
 # endif
 # ifndef OPENSSL_NO_SRTP
     BIO_printf(bio_err,
                " -use_srtp profiles - Offer SRTP key management with a colon-separated profile list\n");
 # endif
 #endif
     BIO_printf(bio_err,
                " -keymatexport label   - Export keying material using label\n");
     BIO_printf(bio_err,
                " -keymatexportlen len  - Export len bytes of keying material (default 20)\n");
     BIO_printf(bio_err,
                " -status           - respond to certificate status requests\n");
     BIO_printf(bio_err,
                " -status_verbose   - enable status request verbose printout\n");
     BIO_printf(bio_err,
                " -status_timeout n - status request responder timeout\n");
     BIO_printf(bio_err, " -status_url URL   - status request fallback URL\n");
 }
 
 static int local_argc = 0;
 static char **local_argv;
 
 #ifdef CHARSET_EBCDIC
 static int ebcdic_new(BIO *bi);
 static int ebcdic_free(BIO *a);
 static int ebcdic_read(BIO *b, char *out, int outl);
 static int ebcdic_write(BIO *b, const char *in, int inl);
 static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr);
 static int ebcdic_gets(BIO *bp, char *buf, int size);
 static int ebcdic_puts(BIO *bp, const char *str);
 
 # define BIO_TYPE_EBCDIC_FILTER  (18|0x0200)
 static BIO_METHOD methods_ebcdic = {
     BIO_TYPE_EBCDIC_FILTER,
     "EBCDIC/ASCII filter",
     ebcdic_write,
     ebcdic_read,
     ebcdic_puts,
     ebcdic_gets,
     ebcdic_ctrl,
     ebcdic_new,
     ebcdic_free,
 };
 
 typedef struct {
     size_t alloced;
     char buff[1];
 } EBCDIC_OUTBUFF;
 
 BIO_METHOD *BIO_f_ebcdic_filter()
 {
     return (&methods_ebcdic);
 }
 
 static int ebcdic_new(BIO *bi)
 {
     EBCDIC_OUTBUFF *wbuf;
 
     wbuf = (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
     if (!wbuf)
         return 0;
     wbuf->alloced = 1024;
     wbuf->buff[0] = '\0';
 
     bi->ptr = (char *)wbuf;
     bi->init = 1;
     bi->flags = 0;
     return (1);
 }
 
 static int ebcdic_free(BIO *a)
 {
     if (a == NULL)
         return (0);
     if (a->ptr != NULL)
         OPENSSL_free(a->ptr);
     a->ptr = NULL;
     a->init = 0;
     a->flags = 0;
     return (1);
 }
 
 static int ebcdic_read(BIO *b, char *out, int outl)
 {
     int ret = 0;
 
     if (out == NULL || outl == 0)
         return (0);
     if (b->next_bio == NULL)
         return (0);
 
     ret = BIO_read(b->next_bio, out, outl);
     if (ret > 0)
         ascii2ebcdic(out, out, ret);
     return (ret);
 }
 
 static int ebcdic_write(BIO *b, const char *in, int inl)
 {
     EBCDIC_OUTBUFF *wbuf;
     int ret = 0;
     int num;
     unsigned char n;
 
     if ((in == NULL) || (inl <= 0))
         return (0);
     if (b->next_bio == NULL)
         return (0);
 
     wbuf = (EBCDIC_OUTBUFF *) b->ptr;
 
     if (inl > (num = wbuf->alloced)) {
         num = num + num;        /* double the size */
         if (num < inl)
             num = inl;
         wbuf =
             (EBCDIC_OUTBUFF *) OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
         if (!wbuf)
             return 0;
         OPENSSL_free(b->ptr);
 
         wbuf->alloced = num;
         wbuf->buff[0] = '\0';
 
         b->ptr = (char *)wbuf;
     }
 
     ebcdic2ascii(wbuf->buff, in, inl);
 
     ret = BIO_write(b->next_bio, wbuf->buff, inl);
 
     return (ret);
 }
 
 static long ebcdic_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     long ret;
 
     if (b->next_bio == NULL)
         return (0);
     switch (cmd) {
     case BIO_CTRL_DUP:
         ret = 0L;
         break;
     default:
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     }
     return (ret);
 }
 
 static int ebcdic_gets(BIO *bp, char *buf, int size)
 {
     int i, ret = 0;
     if (bp->next_bio == NULL)
         return (0);
 /*      return(BIO_gets(bp->next_bio,buf,size));*/
     for (i = 0; i < size - 1; ++i) {
         ret = ebcdic_read(bp, &buf[i], 1);
         if (ret <= 0)
             break;
         else if (buf[i] == '\n') {
             ++i;
             break;
         }
     }
     if (i < size)
         buf[i] = '\0';
     return (ret < 0 && i == 0) ? ret : i;
 }
 
 static int ebcdic_puts(BIO *bp, const char *str)
 {
     if (bp->next_bio == NULL)
         return (0);
     return ebcdic_write(bp, str, strlen(str));
 }
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
 
 /* This is a context that we pass to callbacks */
 typedef struct tlsextctx_st {
     char *servername;
     BIO *biodebug;
     int extension_error;
 } tlsextctx;
 
 static int MS_CALLBACK ssl_servername_cb(SSL *s, int *ad, void *arg)
 {
     tlsextctx *p = (tlsextctx *) arg;
     const char *servername = SSL_get_servername(s, TLSEXT_NAMETYPE_host_name);
     if (servername && p->biodebug)
         BIO_printf(p->biodebug, "Hostname in TLS extension: \"%s\"\n",
                    servername);
 
     if (!p->servername)
         return SSL_TLSEXT_ERR_NOACK;
 
     if (servername) {
         if (strcasecmp(servername, p->servername))
             return p->extension_error;
         if (ctx2) {
             BIO_printf(p->biodebug, "Switching server context.\n");
             SSL_set_SSL_CTX(s, ctx2);
         }
     }
     return SSL_TLSEXT_ERR_OK;
 }
 
 /* Structure passed to cert status callback */
 
 typedef struct tlsextstatusctx_st {
     /* Default responder to use */
     char *host, *path, *port;
     int use_ssl;
     int timeout;
     BIO *err;
     int verbose;
 } tlsextstatusctx;
 
 static tlsextstatusctx tlscstatp = { NULL, NULL, NULL, 0, -1, NULL, 0 };
 
 /*
  * Certificate Status callback. This is called when a client includes a
  * certificate status request extension. This is a simplified version. It
  * examines certificates each time and makes one OCSP responder query for
  * each request. A full version would store details such as the OCSP
  * certificate IDs and minimise the number of OCSP responses by caching them
  * until they were considered "expired".
  */
 
 static int cert_status_cb(SSL *s, void *arg)
 {
     tlsextstatusctx *srctx = arg;
     BIO *err = srctx->err;
     char *host, *port, *path;
     int use_ssl;
     unsigned char *rspder = NULL;
     int rspderlen;
     STACK_OF(OPENSSL_STRING) *aia = NULL;
     X509 *x = NULL;
     X509_STORE_CTX inctx;
     X509_OBJECT obj;
     OCSP_REQUEST *req = NULL;
     OCSP_RESPONSE *resp = NULL;
     OCSP_CERTID *id = NULL;
     STACK_OF(X509_EXTENSION) *exts;
     int ret = SSL_TLSEXT_ERR_NOACK;
     int i;
 # if 0
     STACK_OF(OCSP_RESPID) *ids;
     SSL_get_tlsext_status_ids(s, &ids);
     BIO_printf(err, "cert_status: received %d ids\n",
                sk_OCSP_RESPID_num(ids));
 # endif
     if (srctx->verbose)
         BIO_puts(err, "cert_status: callback called\n");
     /* Build up OCSP query from server certificate */
     x = SSL_get_certificate(s);
     aia = X509_get1_ocsp(x);
     if (aia) {
         if (!OCSP_parse_url(sk_OPENSSL_STRING_value(aia, 0),
                             &host, &port, &path, &use_ssl)) {
             BIO_puts(err, "cert_status: can't parse AIA URL\n");
             goto err;
         }
         if (srctx->verbose)
             BIO_printf(err, "cert_status: AIA URL: %s\n",
                        sk_OPENSSL_STRING_value(aia, 0));
     } else {
         if (!srctx->host) {
             BIO_puts(srctx->err,
                      "cert_status: no AIA and no default responder URL\n");
             goto done;
         }
         host = srctx->host;
         path = srctx->path;
         port = srctx->port;
         use_ssl = srctx->use_ssl;
     }
 
     if (!X509_STORE_CTX_init(&inctx,
                              SSL_CTX_get_cert_store(SSL_get_SSL_CTX(s)),
                              NULL, NULL))
         goto err;
     if (X509_STORE_get_by_subject(&inctx, X509_LU_X509,
                                   X509_get_issuer_name(x), &obj) <= 0) {
         BIO_puts(err, "cert_status: Can't retrieve issuer certificate.\n");
         X509_STORE_CTX_cleanup(&inctx);
         goto done;
     }
     req = OCSP_REQUEST_new();
     if (!req)
         goto err;
     id = OCSP_cert_to_id(NULL, x, obj.data.x509);
     X509_free(obj.data.x509);
     X509_STORE_CTX_cleanup(&inctx);
     if (!id)
         goto err;
     if (!OCSP_request_add0_id(req, id))
         goto err;
     id = NULL;
     /* Add any extensions to the request */
     SSL_get_tlsext_status_exts(s, &exts);
     for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
         X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
         if (!OCSP_REQUEST_add_ext(req, ext, -1))
             goto err;
     }
     resp = process_responder(err, req, host, path, port, use_ssl, NULL,
                              srctx->timeout);
     if (!resp) {
         BIO_puts(err, "cert_status: error querying responder\n");
         goto done;
     }
     rspderlen = i2d_OCSP_RESPONSE(resp, &rspder);
     if (rspderlen <= 0)
         goto err;
     SSL_set_tlsext_status_ocsp_resp(s, rspder, rspderlen);
     if (srctx->verbose) {
         BIO_puts(err, "cert_status: ocsp response sent:\n");
         OCSP_RESPONSE_print(err, resp, 2);
     }
     ret = SSL_TLSEXT_ERR_OK;
  done:
     if (ret != SSL_TLSEXT_ERR_OK)
         ERR_print_errors(err);
     if (aia) {
         OPENSSL_free(host);
         OPENSSL_free(path);
         OPENSSL_free(port);
         X509_email_free(aia);
     }
     if (id)
         OCSP_CERTID_free(id);
     if (req)
         OCSP_REQUEST_free(req);
     if (resp)
         OCSP_RESPONSE_free(resp);
     return ret;
  err:
     ret = SSL_TLSEXT_ERR_ALERT_FATAL;
     goto done;
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /* This is the context that we pass to next_proto_cb */
 typedef struct tlsextnextprotoctx_st {
     unsigned char *data;
     unsigned int len;
 } tlsextnextprotoctx;
 
 static int next_proto_cb(SSL *s, const unsigned char **data,
                          unsigned int *len, void *arg)
 {
     tlsextnextprotoctx *next_proto = arg;
 
     *data = next_proto->data;
     *len = next_proto->len;
 
     return SSL_TLSEXT_ERR_OK;
 }
 # endif                         /* ndef OPENSSL_NO_NEXTPROTONEG */
 
 #endif
 
 int MAIN(int, char **);
 
 #ifndef OPENSSL_NO_JPAKE
 static char *jpake_secret = NULL;
 #endif
 #ifndef OPENSSL_NO_SRP
 static srpsrvparm srp_callback_parm;
 #endif
 #ifndef OPENSSL_NO_SRTP
 static char *srtp_profiles = NULL;
 #endif
 
 int MAIN(int argc, char *argv[])
 {
     X509_VERIFY_PARAM *vpm = NULL;
     int badarg = 0;
     short port = PORT;
     char *CApath = NULL, *CAfile = NULL;
     unsigned char *context = NULL;
     char *dhfile = NULL;
 #ifndef OPENSSL_NO_ECDH
     char *named_curve = NULL;
 #endif
     int badop = 0, bugs = 0;
     int ret = 1;
     int off = 0;
     int no_tmp_rsa = 0, no_dhe = 0, nocert = 0;
 #ifndef OPENSSL_NO_ECDH
     int no_ecdhe = 0;
 #endif
     int state = 0;
     const SSL_METHOD *meth = NULL;
     int socket_type = SOCK_STREAM;
     ENGINE *e = NULL;
     char *inrand = NULL;
     int s_cert_format = FORMAT_PEM, s_key_format = FORMAT_PEM;
     char *passarg = NULL, *pass = NULL;
     char *dpassarg = NULL, *dpass = NULL;
     int s_dcert_format = FORMAT_PEM, s_dkey_format = FORMAT_PEM;
     X509 *s_cert = NULL, *s_dcert = NULL;
     EVP_PKEY *s_key = NULL, *s_dkey = NULL;
     int no_cache = 0;
 #ifndef OPENSSL_NO_TLSEXT
     EVP_PKEY *s_key2 = NULL;
     X509 *s_cert2 = NULL;
     tlsextctx tlsextcbp = { NULL, NULL, SSL_TLSEXT_ERR_ALERT_WARNING };
 # ifndef OPENSSL_NO_NEXTPROTONEG
     const char *next_proto_neg_in = NULL;
     tlsextnextprotoctx next_proto;
 # endif
 #endif
 #ifndef OPENSSL_NO_PSK
     /* by default do not send a PSK identity hint */
     static char *psk_identity_hint = NULL;
 #endif
 #ifndef OPENSSL_NO_SRP
     char *srpuserseed = NULL;
     char *srp_verifier_file = NULL;
 #endif
     meth = SSLv23_server_method();
 
     local_argc = argc;
     local_argv = argv;
 
     apps_startup();
 #ifdef MONOLITH
     s_server_init();
 #endif
 
     if (bio_err == NULL)
         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
 
     if (!load_config(bio_err, NULL))
         goto end;
 
     verify_depth = 0;
 #ifdef FIONBIO
     s_nbio = 0;
 #endif
     s_nbio_test = 0;
 
     argc--;
     argv++;
 
     while (argc >= 1) {
         if ((strcmp(*argv, "-port") == 0) || (strcmp(*argv, "-accept") == 0)) {
             if (--argc < 1)
                 goto bad;
             if (!extract_port(*(++argv), &port))
                 goto bad;
         } else if (strcmp(*argv, "-verify") == 0) {
             s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
             if (--argc < 1)
                 goto bad;
             verify_depth = atoi(*(++argv));
             BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
         } else if (strcmp(*argv, "-Verify") == 0) {
             s_server_verify =
                 SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
                 SSL_VERIFY_CLIENT_ONCE;
             if (--argc < 1)
                 goto bad;
             verify_depth = atoi(*(++argv));
             BIO_printf(bio_err,
                        "verify depth is %d, must return a certificate\n",
                        verify_depth);
         } else if (strcmp(*argv, "-context") == 0) {
             if (--argc < 1)
                 goto bad;
             context = (unsigned char *)*(++argv);
         } else if (strcmp(*argv, "-cert") == 0) {
             if (--argc < 1)
                 goto bad;
             s_cert_file = *(++argv);
         } else if (strcmp(*argv, "-certform") == 0) {
             if (--argc < 1)
                 goto bad;
             s_cert_format = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-key") == 0) {
             if (--argc < 1)
                 goto bad;
             s_key_file = *(++argv);
         } else if (strcmp(*argv, "-keyform") == 0) {
             if (--argc < 1)
                 goto bad;
             s_key_format = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-pass") == 0) {
             if (--argc < 1)
                 goto bad;
             passarg = *(++argv);
         } else if (strcmp(*argv, "-dhparam") == 0) {
             if (--argc < 1)
                 goto bad;
             dhfile = *(++argv);
         }
 #ifndef OPENSSL_NO_ECDH
         else if (strcmp(*argv, "-named_curve") == 0) {
             if (--argc < 1)
                 goto bad;
             named_curve = *(++argv);
         }
 #endif
         else if (strcmp(*argv, "-dcertform") == 0) {
             if (--argc < 1)
                 goto bad;
             s_dcert_format = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-dcert") == 0) {
             if (--argc < 1)
                 goto bad;
             s_dcert_file = *(++argv);
         } else if (strcmp(*argv, "-dkeyform") == 0) {
             if (--argc < 1)
                 goto bad;
             s_dkey_format = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-dpass") == 0) {
             if (--argc < 1)
                 goto bad;
             dpassarg = *(++argv);
         } else if (strcmp(*argv, "-dkey") == 0) {
             if (--argc < 1)
                 goto bad;
             s_dkey_file = *(++argv);
         } else if (strcmp(*argv, "-nocert") == 0) {
             nocert = 1;
         } else if (strcmp(*argv, "-CApath") == 0) {
             if (--argc < 1)
                 goto bad;
             CApath = *(++argv);
         } else if (strcmp(*argv, "-no_cache") == 0)
             no_cache = 1;
         else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm)) {
             if (badarg)
                 goto bad;
             continue;
         } else if (strcmp(*argv, "-verify_return_error") == 0)
             verify_return_error = 1;
         else if (strcmp(*argv, "-serverpref") == 0) {
             off |= SSL_OP_CIPHER_SERVER_PREFERENCE;
         } else if (strcmp(*argv, "-legacy_renegotiation") == 0)
             off |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
         else if (strcmp(*argv, "-cipher") == 0) {
             if (--argc < 1)
                 goto bad;
             cipher = *(++argv);
         } else if (strcmp(*argv, "-CAfile") == 0) {
             if (--argc < 1)
                 goto bad;
             CAfile = *(++argv);
         }
 #ifdef FIONBIO
         else if (strcmp(*argv, "-nbio") == 0) {
             s_nbio = 1;
         }
 #endif
         else if (strcmp(*argv, "-nbio_test") == 0) {
 #ifdef FIONBIO
             s_nbio = 1;
 #endif
             s_nbio_test = 1;
         } else if (strcmp(*argv, "-debug") == 0) {
             s_debug = 1;
         }
 #ifndef OPENSSL_NO_TLSEXT
         else if (strcmp(*argv, "-tlsextdebug") == 0)
             s_tlsextdebug = 1;
         else if (strcmp(*argv, "-status") == 0)
             s_tlsextstatus = 1;
         else if (strcmp(*argv, "-status_verbose") == 0) {
             s_tlsextstatus = 1;
             tlscstatp.verbose = 1;
         } else if (!strcmp(*argv, "-status_timeout")) {
             s_tlsextstatus = 1;
             if (--argc < 1)
                 goto bad;
             tlscstatp.timeout = atoi(*(++argv));
         } else if (!strcmp(*argv, "-status_url")) {
             s_tlsextstatus = 1;
             if (--argc < 1)
                 goto bad;
             if (!OCSP_parse_url(*(++argv),
                                 &tlscstatp.host,
                                 &tlscstatp.port,
                                 &tlscstatp.path, &tlscstatp.use_ssl)) {
                 BIO_printf(bio_err, "Error parsing URL\n");
                 goto bad;
             }
         }
 #endif
         else if (strcmp(*argv, "-msg") == 0) {
             s_msg = 1;
         } else if (strcmp(*argv, "-hack") == 0) {
             hack = 1;
         } else if (strcmp(*argv, "-state") == 0) {
             state = 1;
         } else if (strcmp(*argv, "-crlf") == 0) {
             s_crlf = 1;
         } else if (strcmp(*argv, "-quiet") == 0) {
             s_quiet = 1;
         } else if (strcmp(*argv, "-bugs") == 0) {
             bugs = 1;
         } else if (strcmp(*argv, "-no_tmp_rsa") == 0) {
             no_tmp_rsa = 1;
         } else if (strcmp(*argv, "-no_dhe") == 0) {
             no_dhe = 1;
         }
 #ifndef OPENSSL_NO_ECDH
         else if (strcmp(*argv, "-no_ecdhe") == 0) {
             no_ecdhe = 1;
         }
 #endif
 #ifndef OPENSSL_NO_PSK
         else if (strcmp(*argv, "-psk_hint") == 0) {
             if (--argc < 1)
                 goto bad;
             psk_identity_hint = *(++argv);
         } else if (strcmp(*argv, "-psk") == 0) {
             size_t i;
 
             if (--argc < 1)
                 goto bad;
             psk_key = *(++argv);
             for (i = 0; i < strlen(psk_key); i++) {
                 if (isxdigit((unsigned char)psk_key[i]))
                     continue;
                 BIO_printf(bio_err, "Not a hex number '%s'\n", *argv);
                 goto bad;
             }
         }
 #endif
 #ifndef OPENSSL_NO_SRP
         else if (strcmp(*argv, "-srpvfile") == 0) {
             if (--argc < 1)
                 goto bad;
             srp_verifier_file = *(++argv);
             meth = TLSv1_server_method();
         } else if (strcmp(*argv, "-srpuserseed") == 0) {
             if (--argc < 1)
                 goto bad;
             srpuserseed = *(++argv);
             meth = TLSv1_server_method();
         }
 #endif
         else if (strcmp(*argv, "-www") == 0) {
             www = 1;
         } else if (strcmp(*argv, "-WWW") == 0) {
             www = 2;
         } else if (strcmp(*argv, "-HTTP") == 0) {
             www = 3;
         } else if (strcmp(*argv, "-no_ssl2") == 0) {
             off |= SSL_OP_NO_SSLv2;
         } else if (strcmp(*argv, "-no_ssl3") == 0) {
             off |= SSL_OP_NO_SSLv3;
         } else if (strcmp(*argv, "-no_tls1") == 0) {
             off |= SSL_OP_NO_TLSv1;
         } else if (strcmp(*argv, "-no_tls1_1") == 0) {
             off |= SSL_OP_NO_TLSv1_1;
         } else if (strcmp(*argv, "-no_tls1_2") == 0) {
             off |= SSL_OP_NO_TLSv1_2;
         } else if (strcmp(*argv, "-no_comp") == 0) {
             off |= SSL_OP_NO_COMPRESSION;
         }
 #ifndef OPENSSL_NO_TLSEXT
         else if (strcmp(*argv, "-no_ticket") == 0) {
             off |= SSL_OP_NO_TICKET;
         }
 #endif
 #ifndef OPENSSL_NO_SSL2
         else if (strcmp(*argv, "-ssl2") == 0) {
             meth = SSLv2_server_method();
         }
 #endif
 #ifndef OPENSSL_NO_SSL3_METHOD
         else if (strcmp(*argv, "-ssl3") == 0) {
             meth = SSLv3_server_method();
         }
 #endif
 #ifndef OPENSSL_NO_TLS1
         else if (strcmp(*argv, "-tls1") == 0) {
             meth = TLSv1_server_method();
         } else if (strcmp(*argv, "-tls1_1") == 0) {
             meth = TLSv1_1_server_method();
         } else if (strcmp(*argv, "-tls1_2") == 0) {
             meth = TLSv1_2_server_method();
         }
 #endif
 #ifndef OPENSSL_NO_DTLS1
         else if (strcmp(*argv, "-dtls1") == 0) {
             meth = DTLSv1_server_method();
             socket_type = SOCK_DGRAM;
         } else if (strcmp(*argv, "-timeout") == 0)
             enable_timeouts = 1;
         else if (strcmp(*argv, "-mtu") == 0) {
             if (--argc < 1)
                 goto bad;
             socket_mtu = atol(*(++argv));
         } else if (strcmp(*argv, "-chain") == 0)
             cert_chain = 1;
 #endif
         else if (strcmp(*argv, "-id_prefix") == 0) {
             if (--argc < 1)
                 goto bad;
             session_id_prefix = *(++argv);
         }
 #ifndef OPENSSL_NO_ENGINE
         else if (strcmp(*argv, "-engine") == 0) {
             if (--argc < 1)
                 goto bad;
             engine_id = *(++argv);
         }
 #endif
         else if (strcmp(*argv, "-rand") == 0) {
             if (--argc < 1)
                 goto bad;
             inrand = *(++argv);
         }
 #ifndef OPENSSL_NO_TLSEXT
         else if (strcmp(*argv, "-servername") == 0) {
             if (--argc < 1)
                 goto bad;
             tlsextcbp.servername = *(++argv);
         } else if (strcmp(*argv, "-servername_fatal") == 0) {
             tlsextcbp.extension_error = SSL_TLSEXT_ERR_ALERT_FATAL;
         } else if (strcmp(*argv, "-cert2") == 0) {
             if (--argc < 1)
                 goto bad;
             s_cert_file2 = *(++argv);
         } else if (strcmp(*argv, "-key2") == 0) {
             if (--argc < 1)
                 goto bad;
             s_key_file2 = *(++argv);
         }
 # ifndef OPENSSL_NO_NEXTPROTONEG
         else if (strcmp(*argv, "-nextprotoneg") == 0) {
             if (--argc < 1)
                 goto bad;
             next_proto_neg_in = *(++argv);
         }
 # endif
 #endif
 #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
         else if (strcmp(*argv, "-jpake") == 0) {
             if (--argc < 1)
                 goto bad;
             jpake_secret = *(++argv);
         }
 #endif
 #ifndef OPENSSL_NO_SRTP
         else if (strcmp(*argv, "-use_srtp") == 0) {
             if (--argc < 1)
                 goto bad;
             srtp_profiles = *(++argv);
         }
 #endif
         else if (strcmp(*argv, "-keymatexport") == 0) {
             if (--argc < 1)
                 goto bad;
             keymatexportlabel = *(++argv);
         } else if (strcmp(*argv, "-keymatexportlen") == 0) {
             if (--argc < 1)
                 goto bad;
             keymatexportlen = atoi(*(++argv));
             if (keymatexportlen == 0)
                 goto bad;
         } else {
             BIO_printf(bio_err, "unknown option %s\n", *argv);
             badop = 1;
             break;
         }
         argc--;
         argv++;
     }
     if (badop) {
  bad:
         sv_usage();
         goto end;
     }
 #ifndef OPENSSL_NO_DTLS1
     if (www && socket_type == SOCK_DGRAM) {
         BIO_printf(bio_err, "Can't use -HTTP, -www or -WWW with DTLS\n");
         goto end;
     }
 #endif
 
 #if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
     if (jpake_secret) {
         if (psk_key) {
             BIO_printf(bio_err, "Can't use JPAKE and PSK together\n");
             goto end;
         }
         psk_identity = "JPAKE";
         if (cipher) {
             BIO_printf(bio_err, "JPAKE sets cipher to PSK\n");
             goto end;
         }
         cipher = "PSK";
     }
 #endif
 
     SSL_load_error_strings();
     OpenSSL_add_ssl_algorithms();
 
 #ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine_id, 1);
 #endif
 
     if (!app_passwd(bio_err, passarg, dpassarg, &pass, &dpass)) {
         BIO_printf(bio_err, "Error getting password\n");
         goto end;
     }
 
     if (s_key_file == NULL)
         s_key_file = s_cert_file;
 #ifndef OPENSSL_NO_TLSEXT
     if (s_key_file2 == NULL)
         s_key_file2 = s_cert_file2;
 #endif
 
     if (nocert == 0) {
         s_key = load_key(bio_err, s_key_file, s_key_format, 0, pass, e,
                          "server certificate private key file");
         if (!s_key) {
             ERR_print_errors(bio_err);
             goto end;
         }
 
         s_cert = load_cert(bio_err, s_cert_file, s_cert_format,
                            NULL, e, "server certificate file");
 
         if (!s_cert) {
             ERR_print_errors(bio_err);
             goto end;
         }
 #ifndef OPENSSL_NO_TLSEXT
         if (tlsextcbp.servername) {
             s_key2 = load_key(bio_err, s_key_file2, s_key_format, 0, pass, e,
                               "second server certificate private key file");
             if (!s_key2) {
                 ERR_print_errors(bio_err);
                 goto end;
             }
 
             s_cert2 = load_cert(bio_err, s_cert_file2, s_cert_format,
                                 NULL, e, "second server certificate file");
 
             if (!s_cert2) {
                 ERR_print_errors(bio_err);
                 goto end;
             }
         }
 #endif
     }
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     if (next_proto_neg_in) {
         unsigned short len;
         next_proto.data = next_protos_parse(&len, next_proto_neg_in);
         if (next_proto.data == NULL)
             goto end;
         next_proto.len = len;
     } else {
         next_proto.data = NULL;
     }
 #endif
 
     if (s_dcert_file) {
 
         if (s_dkey_file == NULL)
             s_dkey_file = s_dcert_file;
 
         s_dkey = load_key(bio_err, s_dkey_file, s_dkey_format,
                           0, dpass, e, "second certificate private key file");
         if (!s_dkey) {
             ERR_print_errors(bio_err);
             goto end;
         }
 
         s_dcert = load_cert(bio_err, s_dcert_file, s_dcert_format,
                             NULL, e, "second server certificate file");
 
         if (!s_dcert) {
             ERR_print_errors(bio_err);
             goto end;
         }
 
     }
 
     if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
         && !RAND_status()) {
         BIO_printf(bio_err,
                    "warning, not much extra random data, consider using the -rand option\n");
     }
     if (inrand != NULL)
         BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                    app_RAND_load_files(inrand));
 
     if (bio_s_out == NULL) {
         if (s_quiet && !s_debug && !s_msg) {
             bio_s_out = BIO_new(BIO_s_null());
         } else {
             if (bio_s_out == NULL)
                 bio_s_out = BIO_new_fp(stdout, BIO_NOCLOSE);
         }
     }
 #if !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
     if (nocert)
 #endif
     {
         s_cert_file = NULL;
         s_key_file = NULL;
         s_dcert_file = NULL;
         s_dkey_file = NULL;
 #ifndef OPENSSL_NO_TLSEXT
         s_cert_file2 = NULL;
         s_key_file2 = NULL;
 #endif
     }
 
     ctx = SSL_CTX_new(meth);
     if (ctx == NULL) {
         ERR_print_errors(bio_err);
         goto end;
     }
     if (session_id_prefix) {
         if (strlen(session_id_prefix) >= 32)
             BIO_printf(bio_err,
                        "warning: id_prefix is too long, only one new session will be possible\n");
         else if (strlen(session_id_prefix) >= 16)
             BIO_printf(bio_err,
                        "warning: id_prefix is too long if you use SSLv2\n");
         if (!SSL_CTX_set_generate_session_id(ctx, generate_session_id)) {
             BIO_printf(bio_err, "error setting 'id_prefix'\n");
             ERR_print_errors(bio_err);
             goto end;
         }
         BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
     }
     SSL_CTX_set_quiet_shutdown(ctx, 1);
     if (bugs)
         SSL_CTX_set_options(ctx, SSL_OP_ALL);
     if (hack)
         SSL_CTX_set_options(ctx, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
     SSL_CTX_set_options(ctx, off);
 
     if (state)
         SSL_CTX_set_info_callback(ctx, apps_ssl_info_callback);
     if (no_cache)
         SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
     else
         SSL_CTX_sess_set_cache_size(ctx, 128);
 
 #ifndef OPENSSL_NO_SRTP
     if (srtp_profiles != NULL)
         SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
 #endif
 
 #if 0
     if (cipher == NULL)
         cipher = getenv("SSL_CIPHER");
 #endif
 
 #if 0
     if (s_cert_file == NULL) {
         BIO_printf(bio_err,
                    "You must specify a certificate file for the server to use\n");
         goto end;
     }
 #endif
 
     if ((!SSL_CTX_load_verify_locations(ctx, CAfile, CApath)) ||
         (!SSL_CTX_set_default_verify_paths(ctx))) {
         /* BIO_printf(bio_err,"X509_load_verify_locations\n"); */
         ERR_print_errors(bio_err);
         /* goto end; */
     }
     if (vpm)
         SSL_CTX_set1_param(ctx, vpm);
 
 #ifndef OPENSSL_NO_TLSEXT
     if (s_cert2) {
         ctx2 = SSL_CTX_new(meth);
         if (ctx2 == NULL) {
             ERR_print_errors(bio_err);
             goto end;
         }
     }
 
     if (ctx2) {
         BIO_printf(bio_s_out, "Setting secondary ctx parameters\n");
 
         if (session_id_prefix) {
             if (strlen(session_id_prefix) >= 32)
                 BIO_printf(bio_err,
                            "warning: id_prefix is too long, only one new session will be possible\n");
             else if (strlen(session_id_prefix) >= 16)
                 BIO_printf(bio_err,
                            "warning: id_prefix is too long if you use SSLv2\n");
             if (!SSL_CTX_set_generate_session_id(ctx2, generate_session_id)) {
                 BIO_printf(bio_err, "error setting 'id_prefix'\n");
                 ERR_print_errors(bio_err);
                 goto end;
             }
             BIO_printf(bio_err, "id_prefix '%s' set.\n", session_id_prefix);
         }
         SSL_CTX_set_quiet_shutdown(ctx2, 1);
         if (bugs)
             SSL_CTX_set_options(ctx2, SSL_OP_ALL);
         if (hack)
             SSL_CTX_set_options(ctx2, SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
         SSL_CTX_set_options(ctx2, off);
 
         if (state)
             SSL_CTX_set_info_callback(ctx2, apps_ssl_info_callback);
 
         if (no_cache)
             SSL_CTX_set_session_cache_mode(ctx2, SSL_SESS_CACHE_OFF);
         else
             SSL_CTX_sess_set_cache_size(ctx2, 128);
 
         if ((!SSL_CTX_load_verify_locations(ctx2, CAfile, CApath)) ||
             (!SSL_CTX_set_default_verify_paths(ctx2))) {
             ERR_print_errors(bio_err);
         }
         if (vpm)
             SSL_CTX_set1_param(ctx2, vpm);
     }
 # ifndef OPENSSL_NO_NEXTPROTONEG
     if (next_proto.data)
         SSL_CTX_set_next_protos_advertised_cb(ctx, next_proto_cb,
                                               &next_proto);
 # endif
 #endif
 
 #ifndef OPENSSL_NO_DH
     if (!no_dhe) {
         DH *dh = NULL;
 
         if (dhfile)
             dh = load_dh_param(dhfile);
         else if (s_cert_file)
             dh = load_dh_param(s_cert_file);
 
         if (dh != NULL) {
             BIO_printf(bio_s_out, "Setting temp DH parameters\n");
         } else {
             BIO_printf(bio_s_out, "Using default temp DH parameters\n");
             dh = get_dh2048();
             if (dh == NULL) {
                 ERR_print_errors(bio_err);
                 goto end;
             }
         }
         (void)BIO_flush(bio_s_out);
 
         SSL_CTX_set_tmp_dh(ctx, dh);
 # ifndef OPENSSL_NO_TLSEXT
         if (ctx2) {
             if (!dhfile) {
                 DH *dh2 = load_dh_param(s_cert_file2);
                 if (dh2 != NULL) {
                     BIO_printf(bio_s_out, "Setting temp DH parameters\n");
                     (void)BIO_flush(bio_s_out);
 
                     DH_free(dh);
                     dh = dh2;
                 }
             }
             SSL_CTX_set_tmp_dh(ctx2, dh);
         }
 # endif
         DH_free(dh);
     }
 #endif
 
 #ifndef OPENSSL_NO_ECDH
     if (!no_ecdhe) {
         EC_KEY *ecdh = NULL;
 
         if (named_curve) {
             int nid = OBJ_sn2nid(named_curve);
 
             if (nid == 0) {
                 BIO_printf(bio_err, "unknown curve name (%s)\n", named_curve);
                 goto end;
             }
             ecdh = EC_KEY_new_by_curve_name(nid);
             if (ecdh == NULL) {
                 BIO_printf(bio_err, "unable to create curve (%s)\n",
                            named_curve);
                 goto end;
             }
         }
 
         if (ecdh != NULL) {
             BIO_printf(bio_s_out, "Setting temp ECDH parameters\n");
         } else {
             BIO_printf(bio_s_out, "Using default temp ECDH parameters\n");
             ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
             if (ecdh == NULL) {
                 BIO_printf(bio_err, "unable to create curve (nistp256)\n");
                 goto end;
             }
         }
         (void)BIO_flush(bio_s_out);
 
         SSL_CTX_set_tmp_ecdh(ctx, ecdh);
 # ifndef OPENSSL_NO_TLSEXT
         if (ctx2)
             SSL_CTX_set_tmp_ecdh(ctx2, ecdh);
 # endif
         EC_KEY_free(ecdh);
     }
 #endif
 
     if (!set_cert_key_stuff(ctx, s_cert, s_key))
         goto end;
 #ifndef OPENSSL_NO_TLSEXT
     if (ctx2 && !set_cert_key_stuff(ctx2, s_cert2, s_key2))
         goto end;
 #endif
     if (s_dcert != NULL) {
         if (!set_cert_key_stuff(ctx, s_dcert, s_dkey))
             goto end;
     }
 #ifndef OPENSSL_NO_RSA
 # if 1
     if (!no_tmp_rsa) {
         SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
 #  ifndef OPENSSL_NO_TLSEXT
         if (ctx2)
             SSL_CTX_set_tmp_rsa_callback(ctx2, tmp_rsa_cb);
 #  endif
     }
 # else
     if (!no_tmp_rsa && SSL_CTX_need_tmp_RSA(ctx)) {
         RSA *rsa;
 
         BIO_printf(bio_s_out, "Generating temp (512 bit) RSA key...");
         BIO_flush(bio_s_out);
 
         rsa = RSA_generate_key(512, RSA_F4, NULL);
 
         if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
             ERR_print_errors(bio_err);
             goto end;
         }
 #  ifndef OPENSSL_NO_TLSEXT
         if (ctx2) {
             if (!SSL_CTX_set_tmp_rsa(ctx2, rsa)) {
                 ERR_print_errors(bio_err);
                 goto end;
             }
         }
 #  endif
         RSA_free(rsa);
         BIO_printf(bio_s_out, "\n");
     }
 # endif
 #endif
 
 #ifndef OPENSSL_NO_PSK
 # ifdef OPENSSL_NO_JPAKE
     if (psk_key != NULL)
 # else
     if (psk_key != NULL || jpake_secret)
 # endif
     {
         if (s_debug)
             BIO_printf(bio_s_out,
                        "PSK key given or JPAKE in use, setting server callback\n");
         SSL_CTX_set_psk_server_callback(ctx, psk_server_cb);
     }
 
     if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) {
         BIO_printf(bio_err, "error setting PSK identity hint to context\n");
         ERR_print_errors(bio_err);
         goto end;
     }
 #endif
 
     if (cipher != NULL) {
         if (!SSL_CTX_set_cipher_list(ctx, cipher)) {
             BIO_printf(bio_err, "error setting cipher list\n");
             ERR_print_errors(bio_err);
             goto end;
         }
 #ifndef OPENSSL_NO_TLSEXT
         if (ctx2 && !SSL_CTX_set_cipher_list(ctx2, cipher)) {
             BIO_printf(bio_err, "error setting cipher list\n");
             ERR_print_errors(bio_err);
             goto end;
         }
 #endif
     }
     SSL_CTX_set_verify(ctx, s_server_verify, verify_callback);
     SSL_CTX_set_session_id_context(ctx, (void *)&s_server_session_id_context,
                                    sizeof s_server_session_id_context);
 
     /* Set DTLS cookie generation and verification callbacks */
     SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie_callback);
     SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie_callback);
 
 #ifndef OPENSSL_NO_TLSEXT
     if (ctx2) {
         SSL_CTX_set_verify(ctx2, s_server_verify, verify_callback);
         SSL_CTX_set_session_id_context(ctx2,
                                        (void *)&s_server_session_id_context,
                                        sizeof s_server_session_id_context);
 
         tlsextcbp.biodebug = bio_s_out;
         SSL_CTX_set_tlsext_servername_callback(ctx2, ssl_servername_cb);
         SSL_CTX_set_tlsext_servername_arg(ctx2, &tlsextcbp);
         SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
         SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
     }
 #endif
 
 #ifndef OPENSSL_NO_SRP
     if (srp_verifier_file != NULL) {
         srp_callback_parm.vb = SRP_VBASE_new(srpuserseed);
         srp_callback_parm.user = NULL;
         srp_callback_parm.login = NULL;
         if ((ret =
              SRP_VBASE_init(srp_callback_parm.vb,
                             srp_verifier_file)) != SRP_NO_ERROR) {
             BIO_printf(bio_err,
                        "Cannot initialize SRP verifier file \"%s\":ret=%d\n",
                        srp_verifier_file, ret);
             goto end;
         }
         SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, verify_callback);
         SSL_CTX_set_srp_cb_arg(ctx, &srp_callback_parm);
         SSL_CTX_set_srp_username_callback(ctx, ssl_srp_server_param_cb);
     } else
 #endif
     if (CAfile != NULL) {
         SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAfile));
 #ifndef OPENSSL_NO_TLSEXT
         if (ctx2)
             SSL_CTX_set_client_CA_list(ctx2, SSL_load_client_CA_file(CAfile));
 #endif
     }
 
     BIO_printf(bio_s_out, "ACCEPT\n");
     (void)BIO_flush(bio_s_out);
     if (www)
         do_server(port, socket_type, &accept_socket, www_body, context);
     else
         do_server(port, socket_type, &accept_socket, sv_body, context);
     print_stats(bio_s_out, ctx);
     ret = 0;
  end:
     if (ctx != NULL)
         SSL_CTX_free(ctx);
     if (s_cert)
         X509_free(s_cert);
     if (s_dcert)
         X509_free(s_dcert);
     if (s_key)
         EVP_PKEY_free(s_key);
     if (s_dkey)
         EVP_PKEY_free(s_dkey);
     if (pass)
         OPENSSL_free(pass);
     if (dpass)
         OPENSSL_free(dpass);
     if (vpm)
         X509_VERIFY_PARAM_free(vpm);
 #ifndef OPENSSL_NO_TLSEXT
     if (tlscstatp.host)
         OPENSSL_free(tlscstatp.host);
     if (tlscstatp.port)
         OPENSSL_free(tlscstatp.port);
     if (tlscstatp.path)
         OPENSSL_free(tlscstatp.path);
     if (ctx2 != NULL)
         SSL_CTX_free(ctx2);
     if (s_cert2)
         X509_free(s_cert2);
     if (s_key2)
         EVP_PKEY_free(s_key2);
 #endif
     if (bio_s_out != NULL) {
         BIO_free(bio_s_out);
         bio_s_out = NULL;
     }
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }
 
 static void print_stats(BIO *bio, SSL_CTX *ssl_ctx)
 {
     BIO_printf(bio, "%4ld items in the session cache\n",
                SSL_CTX_sess_number(ssl_ctx));
     BIO_printf(bio, "%4ld client connects (SSL_connect())\n",
                SSL_CTX_sess_connect(ssl_ctx));
     BIO_printf(bio, "%4ld client renegotiates (SSL_connect())\n",
                SSL_CTX_sess_connect_renegotiate(ssl_ctx));
     BIO_printf(bio, "%4ld client connects that finished\n",
                SSL_CTX_sess_connect_good(ssl_ctx));
     BIO_printf(bio, "%4ld server accepts (SSL_accept())\n",
                SSL_CTX_sess_accept(ssl_ctx));
     BIO_printf(bio, "%4ld server renegotiates (SSL_accept())\n",
                SSL_CTX_sess_accept_renegotiate(ssl_ctx));
     BIO_printf(bio, "%4ld server accepts that finished\n",
                SSL_CTX_sess_accept_good(ssl_ctx));
     BIO_printf(bio, "%4ld session cache hits\n", SSL_CTX_sess_hits(ssl_ctx));
     BIO_printf(bio, "%4ld session cache misses\n",
                SSL_CTX_sess_misses(ssl_ctx));
     BIO_printf(bio, "%4ld session cache timeouts\n",
                SSL_CTX_sess_timeouts(ssl_ctx));
     BIO_printf(bio, "%4ld callback cache hits\n",
                SSL_CTX_sess_cb_hits(ssl_ctx));
     BIO_printf(bio, "%4ld cache full overflows (%ld allowed)\n",
                SSL_CTX_sess_cache_full(ssl_ctx),
                SSL_CTX_sess_get_cache_size(ssl_ctx));
 }
 
 static int sv_body(char *hostname, int s, unsigned char *context)
 {
     char *buf = NULL;
     fd_set readfds;
     int ret = 1, width;
     int k, i;
     unsigned long l;
     SSL *con = NULL;
     BIO *sbio;
 #ifndef OPENSSL_NO_KRB5
     KSSL_CTX *kctx;
 #endif
     struct timeval timeout;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
     struct timeval tv;
 #else
     struct timeval *timeoutp;
 #endif
 
     if ((buf = OPENSSL_malloc(bufsize)) == NULL) {
         BIO_printf(bio_err, "out of memory\n");
         goto err;
     }
 #ifdef FIONBIO
     if (s_nbio) {
         unsigned long sl = 1;
 
         if (!s_quiet)
             BIO_printf(bio_err, "turning on non blocking io\n");
         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
             ERR_print_errors(bio_err);
     }
 #endif
 
     if (con == NULL) {
         con = SSL_new(ctx);
 #ifndef OPENSSL_NO_TLSEXT
         if (s_tlsextdebug) {
             SSL_set_tlsext_debug_callback(con, tlsext_cb);
             SSL_set_tlsext_debug_arg(con, bio_s_out);
         }
         if (s_tlsextstatus) {
             SSL_CTX_set_tlsext_status_cb(ctx, cert_status_cb);
             tlscstatp.err = bio_err;
             SSL_CTX_set_tlsext_status_arg(ctx, &tlscstatp);
         }
 #endif
 #ifndef OPENSSL_NO_KRB5
         if ((kctx = kssl_ctx_new()) != NULL) {
             SSL_set0_kssl_ctx(con, kctx);
             kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
             kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
         }
 #endif                          /* OPENSSL_NO_KRB5 */
         if (context)
             SSL_set_session_id_context(con, context, strlen((char *)context));
     }
     SSL_clear(con);
 #if 0
 # ifdef TLSEXT_TYPE_opaque_prf_input
     SSL_set_tlsext_opaque_prf_input(con, "Test server", 11);
 # endif
 #endif
 
     if (SSL_version(con) == DTLS1_VERSION) {
 
         sbio = BIO_new_dgram(s, BIO_NOCLOSE);
 
         if (enable_timeouts) {
             timeout.tv_sec = 0;
             timeout.tv_usec = DGRAM_RCV_TIMEOUT;
             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
 
             timeout.tv_sec = 0;
             timeout.tv_usec = DGRAM_SND_TIMEOUT;
             BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
         }
 
         if (socket_mtu) {
             if (socket_mtu < DTLS_get_link_min_mtu(con)) {
                 BIO_printf(bio_err, "MTU too small. Must be at least %ld\n",
                            DTLS_get_link_min_mtu(con));
                 ret = -1;
                 BIO_free(sbio);
                 goto err;
             }
             SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
             if (!DTLS_set_link_mtu(con, socket_mtu)) {
                 BIO_printf(bio_err, "Failed to set MTU\n");
                 ret = -1;
                 BIO_free(sbio);
                 goto err;
             }
         } else
             /* want to do MTU discovery */
             BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
 
         /* turn on cookie exchange */
         SSL_set_options(con, SSL_OP_COOKIE_EXCHANGE);
     } else
         sbio = BIO_new_socket(s, BIO_NOCLOSE);
 
     if (s_nbio_test) {
         BIO *test;
 
         test = BIO_new(BIO_f_nbio_test());
         sbio = BIO_push(test, sbio);
     }
 #ifndef OPENSSL_NO_JPAKE
     if (jpake_secret)
         jpake_server_auth(bio_s_out, sbio, jpake_secret);
 #endif
 
     SSL_set_bio(con, sbio, sbio);
     SSL_set_accept_state(con);
     /* SSL_set_fd(con,s); */
 
     if (s_debug) {
         SSL_set_debug(con, 1);
         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
     }
     if (s_msg) {
         SSL_set_msg_callback(con, msg_cb);
         SSL_set_msg_callback_arg(con, bio_s_out);
     }
 #ifndef OPENSSL_NO_TLSEXT
     if (s_tlsextdebug) {
         SSL_set_tlsext_debug_callback(con, tlsext_cb);
         SSL_set_tlsext_debug_arg(con, bio_s_out);
     }
 #endif
 
     width = s + 1;
     for (;;) {
         int read_from_terminal;
         int read_from_sslcon;
 
         read_from_terminal = 0;
         read_from_sslcon = SSL_pending(con);
 
         if (!read_from_sslcon) {
             FD_ZERO(&readfds);
 #if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined(OPENSSL_SYS_BEOS_R5)
             openssl_fdset(fileno(stdin), &readfds);
 #endif
             openssl_fdset(s, &readfds);
             /*
              * Note: under VMS with SOCKETSHR the second parameter is
              * currently of type (int *) whereas under other systems it is
              * (void *) if you don't have a cast it will choke the compiler:
              * if you do have a cast then you can either go for (int *) or
              * (void *).
              */
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE)
             /*
              * Under DOS (non-djgpp) and Windows we can't select on stdin:
              * only on sockets. As a workaround we timeout the select every
              * second and check for any keypress. In a proper Windows
              * application we wouldn't do this because it is inefficient.
              */
             tv.tv_sec = 1;
             tv.tv_usec = 0;
             i = select(width, (void *)&readfds, NULL, NULL, &tv);
             if ((i < 0) || (!i && !_kbhit()))
                 continue;
             if (_kbhit())
                 read_from_terminal = 1;
 #elif defined(OPENSSL_SYS_BEOS_R5)
             /* Under BeOS-R5 the situation is similar to DOS */
             tv.tv_sec = 1;
             tv.tv_usec = 0;
             (void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
             i = select(width, (void *)&readfds, NULL, NULL, &tv);
             if ((i < 0) || (!i && read(fileno(stdin), buf, 0) < 0))
                 continue;
             if (read(fileno(stdin), buf, 0) >= 0)
                 read_from_terminal = 1;
             (void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
             if ((SSL_version(con) == DTLS1_VERSION) &&
                 DTLSv1_get_timeout(con, &timeout))
                 timeoutp = &timeout;
             else
                 timeoutp = NULL;
 
             i = select(width, (void *)&readfds, NULL, NULL, timeoutp);
 
             if ((SSL_version(con) == DTLS1_VERSION)
                 && DTLSv1_handle_timeout(con) > 0) {
                 BIO_printf(bio_err, "TIMEOUT occured\n");
             }
 
             if (i <= 0)
                 continue;
             if (FD_ISSET(fileno(stdin), &readfds))
                 read_from_terminal = 1;
 #endif
             if (FD_ISSET(s, &readfds))
                 read_from_sslcon = 1;
         }
         if (read_from_terminal) {
             if (s_crlf) {
                 int j, lf_num;
 
                 i = raw_read_stdin(buf, bufsize / 2);
                 lf_num = 0;
                 /* both loops are skipped when i <= 0 */
                 for (j = 0; j < i; j++)
                     if (buf[j] == '\n')
                         lf_num++;
                 for (j = i - 1; j >= 0; j--) {
                     buf[j + lf_num] = buf[j];
                     if (buf[j] == '\n') {
                         lf_num--;
                         i++;
                         buf[j + lf_num] = '\r';
                     }
                 }
                 assert(lf_num == 0);
             } else
                 i = raw_read_stdin(buf, bufsize);
             if (!s_quiet) {
                 if ((i <= 0) || (buf[0] == 'Q')) {
                     BIO_printf(bio_s_out, "DONE\n");
                     SHUTDOWN(s);
                     close_accept_socket();
                     ret = -11;
                     goto err;
                 }
                 if ((i <= 0) || (buf[0] == 'q')) {
                     BIO_printf(bio_s_out, "DONE\n");
                     if (SSL_version(con) != DTLS1_VERSION)
                         SHUTDOWN(s);
                     /*
                      * close_accept_socket(); ret= -11;
                      */
                     goto err;
                 }
 #ifndef OPENSSL_NO_HEARTBEATS
                 if ((buf[0] == 'B') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
                     BIO_printf(bio_err, "HEARTBEATING\n");
                     SSL_heartbeat(con);
                     i = 0;
                     continue;
                 }
 #endif
                 if ((buf[0] == 'r') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
                     SSL_renegotiate(con);
                     i = SSL_do_handshake(con);
                     printf("SSL_do_handshake -> %d\n", i);
                     i = 0;      /* 13; */
                     continue;
                     /*
                      * strcpy(buf,"server side RE-NEGOTIATE\n");
                      */
                 }
                 if ((buf[0] == 'R') && ((buf[1] == '\n') || (buf[1] == '\r'))) {
                     SSL_set_verify(con,
                                    SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE,
                                    NULL);
                     SSL_renegotiate(con);
                     i = SSL_do_handshake(con);
                     printf("SSL_do_handshake -> %d\n", i);
                     i = 0;      /* 13; */
                     continue;
                     /*
                      * strcpy(buf,"server side RE-NEGOTIATE asking for client
                      * cert\n");
                      */
                 }
                 if (buf[0] == 'P') {
                     static const char *str = "Lets print some clear text\n";
                     BIO_write(SSL_get_wbio(con), str, strlen(str));
                 }
                 if (buf[0] == 'S') {
                     print_stats(bio_s_out, SSL_get_SSL_CTX(con));
                 }
             }
 #ifdef CHARSET_EBCDIC
             ebcdic2ascii(buf, buf, i);
 #endif
             l = k = 0;
             for (;;) {
                 /* should do a select for the write */
 #ifdef RENEG
                 {
                     static count = 0;
                     if (++count == 100) {
                         count = 0;
                         SSL_renegotiate(con);
                     }
                 }
 #endif
                 k = SSL_write(con, &(buf[l]), (unsigned int)i);
 #ifndef OPENSSL_NO_SRP
                 while (SSL_get_error(con, k) == SSL_ERROR_WANT_X509_LOOKUP) {
                     BIO_printf(bio_s_out, "LOOKUP renego during write\n");
                     SRP_user_pwd_free(srp_callback_parm.user);
                     srp_callback_parm.user =
                         SRP_VBASE_get1_by_user(srp_callback_parm.vb,
                                                srp_callback_parm.login);
                     if (srp_callback_parm.user)
                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
                                    srp_callback_parm.user->info);
                     else
                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
                     k = SSL_write(con, &(buf[l]), (unsigned int)i);
                 }
 #endif
                 switch (SSL_get_error(con, k)) {
                 case SSL_ERROR_NONE:
                     break;
                 case SSL_ERROR_WANT_WRITE:
                 case SSL_ERROR_WANT_READ:
                 case SSL_ERROR_WANT_X509_LOOKUP:
                     BIO_printf(bio_s_out, "Write BLOCK\n");
                     break;
                 case SSL_ERROR_SYSCALL:
                 case SSL_ERROR_SSL:
                     BIO_printf(bio_s_out, "ERROR\n");
                     ERR_print_errors(bio_err);
                     ret = 1;
                     goto err;
                     /* break; */
                 case SSL_ERROR_ZERO_RETURN:
                     BIO_printf(bio_s_out, "DONE\n");
                     ret = 1;
                     goto err;
                 }
                 if (k > 0) {
                     l += k;
                     i -= k;
                 }
                 if (i <= 0)
                     break;
             }
         }
         if (read_from_sslcon) {
             if (!SSL_is_init_finished(con)) {
                 i = init_ssl_connection(con);
 
                 if (i < 0) {
                     ret = 0;
                     goto err;
                 } else if (i == 0) {
                     ret = 1;
                     goto err;
                 }
             } else {
  again:
                 i = SSL_read(con, (char *)buf, bufsize);
 #ifndef OPENSSL_NO_SRP
                 while (SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
                     SRP_user_pwd_free(srp_callback_parm.user);
                     srp_callback_parm.user =
                         SRP_VBASE_get1_by_user(srp_callback_parm.vb,
                                                srp_callback_parm.login);
                     if (srp_callback_parm.user)
                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
                                    srp_callback_parm.user->info);
                     else
                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
                     i = SSL_read(con, (char *)buf, bufsize);
                 }
 #endif
                 switch (SSL_get_error(con, i)) {
                 case SSL_ERROR_NONE:
 #ifdef CHARSET_EBCDIC
                     ascii2ebcdic(buf, buf, i);
 #endif
                     raw_write_stdout(buf, (unsigned int)i);
                     if (SSL_pending(con))
                         goto again;
                     break;
                 case SSL_ERROR_WANT_WRITE:
                 case SSL_ERROR_WANT_READ:
                     BIO_printf(bio_s_out, "Read BLOCK\n");
                     break;
                 case SSL_ERROR_SYSCALL:
                 case SSL_ERROR_SSL:
                     BIO_printf(bio_s_out, "ERROR\n");
                     ERR_print_errors(bio_err);
                     ret = 1;
                     goto err;
                 case SSL_ERROR_ZERO_RETURN:
                     BIO_printf(bio_s_out, "DONE\n");
                     ret = 1;
                     goto err;
                 }
             }
         }
     }
  err:
     if (con != NULL) {
         BIO_printf(bio_s_out, "shutting down SSL\n");
 #if 1
         SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
 #else
         SSL_shutdown(con);
 #endif
         SSL_free(con);
     }
     BIO_printf(bio_s_out, "CONNECTION CLOSED\n");
     if (buf != NULL) {
         OPENSSL_cleanse(buf, bufsize);
         OPENSSL_free(buf);
     }
     if (ret >= 0)
         BIO_printf(bio_s_out, "ACCEPT\n");
     return (ret);
 }
 
 static void close_accept_socket(void)
 {
     BIO_printf(bio_err, "shutdown accept socket\n");
     if (accept_socket >= 0) {
         SHUTDOWN2(accept_socket);
     }
 }
 
 static int init_ssl_connection(SSL *con)
 {
     int i;
     const char *str;
     X509 *peer;
     long verify_error;
     MS_STATIC char buf[BUFSIZ];
 #ifndef OPENSSL_NO_KRB5
     char *client_princ;
 #endif
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     const unsigned char *next_proto_neg;
     unsigned next_proto_neg_len;
 #endif
     unsigned char *exportedkeymat;
 
     i = SSL_accept(con);
 #ifndef OPENSSL_NO_SRP
     while (i <= 0 && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
         BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
                    srp_callback_parm.login);
         SRP_user_pwd_free(srp_callback_parm.user);
         srp_callback_parm.user =
             SRP_VBASE_get1_by_user(srp_callback_parm.vb,
                                    srp_callback_parm.login);
         if (srp_callback_parm.user)
             BIO_printf(bio_s_out, "LOOKUP done %s\n",
                        srp_callback_parm.user->info);
         else
             BIO_printf(bio_s_out, "LOOKUP not successful\n");
         i = SSL_accept(con);
     }
 #endif
     if (i <= 0) {
         if (BIO_sock_should_retry(i)) {
             BIO_printf(bio_s_out, "DELAY\n");
             return (1);
         }
 
         BIO_printf(bio_err, "ERROR\n");
         verify_error = SSL_get_verify_result(con);
         if (verify_error != X509_V_OK) {
             BIO_printf(bio_err, "verify error:%s\n",
                        X509_verify_cert_error_string(verify_error));
         } else
             ERR_print_errors(bio_err);
         return (0);
     }
 
     PEM_write_bio_SSL_SESSION(bio_s_out, SSL_get_session(con));
 
     peer = SSL_get_peer_certificate(con);
     if (peer != NULL) {
         BIO_printf(bio_s_out, "Client certificate\n");
         PEM_write_bio_X509(bio_s_out, peer);
         X509_NAME_oneline(X509_get_subject_name(peer), buf, sizeof buf);
         BIO_printf(bio_s_out, "subject=%s\n", buf);
         X509_NAME_oneline(X509_get_issuer_name(peer), buf, sizeof buf);
         BIO_printf(bio_s_out, "issuer=%s\n", buf);
         X509_free(peer);
     }
 
     if (SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL)
         BIO_printf(bio_s_out, "Shared ciphers:%s\n", buf);
     str = SSL_CIPHER_get_name(SSL_get_current_cipher(con));
     BIO_printf(bio_s_out, "CIPHER is %s\n", (str != NULL) ? str : "(NONE)");
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     SSL_get0_next_proto_negotiated(con, &next_proto_neg, &next_proto_neg_len);
     if (next_proto_neg) {
         BIO_printf(bio_s_out, "NEXTPROTO is ");
         BIO_write(bio_s_out, next_proto_neg, next_proto_neg_len);
         BIO_printf(bio_s_out, "\n");
     }
 #endif
 #ifndef OPENSSL_NO_SRTP
     {
         SRTP_PROTECTION_PROFILE *srtp_profile
             = SSL_get_selected_srtp_profile(con);
 
         if (srtp_profile)
             BIO_printf(bio_s_out, "SRTP Extension negotiated, profile=%s\n",
                        srtp_profile->name);
     }
 #endif
     if (SSL_cache_hit(con))
         BIO_printf(bio_s_out, "Reused session-id\n");
     if (SSL_ctrl(con, SSL_CTRL_GET_FLAGS, 0, NULL) &
         TLS1_FLAGS_TLS_PADDING_BUG)
         BIO_printf(bio_s_out, "Peer has incorrect TLSv1 block padding\n");
 #ifndef OPENSSL_NO_KRB5
     client_princ = kssl_ctx_get0_client_princ(SSL_get0_kssl_ctx(con));
     if (client_princ != NULL) {
         BIO_printf(bio_s_out, "Kerberos peer principal is %s\n",
                    client_princ);
     }
 #endif                          /* OPENSSL_NO_KRB5 */
     BIO_printf(bio_s_out, "Secure Renegotiation IS%s supported\n",
                SSL_get_secure_renegotiation_support(con) ? "" : " NOT");
     if (keymatexportlabel != NULL) {
         BIO_printf(bio_s_out, "Keying material exporter:\n");
         BIO_printf(bio_s_out, "    Label: '%s'\n", keymatexportlabel);
         BIO_printf(bio_s_out, "    Length: %i bytes\n", keymatexportlen);
         exportedkeymat = OPENSSL_malloc(keymatexportlen);
         if (exportedkeymat != NULL) {
             if (!SSL_export_keying_material(con, exportedkeymat,
                                             keymatexportlen,
                                             keymatexportlabel,
                                             strlen(keymatexportlabel),
                                             NULL, 0, 0)) {
                 BIO_printf(bio_s_out, "    Error\n");
             } else {
                 BIO_printf(bio_s_out, "    Keying material: ");
                 for (i = 0; i < keymatexportlen; i++)
                     BIO_printf(bio_s_out, "%02X", exportedkeymat[i]);
                 BIO_printf(bio_s_out, "\n");
             }
             OPENSSL_free(exportedkeymat);
         }
     }
 
     return (1);
 }
 
 #ifndef OPENSSL_NO_DH
 static DH *load_dh_param(const char *dhfile)
 {
     DH *ret = NULL;
     BIO *bio;
 
     if ((bio = BIO_new_file(dhfile, "r")) == NULL)
         goto err;
     ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
  err:
     if (bio != NULL)
         BIO_free(bio);
     return (ret);
 }
 #endif
 #ifndef OPENSSL_NO_KRB5
 char *client_princ;
 #endif
 
 #if 0
 static int load_CA(SSL_CTX *ctx, char *file)
 {
     FILE *in;
     X509 *x = NULL;
 
     if ((in = fopen(file, "r")) == NULL)
         return (0);
 
     for (;;) {
         if (PEM_read_X509(in, &x, NULL) == NULL)
             break;
         SSL_CTX_add_client_CA(ctx, x);
     }
     if (x != NULL)
         X509_free(x);
     fclose(in);
     return (1);
 }
 #endif
 
 static int www_body(char *hostname, int s, unsigned char *context)
 {
     char *buf = NULL;
     int ret = 1;
     int i, j, k, dot;
     SSL *con;
     const SSL_CIPHER *c;
     BIO *io, *ssl_bio, *sbio;
 #ifndef OPENSSL_NO_KRB5
     KSSL_CTX *kctx;
 #endif
 
     buf = OPENSSL_malloc(bufsize);
     if (buf == NULL)
         return (0);
     io = BIO_new(BIO_f_buffer());
     ssl_bio = BIO_new(BIO_f_ssl());
     if ((io == NULL) || (ssl_bio == NULL))
         goto err;
 
 #ifdef FIONBIO
     if (s_nbio) {
         unsigned long sl = 1;
 
         if (!s_quiet)
             BIO_printf(bio_err, "turning on non blocking io\n");
         if (BIO_socket_ioctl(s, FIONBIO, &sl) < 0)
             ERR_print_errors(bio_err);
     }
 #endif
 
     /* lets make the output buffer a reasonable size */
     if (!BIO_set_write_buffer_size(io, bufsize))
         goto err;
 
     if ((con = SSL_new(ctx)) == NULL)
         goto err;
 #ifndef OPENSSL_NO_TLSEXT
     if (s_tlsextdebug) {
         SSL_set_tlsext_debug_callback(con, tlsext_cb);
         SSL_set_tlsext_debug_arg(con, bio_s_out);
     }
 #endif
 #ifndef OPENSSL_NO_KRB5
     if ((kctx = kssl_ctx_new()) != NULL) {
         kssl_ctx_setstring(kctx, KSSL_SERVICE, KRB5SVC);
         kssl_ctx_setstring(kctx, KSSL_KEYTAB, KRB5KEYTAB);
     }
 #endif                          /* OPENSSL_NO_KRB5 */
     if (context)
         SSL_set_session_id_context(con, context, strlen((char *)context));
 
     sbio = BIO_new_socket(s, BIO_NOCLOSE);
     if (s_nbio_test) {
         BIO *test;
 
         test = BIO_new(BIO_f_nbio_test());
         sbio = BIO_push(test, sbio);
     }
     SSL_set_bio(con, sbio, sbio);
     SSL_set_accept_state(con);
 
     /* SSL_set_fd(con,s); */
     BIO_set_ssl(ssl_bio, con, BIO_CLOSE);
     BIO_push(io, ssl_bio);
 #ifdef CHARSET_EBCDIC
     io = BIO_push(BIO_new(BIO_f_ebcdic_filter()), io);
 #endif
 
     if (s_debug) {
         SSL_set_debug(con, 1);
         BIO_set_callback(SSL_get_rbio(con), bio_dump_callback);
         BIO_set_callback_arg(SSL_get_rbio(con), (char *)bio_s_out);
     }
     if (s_msg) {
         SSL_set_msg_callback(con, msg_cb);
         SSL_set_msg_callback_arg(con, bio_s_out);
     }
 
     for (;;) {
         if (hack) {
             i = SSL_accept(con);
 #ifndef OPENSSL_NO_SRP
             while (i <= 0
                    && SSL_get_error(con, i) == SSL_ERROR_WANT_X509_LOOKUP) {
                 BIO_printf(bio_s_out, "LOOKUP during accept %s\n",
                            srp_callback_parm.login);
                 SRP_user_pwd_free(srp_callback_parm.user);
                 srp_callback_parm.user =
                     SRP_VBASE_get1_by_user(srp_callback_parm.vb,
                                            srp_callback_parm.login);
                 if (srp_callback_parm.user)
                     BIO_printf(bio_s_out, "LOOKUP done %s\n",
                                srp_callback_parm.user->info);
                 else
                     BIO_printf(bio_s_out, "LOOKUP not successful\n");
                 i = SSL_accept(con);
             }
 #endif
             switch (SSL_get_error(con, i)) {
             case SSL_ERROR_NONE:
                 break;
             case SSL_ERROR_WANT_WRITE:
             case SSL_ERROR_WANT_READ:
             case SSL_ERROR_WANT_X509_LOOKUP:
                 continue;
             case SSL_ERROR_SYSCALL:
             case SSL_ERROR_SSL:
             case SSL_ERROR_ZERO_RETURN:
                 ret = 1;
                 goto err;
                 /* break; */
             }
 
             SSL_renegotiate(con);
             SSL_write(con, NULL, 0);
         }
 
         i = BIO_gets(io, buf, bufsize - 1);
         if (i < 0) {            /* error */
             if (!BIO_should_retry(io)) {
                 if (!s_quiet)
                     ERR_print_errors(bio_err);
                 goto err;
             } else {
                 BIO_printf(bio_s_out, "read R BLOCK\n");
 #ifndef OPENSSL_NO_SRP
                 if (BIO_should_io_special(io)
                     && BIO_get_retry_reason(io) == BIO_RR_SSL_X509_LOOKUP) {
                     BIO_printf(bio_s_out, "LOOKUP renego during read\n");
                     SRP_user_pwd_free(srp_callback_parm.user);
                     srp_callback_parm.user =
                         SRP_VBASE_get1_by_user(srp_callback_parm.vb,
                                                srp_callback_parm.login);
                     if (srp_callback_parm.user)
                         BIO_printf(bio_s_out, "LOOKUP done %s\n",
                                    srp_callback_parm.user->info);
                     else
                         BIO_printf(bio_s_out, "LOOKUP not successful\n");
                     continue;
                 }
 #endif
 #if defined(OPENSSL_SYS_NETWARE)
                 delay(1000);
 #elif !defined(OPENSSL_SYS_MSDOS) && !defined(__DJGPP__)
                 sleep(1);
 #endif
                 continue;
             }
         } else if (i == 0) {    /* end of input */
             ret = 1;
             goto end;
         }
 
         /* else we have data */
         if (((www == 1) && (strncmp("GET ", buf, 4) == 0)) ||
             ((www == 2) && (strncmp("GET /stats ", buf, 11) == 0))) {
             char *p;
             X509 *peer;
             STACK_OF(SSL_CIPHER) *sk;
             static const char *space = "                          ";
 
             BIO_puts(io,
                      "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
             BIO_puts(io, "<HTML><BODY BGCOLOR=\"#ffffff\">\n");
             BIO_puts(io, "<pre>\n");
 /*                      BIO_puts(io,SSLeay_version(SSLEAY_VERSION));*/
             BIO_puts(io, "\n");
             for (i = 0; i < local_argc; i++) {
                 BIO_puts(io, local_argv[i]);
                 BIO_write(io, " ", 1);
             }
             BIO_puts(io, "\n");
 
             BIO_printf(io,
                        "Secure Renegotiation IS%s supported\n",
                        SSL_get_secure_renegotiation_support(con) ?
                        "" : " NOT");
 
             /*
              * The following is evil and should not really be done
              */
             BIO_printf(io, "Ciphers supported in s_server binary\n");
             sk = SSL_get_ciphers(con);
             j = sk_SSL_CIPHER_num(sk);
             for (i = 0; i < j; i++) {
                 c = sk_SSL_CIPHER_value(sk, i);
                 BIO_printf(io, "%-11s:%-25s",
                            SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
                 if ((((i + 1) % 2) == 0) && (i + 1 != j))
                     BIO_puts(io, "\n");
             }
             BIO_puts(io, "\n");
             p = SSL_get_shared_ciphers(con, buf, bufsize);
             if (p != NULL) {
                 BIO_printf(io,
                            "---\nCiphers common between both SSL end points:\n");
                 j = i = 0;
                 while (*p) {
                     if (*p == ':') {
                         BIO_write(io, space, 26 - j);
                         i++;
                         j = 0;
                         BIO_write(io, ((i % 3) ? " " : "\n"), 1);
                     } else {
                         BIO_write(io, p, 1);
                         j++;
                     }
                     p++;
                 }
                 BIO_puts(io, "\n");
             }
             BIO_printf(io, (SSL_cache_hit(con)
                             ? "---\nReused, " : "---\nNew, "));
             c = SSL_get_current_cipher(con);
             BIO_printf(io, "%s, Cipher is %s\n",
                        SSL_CIPHER_get_version(c), SSL_CIPHER_get_name(c));
             SSL_SESSION_print(io, SSL_get_session(con));
             BIO_printf(io, "---\n");
             print_stats(io, SSL_get_SSL_CTX(con));
             BIO_printf(io, "---\n");
             peer = SSL_get_peer_certificate(con);
             if (peer != NULL) {
                 BIO_printf(io, "Client certificate\n");
                 X509_print(io, peer);
                 PEM_write_bio_X509(io, peer);
             } else
                 BIO_puts(io, "no client certificate available\n");
             BIO_puts(io, "</BODY></HTML>\r\n\r\n");
             break;
         } else if ((www == 2 || www == 3)
                    && (strncmp("GET /", buf, 5) == 0)) {
             BIO *file;
             char *p, *e;
             static const char *text =
                 "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n";
 
             /* skip the '/' */
             p = &(buf[5]);
 
             dot = 1;
             for (e = p; *e != '\0'; e++) {
                 if (e[0] == ' ')
                     break;
 
                 switch (dot) {
                 case 1:
                     dot = (e[0] == '.') ? 2 : 0;
                     break;
                 case 2:
                     dot = (e[0] == '.') ? 3 : 0;
                     break;
                 case 3:
                     dot = (e[0] == '/') ? -1 : 0;
                     break;
                 }
                 if (dot == 0)
                     dot = (e[0] == '/') ? 1 : 0;
             }
             dot = (dot == 3) || (dot == -1); /* filename contains ".."
                                               * component */
 
             if (*e == '\0') {
                 BIO_puts(io, text);
                 BIO_printf(io, "'%s' is an invalid file name\r\n", p);
                 break;
             }
             *e = '\0';
 
             if (dot) {
                 BIO_puts(io, text);
                 BIO_printf(io, "'%s' contains '..' reference\r\n", p);
                 break;
             }
 
             if (*p == '/') {
                 BIO_puts(io, text);
                 BIO_printf(io, "'%s' is an invalid path\r\n", p);
                 break;
             }
 #if 0
             /* append if a directory lookup */
             if (e[-1] == '/')
                 strcat(p, "index.html");
 #endif
 
             /* if a directory, do the index thang */
             if (app_isdir(p) > 0) {
 #if 0                           /* must check buffer size */
                 strcat(p, "/index.html");
 #else
                 BIO_puts(io, text);
                 BIO_printf(io, "'%s' is a directory\r\n", p);
                 break;
 #endif
             }
 
             if ((file = BIO_new_file(p, "r")) == NULL) {
                 BIO_puts(io, text);
                 BIO_printf(io, "Error opening '%s'\r\n", p);
                 ERR_print_errors(io);
                 break;
             }
 
             if (!s_quiet)
                 BIO_printf(bio_err, "FILE:%s\n", p);
 
             if (www == 2) {
                 i = strlen(p);
                 if (((i > 5) && (strcmp(&(p[i - 5]), ".html") == 0)) ||
                     ((i > 4) && (strcmp(&(p[i - 4]), ".php") == 0)) ||
                     ((i > 4) && (strcmp(&(p[i - 4]), ".htm") == 0)))
                     BIO_puts(io,
                              "HTTP/1.0 200 ok\r\nContent-type: text/html\r\n\r\n");
                 else
                     BIO_puts(io,
                              "HTTP/1.0 200 ok\r\nContent-type: text/plain\r\n\r\n");
             }
             /* send the file */
             for (;;) {
                 i = BIO_read(file, buf, bufsize);
                 if (i <= 0)
                     break;
 
 #ifdef RENEG
                 total_bytes += i;
                 fprintf(stderr, "%d\n", i);
                 if (total_bytes > 3 * 1024) {
                     total_bytes = 0;
                     fprintf(stderr, "RENEGOTIATE\n");
                     SSL_renegotiate(con);
                 }
 #endif
 
                 for (j = 0; j < i;) {
 #ifdef RENEG
                     {
                         static count = 0;
                         if (++count == 13) {
                             SSL_renegotiate(con);
                         }
                     }
 #endif
                     k = BIO_write(io, &(buf[j]), i - j);
                     if (k <= 0) {
                         if (!BIO_should_retry(io))
                             goto write_error;
                         else {
                             BIO_printf(bio_s_out, "rwrite W BLOCK\n");
                         }
                     } else {
                         j += k;
                     }
                 }
             }
  write_error:
             BIO_free(file);
             break;
         }
     }
 
     for (;;) {
         i = (int)BIO_flush(io);
         if (i <= 0) {
             if (!BIO_should_retry(io))
                 break;
         } else
             break;
     }
  end:
 #if 1
     /* make sure we re-use sessions */
     SSL_set_shutdown(con, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
 #else
     /* This kills performance */
     /*
      * SSL_shutdown(con); A shutdown gets sent in the BIO_free_all(io)
      * procession
      */
 #endif
 
  err:
 
     if (ret >= 0)
         BIO_printf(bio_s_out, "ACCEPT\n");
 
     if (buf != NULL)
         OPENSSL_free(buf);
     if (io != NULL)
         BIO_free_all(io);
 /*      if (ssl_bio != NULL) BIO_free(ssl_bio);*/
     return (ret);
 }
 
 #ifndef OPENSSL_NO_RSA
 static RSA MS_CALLBACK *tmp_rsa_cb(SSL *s, int is_export, int keylength)
 {
     BIGNUM *bn = NULL;
     static RSA *rsa_tmp = NULL;
 
     if (!rsa_tmp && ((bn = BN_new()) == NULL))
         BIO_printf(bio_err, "Allocation error in generating RSA key\n");
     if (!rsa_tmp && bn) {
         if (!s_quiet) {
             BIO_printf(bio_err, "Generating temp (%d bit) RSA key...",
                        keylength);
             (void)BIO_flush(bio_err);
         }
         if (!BN_set_word(bn, RSA_F4) || ((rsa_tmp = RSA_new()) == NULL) ||
             !RSA_generate_key_ex(rsa_tmp, keylength, bn, NULL)) {
             if (rsa_tmp)
                 RSA_free(rsa_tmp);
             rsa_tmp = NULL;
         }
         if (!s_quiet) {
             BIO_printf(bio_err, "\n");
             (void)BIO_flush(bio_err);
         }
         BN_free(bn);
     }
     return (rsa_tmp);
 }
 #endif
 
 #define MAX_SESSION_ID_ATTEMPTS 10
 static int generate_session_id(const SSL *ssl, unsigned char *id,
                                unsigned int *id_len)
 {
     unsigned int count = 0;
     do {
-        if (RAND_pseudo_bytes(id, *id_len) < 0)
+        if (RAND_bytes(id, *id_len) <= 0)
             return 0;
         /*
          * Prefix the session_id with the required prefix. NB: If our prefix
          * is too long, clip it - but there will be worse effects anyway, eg.
          * the server could only possibly create 1 session ID (ie. the
          * prefix!) so all future session negotiations will fail due to
          * conflicts.
          */
         memcpy(id, session_id_prefix,
                (strlen(session_id_prefix) < *id_len) ?
                strlen(session_id_prefix) : *id_len);
     }
     while (SSL_has_matching_session_id(ssl, id, *id_len) &&
            (++count < MAX_SESSION_ID_ATTEMPTS));
     if (count >= MAX_SESSION_ID_ATTEMPTS)
         return 0;
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/apps/x509.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/apps/x509.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/apps/x509.c	(revision 306191)
@@ -1,1215 +1,1221 @@
 /* apps/x509.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.]
  */
 
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #ifdef OPENSSL_NO_STDIO
 # define APPS_WIN16
 #endif
 #include "apps.h"
 #include <openssl/bio.h>
 #include <openssl/asn1.h>
 #include <openssl/err.h>
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
 #include <openssl/pem.h>
 #ifndef OPENSSL_NO_RSA
 # include <openssl/rsa.h>
 #endif
 #ifndef OPENSSL_NO_DSA
 # include <openssl/dsa.h>
 #endif
 
 #undef PROG
 #define PROG x509_main
 
 #undef POSTFIX
 #define POSTFIX ".srl"
 #define DEF_DAYS        30
 
 static const char *x509_usage[] = {
     "usage: x509 args\n",
     " -inform arg     - input format - default PEM (one of DER, NET or PEM)\n",
     " -outform arg    - output format - default PEM (one of DER, NET or PEM)\n",
     " -keyform arg    - private key format - default PEM\n",
     " -CAform arg     - CA format - default PEM\n",
     " -CAkeyform arg  - CA key format - default PEM\n",
     " -in arg         - input file - default stdin\n",
     " -out arg        - output file - default stdout\n",
     " -passin arg     - private key password source\n",
     " -serial         - print serial number value\n",
     " -subject_hash   - print subject hash value\n",
 #ifndef OPENSSL_NO_MD5
     " -subject_hash_old   - print old-style (MD5) subject hash value\n",
 #endif
     " -issuer_hash    - print issuer hash value\n",
 #ifndef OPENSSL_NO_MD5
     " -issuer_hash_old    - print old-style (MD5) issuer hash value\n",
 #endif
     " -hash           - synonym for -subject_hash\n",
     " -subject        - print subject DN\n",
     " -issuer         - print issuer DN\n",
     " -email          - print email address(es)\n",
     " -startdate      - notBefore field\n",
     " -enddate        - notAfter field\n",
     " -purpose        - print out certificate purposes\n",
     " -dates          - both Before and After dates\n",
     " -modulus        - print the RSA key modulus\n",
     " -pubkey         - output the public key\n",
     " -fingerprint    - print the certificate fingerprint\n",
     " -alias          - output certificate alias\n",
     " -noout          - no certificate output\n",
     " -ocspid         - print OCSP hash values for the subject name and public key\n",
     " -ocsp_uri       - print OCSP Responder URL(s)\n",
     " -trustout       - output a \"trusted\" certificate\n",
     " -clrtrust       - clear all trusted purposes\n",
     " -clrreject      - clear all rejected purposes\n",
     " -addtrust arg   - trust certificate for a given purpose\n",
     " -addreject arg  - reject certificate for a given purpose\n",
     " -setalias arg   - set certificate alias\n",
     " -days arg       - How long till expiry of a signed certificate - def 30 days\n",
     " -checkend arg   - check whether the cert expires in the next arg seconds\n",
     "                   exit 1 if so, 0 if not\n",
     " -signkey arg    - self sign cert with arg\n",
     " -x509toreq      - output a certification request object\n",
     " -req            - input is a certificate request, sign and output.\n",
     " -CA arg         - set the CA certificate, must be PEM format.\n",
     " -CAkey arg      - set the CA key, must be PEM format\n",
     "                   missing, it is assumed to be in the CA file.\n",
     " -CAcreateserial - create serial number file if it does not exist\n",
     " -CAserial arg   - serial file\n",
     " -set_serial     - serial number to use\n",
     " -text           - print the certificate in text form\n",
     " -C              - print out C code forms\n",
     " -md2/-md5/-sha1/-mdc2 - digest to use\n",
     " -extfile        - configuration file with X509V3 extensions to add\n",
     " -extensions     - section from config file with X509V3 extensions to add\n",
     " -clrext         - delete extensions before signing and input certificate\n",
     " -nameopt arg    - various certificate name options\n",
 #ifndef OPENSSL_NO_ENGINE
     " -engine e       - use engine e, possibly a hardware device.\n",
 #endif
     " -certopt arg    - various certificate text options\n",
     NULL
 };
 
 static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx);
 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
                 const EVP_MD *digest, CONF *conf, char *section);
 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
                         X509 *x, X509 *xca, EVP_PKEY *pkey,
                         STACK_OF(OPENSSL_STRING) *sigopts, char *serial,
                         int create, int days, int clrext, CONF *conf,
                         char *section, ASN1_INTEGER *sno);
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt);
 static int reqfile = 0;
 
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
 {
     ENGINE *e = NULL;
     int ret = 1;
     X509_REQ *req = NULL;
     X509 *x = NULL, *xca = NULL;
     ASN1_OBJECT *objtmp;
     STACK_OF(OPENSSL_STRING) *sigopts = NULL;
     EVP_PKEY *Upkey = NULL, *CApkey = NULL;
     ASN1_INTEGER *sno = NULL;
     int i, num, badops = 0;
     BIO *out = NULL;
     BIO *STDout = NULL;
     STACK_OF(ASN1_OBJECT) *trust = NULL, *reject = NULL;
     int informat, outformat, keyformat, CAformat, CAkeyformat;
     char *infile = NULL, *outfile = NULL, *keyfile = NULL, *CAfile = NULL;
     char *CAkeyfile = NULL, *CAserial = NULL;
     char *alias = NULL;
     int text = 0, serial = 0, subject = 0, issuer = 0, startdate =
         0, enddate = 0;
     int next_serial = 0;
     int subject_hash = 0, issuer_hash = 0, ocspid = 0;
 #ifndef OPENSSL_NO_MD5
     int subject_hash_old = 0, issuer_hash_old = 0;
 #endif
     int noout = 0, sign_flag = 0, CA_flag = 0, CA_createserial = 0, email = 0;
     int ocsp_uri = 0;
     int trustout = 0, clrtrust = 0, clrreject = 0, aliasout = 0, clrext = 0;
     int C = 0;
     int x509req = 0, days = DEF_DAYS, modulus = 0, pubkey = 0;
     int pprint = 0;
     const char **pp;
     X509_STORE *ctx = NULL;
     X509_REQ *rq = NULL;
     int fingerprint = 0;
     char buf[256];
     const EVP_MD *md_alg, *digest = NULL;
     CONF *extconf = NULL;
     char *extsect = NULL, *extfile = NULL, *passin = NULL, *passargin = NULL;
     int need_rand = 0;
     int checkend = 0, checkoffset = 0;
     unsigned long nmflag = 0, certflag = 0;
 #ifndef OPENSSL_NO_ENGINE
     char *engine = NULL;
 #endif
 
     reqfile = 0;
 
     apps_startup();
 
     if (bio_err == NULL)
         bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
 
     if (!load_config(bio_err, NULL))
         goto end;
     STDout = BIO_new_fp(stdout, BIO_NOCLOSE);
 #ifdef OPENSSL_SYS_VMS
     {
         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
         STDout = BIO_push(tmpbio, STDout);
     }
 #endif
 
     informat = FORMAT_PEM;
     outformat = FORMAT_PEM;
     keyformat = FORMAT_PEM;
     CAformat = FORMAT_PEM;
     CAkeyformat = FORMAT_PEM;
 
     ctx = X509_STORE_new();
     if (ctx == NULL)
         goto end;
     X509_STORE_set_verify_cb(ctx, callb);
 
     argc--;
     argv++;
     num = 0;
     while (argc >= 1) {
         if (strcmp(*argv, "-inform") == 0) {
             if (--argc < 1)
                 goto bad;
             informat = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-outform") == 0) {
             if (--argc < 1)
                 goto bad;
             outformat = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-keyform") == 0) {
             if (--argc < 1)
                 goto bad;
             keyformat = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-req") == 0) {
             reqfile = 1;
             need_rand = 1;
         } else if (strcmp(*argv, "-CAform") == 0) {
             if (--argc < 1)
                 goto bad;
             CAformat = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-CAkeyform") == 0) {
             if (--argc < 1)
                 goto bad;
             CAkeyformat = str2fmt(*(++argv));
         } else if (strcmp(*argv, "-sigopt") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!sigopts)
                 sigopts = sk_OPENSSL_STRING_new_null();
             if (!sigopts || !sk_OPENSSL_STRING_push(sigopts, *(++argv)))
                 goto bad;
         } else if (strcmp(*argv, "-days") == 0) {
             if (--argc < 1)
                 goto bad;
             days = atoi(*(++argv));
             if (days == 0) {
                 BIO_printf(bio_err, "bad number of days\n");
                 goto bad;
             }
         } else if (strcmp(*argv, "-passin") == 0) {
             if (--argc < 1)
                 goto bad;
             passargin = *(++argv);
         } else if (strcmp(*argv, "-extfile") == 0) {
             if (--argc < 1)
                 goto bad;
             extfile = *(++argv);
         } else if (strcmp(*argv, "-extensions") == 0) {
             if (--argc < 1)
                 goto bad;
             extsect = *(++argv);
         } else if (strcmp(*argv, "-in") == 0) {
             if (--argc < 1)
                 goto bad;
             infile = *(++argv);
         } else if (strcmp(*argv, "-out") == 0) {
             if (--argc < 1)
                 goto bad;
             outfile = *(++argv);
         } else if (strcmp(*argv, "-signkey") == 0) {
             if (--argc < 1)
                 goto bad;
             keyfile = *(++argv);
             sign_flag = ++num;
             need_rand = 1;
         } else if (strcmp(*argv, "-CA") == 0) {
             if (--argc < 1)
                 goto bad;
             CAfile = *(++argv);
             CA_flag = ++num;
             need_rand = 1;
         } else if (strcmp(*argv, "-CAkey") == 0) {
             if (--argc < 1)
                 goto bad;
             CAkeyfile = *(++argv);
         } else if (strcmp(*argv, "-CAserial") == 0) {
             if (--argc < 1)
                 goto bad;
             CAserial = *(++argv);
         } else if (strcmp(*argv, "-set_serial") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!(sno = s2i_ASN1_INTEGER(NULL, *(++argv))))
                 goto bad;
         } else if (strcmp(*argv, "-addtrust") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
                 BIO_printf(bio_err, "Invalid trust object value %s\n", *argv);
                 goto bad;
             }
             if (!trust)
                 trust = sk_ASN1_OBJECT_new_null();
             sk_ASN1_OBJECT_push(trust, objtmp);
             trustout = 1;
         } else if (strcmp(*argv, "-addreject") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!(objtmp = OBJ_txt2obj(*(++argv), 0))) {
                 BIO_printf(bio_err,
                            "Invalid reject object value %s\n", *argv);
                 goto bad;
             }
             if (!reject)
                 reject = sk_ASN1_OBJECT_new_null();
             sk_ASN1_OBJECT_push(reject, objtmp);
             trustout = 1;
         } else if (strcmp(*argv, "-setalias") == 0) {
             if (--argc < 1)
                 goto bad;
             alias = *(++argv);
             trustout = 1;
         } else if (strcmp(*argv, "-certopt") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!set_cert_ex(&certflag, *(++argv)))
                 goto bad;
         } else if (strcmp(*argv, "-nameopt") == 0) {
             if (--argc < 1)
                 goto bad;
             if (!set_name_ex(&nmflag, *(++argv)))
                 goto bad;
         }
 #ifndef OPENSSL_NO_ENGINE
         else if (strcmp(*argv, "-engine") == 0) {
             if (--argc < 1)
                 goto bad;
             engine = *(++argv);
         }
 #endif
         else if (strcmp(*argv, "-C") == 0)
             C = ++num;
         else if (strcmp(*argv, "-email") == 0)
             email = ++num;
         else if (strcmp(*argv, "-ocsp_uri") == 0)
             ocsp_uri = ++num;
         else if (strcmp(*argv, "-serial") == 0)
             serial = ++num;
         else if (strcmp(*argv, "-next_serial") == 0)
             next_serial = ++num;
         else if (strcmp(*argv, "-modulus") == 0)
             modulus = ++num;
         else if (strcmp(*argv, "-pubkey") == 0)
             pubkey = ++num;
         else if (strcmp(*argv, "-x509toreq") == 0)
             x509req = ++num;
         else if (strcmp(*argv, "-text") == 0)
             text = ++num;
         else if (strcmp(*argv, "-hash") == 0
                  || strcmp(*argv, "-subject_hash") == 0)
             subject_hash = ++num;
 #ifndef OPENSSL_NO_MD5
         else if (strcmp(*argv, "-subject_hash_old") == 0)
             subject_hash_old = ++num;
 #endif
         else if (strcmp(*argv, "-issuer_hash") == 0)
             issuer_hash = ++num;
 #ifndef OPENSSL_NO_MD5
         else if (strcmp(*argv, "-issuer_hash_old") == 0)
             issuer_hash_old = ++num;
 #endif
         else if (strcmp(*argv, "-subject") == 0)
             subject = ++num;
         else if (strcmp(*argv, "-issuer") == 0)
             issuer = ++num;
         else if (strcmp(*argv, "-fingerprint") == 0)
             fingerprint = ++num;
         else if (strcmp(*argv, "-dates") == 0) {
             startdate = ++num;
             enddate = ++num;
         } else if (strcmp(*argv, "-purpose") == 0)
             pprint = ++num;
         else if (strcmp(*argv, "-startdate") == 0)
             startdate = ++num;
         else if (strcmp(*argv, "-enddate") == 0)
             enddate = ++num;
         else if (strcmp(*argv, "-checkend") == 0) {
             if (--argc < 1)
                 goto bad;
             checkoffset = atoi(*(++argv));
             checkend = 1;
         } else if (strcmp(*argv, "-noout") == 0)
             noout = ++num;
         else if (strcmp(*argv, "-trustout") == 0)
             trustout = 1;
         else if (strcmp(*argv, "-clrtrust") == 0)
             clrtrust = ++num;
         else if (strcmp(*argv, "-clrreject") == 0)
             clrreject = ++num;
         else if (strcmp(*argv, "-alias") == 0)
             aliasout = ++num;
         else if (strcmp(*argv, "-CAcreateserial") == 0)
             CA_createserial = ++num;
         else if (strcmp(*argv, "-clrext") == 0)
             clrext = 1;
 #if 1                           /* stay backwards-compatible with 0.9.5; this
                                  * should go away soon */
         else if (strcmp(*argv, "-crlext") == 0) {
             BIO_printf(bio_err, "use -clrext instead of -crlext\n");
             clrext = 1;
         }
 #endif
         else if (strcmp(*argv, "-ocspid") == 0)
             ocspid = ++num;
         else if ((md_alg = EVP_get_digestbyname(*argv + 1))) {
             /* ok */
             digest = md_alg;
         } else {
             BIO_printf(bio_err, "unknown option %s\n", *argv);
             badops = 1;
             break;
         }
         argc--;
         argv++;
     }
 
     if (badops) {
  bad:
         for (pp = x509_usage; (*pp != NULL); pp++)
             BIO_printf(bio_err, "%s", *pp);
         goto end;
     }
 #ifndef OPENSSL_NO_ENGINE
     e = setup_engine(bio_err, engine, 0);
 #endif
 
     if (need_rand)
         app_RAND_load_file(NULL, bio_err, 0);
 
     ERR_load_crypto_strings();
 
     if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
         BIO_printf(bio_err, "Error getting password\n");
         goto end;
     }
 
     if (!X509_STORE_set_default_paths(ctx)) {
         ERR_print_errors(bio_err);
         goto end;
     }
 
     if ((CAkeyfile == NULL) && (CA_flag) && (CAformat == FORMAT_PEM)) {
         CAkeyfile = CAfile;
     } else if ((CA_flag) && (CAkeyfile == NULL)) {
         BIO_printf(bio_err,
                    "need to specify a CAkey if using the CA command\n");
         goto end;
     }
 
     if (extfile) {
         long errorline = -1;
         X509V3_CTX ctx2;
         extconf = NCONF_new(NULL);
         if (!NCONF_load(extconf, extfile, &errorline)) {
             if (errorline <= 0)
                 BIO_printf(bio_err,
                            "error loading the config file '%s'\n", extfile);
             else
                 BIO_printf(bio_err,
                            "error on line %ld of config file '%s'\n",
                            errorline, extfile);
             goto end;
         }
         if (!extsect) {
             extsect = NCONF_get_string(extconf, "default", "extensions");
             if (!extsect) {
                 ERR_clear_error();
                 extsect = "default";
             }
         }
         X509V3_set_ctx_test(&ctx2);
         X509V3_set_nconf(&ctx2, extconf);
         if (!X509V3_EXT_add_nconf(extconf, &ctx2, extsect, NULL)) {
             BIO_printf(bio_err,
                        "Error Loading extension section %s\n", extsect);
             ERR_print_errors(bio_err);
             goto end;
         }
     }
 
     if (reqfile) {
         EVP_PKEY *pkey;
         BIO *in;
 
         if (!sign_flag && !CA_flag) {
             BIO_printf(bio_err, "We need a private key to sign with\n");
             goto end;
         }
         in = BIO_new(BIO_s_file());
         if (in == NULL) {
             ERR_print_errors(bio_err);
             goto end;
         }
 
         if (infile == NULL)
             BIO_set_fp(in, stdin, BIO_NOCLOSE | BIO_FP_TEXT);
         else {
             if (BIO_read_filename(in, infile) <= 0) {
                 perror(infile);
                 BIO_free(in);
                 goto end;
             }
         }
         req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL);
         BIO_free(in);
 
         if (req == NULL) {
             ERR_print_errors(bio_err);
             goto end;
         }
 
         if ((req->req_info == NULL) ||
             (req->req_info->pubkey == NULL) ||
             (req->req_info->pubkey->public_key == NULL) ||
             (req->req_info->pubkey->public_key->data == NULL)) {
             BIO_printf(bio_err,
                        "The certificate request appears to corrupted\n");
             BIO_printf(bio_err, "It does not contain a public key\n");
             goto end;
         }
         if ((pkey = X509_REQ_get_pubkey(req)) == NULL) {
             BIO_printf(bio_err, "error unpacking public key\n");
             goto end;
         }
         i = X509_REQ_verify(req, pkey);
         EVP_PKEY_free(pkey);
         if (i < 0) {
             BIO_printf(bio_err, "Signature verification error\n");
             ERR_print_errors(bio_err);
             goto end;
         }
         if (i == 0) {
             BIO_printf(bio_err,
                        "Signature did not match the certificate request\n");
             goto end;
         } else
             BIO_printf(bio_err, "Signature ok\n");
 
         print_name(bio_err, "subject=", X509_REQ_get_subject_name(req),
                    nmflag);
 
         if ((x = X509_new()) == NULL)
             goto end;
 
         if (sno == NULL) {
             sno = ASN1_INTEGER_new();
             if (!sno || !rand_serial(NULL, sno))
                 goto end;
             if (!X509_set_serialNumber(x, sno))
                 goto end;
             ASN1_INTEGER_free(sno);
             sno = NULL;
         } else if (!X509_set_serialNumber(x, sno))
             goto end;
 
         if (!X509_set_issuer_name(x, req->req_info->subject))
             goto end;
         if (!X509_set_subject_name(x, req->req_info->subject))
             goto end;
 
         X509_gmtime_adj(X509_get_notBefore(x), 0);
         X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL);
 
         pkey = X509_REQ_get_pubkey(req);
         X509_set_pubkey(x, pkey);
         EVP_PKEY_free(pkey);
     } else
         x = load_cert(bio_err, infile, informat, NULL, e, "Certificate");
 
     if (x == NULL)
         goto end;
     if (CA_flag) {
         xca = load_cert(bio_err, CAfile, CAformat, NULL, e, "CA Certificate");
         if (xca == NULL)
             goto end;
     }
 
     if (!noout || text || next_serial) {
         OBJ_create("2.99999.3", "SET.ex3", "SET x509v3 extension 3");
 
         out = BIO_new(BIO_s_file());
         if (out == NULL) {
             ERR_print_errors(bio_err);
             goto end;
         }
         if (outfile == NULL) {
             BIO_set_fp(out, stdout, BIO_NOCLOSE);
 #ifdef OPENSSL_SYS_VMS
             {
                 BIO *tmpbio = BIO_new(BIO_f_linebuffer());
                 out = BIO_push(tmpbio, out);
             }
 #endif
         } else {
             if (BIO_write_filename(out, outfile) <= 0) {
                 perror(outfile);
                 goto end;
             }
         }
     }
 
     if (alias)
         X509_alias_set1(x, (unsigned char *)alias, -1);
 
     if (clrtrust)
         X509_trust_clear(x);
     if (clrreject)
         X509_reject_clear(x);
 
     if (trust) {
         for (i = 0; i < sk_ASN1_OBJECT_num(trust); i++) {
             objtmp = sk_ASN1_OBJECT_value(trust, i);
             X509_add1_trust_object(x, objtmp);
         }
     }
 
     if (reject) {
         for (i = 0; i < sk_ASN1_OBJECT_num(reject); i++) {
             objtmp = sk_ASN1_OBJECT_value(reject, i);
             X509_add1_reject_object(x, objtmp);
         }
     }
 
     if (num) {
         for (i = 1; i <= num; i++) {
             if (issuer == i) {
                 print_name(STDout, "issuer= ",
                            X509_get_issuer_name(x), nmflag);
             } else if (subject == i) {
                 print_name(STDout, "subject= ",
                            X509_get_subject_name(x), nmflag);
             } else if (serial == i) {
                 BIO_printf(STDout, "serial=");
                 i2a_ASN1_INTEGER(STDout, X509_get_serialNumber(x));
                 BIO_printf(STDout, "\n");
             } else if (next_serial == i) {
                 BIGNUM *bnser;
                 ASN1_INTEGER *ser;
                 ser = X509_get_serialNumber(x);
                 bnser = ASN1_INTEGER_to_BN(ser, NULL);
                 if (!bnser)
                     goto end;
                 if (!BN_add_word(bnser, 1))
                     goto end;
                 ser = BN_to_ASN1_INTEGER(bnser, NULL);
                 if (!ser)
                     goto end;
                 BN_free(bnser);
                 i2a_ASN1_INTEGER(out, ser);
                 ASN1_INTEGER_free(ser);
                 BIO_puts(out, "\n");
             } else if ((email == i) || (ocsp_uri == i)) {
                 int j;
                 STACK_OF(OPENSSL_STRING) *emlst;
                 if (email == i)
                     emlst = X509_get1_email(x);
                 else
                     emlst = X509_get1_ocsp(x);
                 for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
                     BIO_printf(STDout, "%s\n",
                                sk_OPENSSL_STRING_value(emlst, j));
                 X509_email_free(emlst);
             } else if (aliasout == i) {
                 unsigned char *alstr;
                 alstr = X509_alias_get0(x, NULL);
                 if (alstr)
                     BIO_printf(STDout, "%s\n", alstr);
                 else
                     BIO_puts(STDout, "<No Alias>\n");
             } else if (subject_hash == i) {
                 BIO_printf(STDout, "%08lx\n", X509_subject_name_hash(x));
             }
 #ifndef OPENSSL_NO_MD5
             else if (subject_hash_old == i) {
                 BIO_printf(STDout, "%08lx\n", X509_subject_name_hash_old(x));
             }
 #endif
             else if (issuer_hash == i) {
                 BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash(x));
             }
 #ifndef OPENSSL_NO_MD5
             else if (issuer_hash_old == i) {
                 BIO_printf(STDout, "%08lx\n", X509_issuer_name_hash_old(x));
             }
 #endif
             else if (pprint == i) {
                 X509_PURPOSE *ptmp;
                 int j;
                 BIO_printf(STDout, "Certificate purposes:\n");
                 for (j = 0; j < X509_PURPOSE_get_count(); j++) {
                     ptmp = X509_PURPOSE_get0(j);
                     purpose_print(STDout, x, ptmp);
                 }
             } else if (modulus == i) {
                 EVP_PKEY *pkey;
 
                 pkey = X509_get_pubkey(x);
                 if (pkey == NULL) {
                     BIO_printf(bio_err, "Modulus=unavailable\n");
                     ERR_print_errors(bio_err);
                     goto end;
                 }
                 BIO_printf(STDout, "Modulus=");
 #ifndef OPENSSL_NO_RSA
                 if (pkey->type == EVP_PKEY_RSA)
                     BN_print(STDout, pkey->pkey.rsa->n);
                 else
 #endif
 #ifndef OPENSSL_NO_DSA
                 if (pkey->type == EVP_PKEY_DSA)
                     BN_print(STDout, pkey->pkey.dsa->pub_key);
                 else
 #endif
                     BIO_printf(STDout, "Wrong Algorithm type");
                 BIO_printf(STDout, "\n");
                 EVP_PKEY_free(pkey);
             } else if (pubkey == i) {
                 EVP_PKEY *pkey;
 
                 pkey = X509_get_pubkey(x);
                 if (pkey == NULL) {
                     BIO_printf(bio_err, "Error getting public key\n");
                     ERR_print_errors(bio_err);
                     goto end;
                 }
                 PEM_write_bio_PUBKEY(STDout, pkey);
                 EVP_PKEY_free(pkey);
             } else if (C == i) {
                 unsigned char *d;
                 char *m;
                 int y, z;
 
                 X509_NAME_oneline(X509_get_subject_name(x), buf, sizeof buf);
                 BIO_printf(STDout, "/* subject:%s */\n", buf);
                 m = X509_NAME_oneline(X509_get_issuer_name(x), buf,
                                       sizeof buf);
                 BIO_printf(STDout, "/* issuer :%s */\n", buf);
 
                 z = i2d_X509(x, NULL);
                 m = OPENSSL_malloc(z);
                 if (!m) {
                     BIO_printf(bio_err, "Out of memory\n");
                     ERR_print_errors(bio_err);
                     goto end;
                 }
 
                 d = (unsigned char *)m;
                 z = i2d_X509_NAME(X509_get_subject_name(x), &d);
                 BIO_printf(STDout, "unsigned char XXX_subject_name[%d]={\n",
                            z);
                 d = (unsigned char *)m;
                 for (y = 0; y < z; y++) {
                     BIO_printf(STDout, "0x%02X,", d[y]);
                     if ((y & 0x0f) == 0x0f)
                         BIO_printf(STDout, "\n");
                 }
                 if (y % 16 != 0)
                     BIO_printf(STDout, "\n");
                 BIO_printf(STDout, "};\n");
 
                 z = i2d_X509_PUBKEY(X509_get_X509_PUBKEY(x), &d);
                 BIO_printf(STDout, "unsigned char XXX_public_key[%d]={\n", z);
                 d = (unsigned char *)m;
                 for (y = 0; y < z; y++) {
                     BIO_printf(STDout, "0x%02X,", d[y]);
                     if ((y & 0x0f) == 0x0f)
                         BIO_printf(STDout, "\n");
                 }
                 if (y % 16 != 0)
                     BIO_printf(STDout, "\n");
                 BIO_printf(STDout, "};\n");
 
                 z = i2d_X509(x, &d);
                 BIO_printf(STDout, "unsigned char XXX_certificate[%d]={\n",
                            z);
                 d = (unsigned char *)m;
                 for (y = 0; y < z; y++) {
                     BIO_printf(STDout, "0x%02X,", d[y]);
                     if ((y & 0x0f) == 0x0f)
                         BIO_printf(STDout, "\n");
                 }
                 if (y % 16 != 0)
                     BIO_printf(STDout, "\n");
                 BIO_printf(STDout, "};\n");
 
                 OPENSSL_free(m);
             } else if (text == i) {
                 X509_print_ex(STDout, x, nmflag, certflag);
             } else if (startdate == i) {
                 BIO_puts(STDout, "notBefore=");
                 ASN1_TIME_print(STDout, X509_get_notBefore(x));
                 BIO_puts(STDout, "\n");
             } else if (enddate == i) {
                 BIO_puts(STDout, "notAfter=");
                 ASN1_TIME_print(STDout, X509_get_notAfter(x));
                 BIO_puts(STDout, "\n");
             } else if (fingerprint == i) {
                 int j;
                 unsigned int n;
                 unsigned char md[EVP_MAX_MD_SIZE];
                 const EVP_MD *fdig = digest;
 
                 if (!fdig)
                     fdig = EVP_sha1();
 
                 if (!X509_digest(x, fdig, md, &n)) {
                     BIO_printf(bio_err, "out of memory\n");
                     goto end;
                 }
                 BIO_printf(STDout, "%s Fingerprint=",
                            OBJ_nid2sn(EVP_MD_type(fdig)));
                 for (j = 0; j < (int)n; j++) {
                     BIO_printf(STDout, "%02X%c", md[j], (j + 1 == (int)n)
                                ? '\n' : ':');
                 }
             }
 
             /* should be in the library */
             else if ((sign_flag == i) && (x509req == 0)) {
                 BIO_printf(bio_err, "Getting Private key\n");
                 if (Upkey == NULL) {
                     Upkey = load_key(bio_err,
                                      keyfile, keyformat, 0,
                                      passin, e, "Private key");
                     if (Upkey == NULL)
                         goto end;
                 }
 
                 assert(need_rand);
                 if (!sign(x, Upkey, days, clrext, digest, extconf, extsect))
                     goto end;
             } else if (CA_flag == i) {
                 BIO_printf(bio_err, "Getting CA Private Key\n");
                 if (CAkeyfile != NULL) {
                     CApkey = load_key(bio_err,
                                       CAkeyfile, CAkeyformat,
                                       0, passin, e, "CA Private Key");
                     if (CApkey == NULL)
                         goto end;
                 }
 
                 assert(need_rand);
                 if (!x509_certify(ctx, CAfile, digest, x, xca,
                                   CApkey, sigopts,
                                   CAserial, CA_createserial, days, clrext,
                                   extconf, extsect, sno))
                     goto end;
             } else if (x509req == i) {
                 EVP_PKEY *pk;
 
                 BIO_printf(bio_err, "Getting request Private Key\n");
                 if (keyfile == NULL) {
                     BIO_printf(bio_err, "no request key file specified\n");
                     goto end;
                 } else {
                     pk = load_key(bio_err,
                                   keyfile, keyformat, 0,
                                   passin, e, "request key");
                     if (pk == NULL)
                         goto end;
                 }
 
                 BIO_printf(bio_err, "Generating certificate request\n");
 
                 rq = X509_to_X509_REQ(x, pk, digest);
                 EVP_PKEY_free(pk);
                 if (rq == NULL) {
                     ERR_print_errors(bio_err);
                     goto end;
                 }
                 if (!noout) {
                     X509_REQ_print(out, rq);
                     PEM_write_bio_X509_REQ(out, rq);
                 }
                 noout = 1;
             } else if (ocspid == i) {
                 X509_ocspid_print(out, x);
             }
         }
     }
 
     if (checkend) {
         time_t tcheck = time(NULL) + checkoffset;
 
         if (X509_cmp_time(X509_get_notAfter(x), &tcheck) < 0) {
             BIO_printf(out, "Certificate will expire\n");
             ret = 1;
         } else {
             BIO_printf(out, "Certificate will not expire\n");
             ret = 0;
         }
         goto end;
     }
 
     if (noout) {
         ret = 0;
         goto end;
     }
 
     if (outformat == FORMAT_ASN1)
         i = i2d_X509_bio(out, x);
     else if (outformat == FORMAT_PEM) {
         if (trustout)
             i = PEM_write_bio_X509_AUX(out, x);
         else
             i = PEM_write_bio_X509(out, x);
     } else if (outformat == FORMAT_NETSCAPE) {
         NETSCAPE_X509 nx;
         ASN1_OCTET_STRING hdr;
 
         hdr.data = (unsigned char *)NETSCAPE_CERT_HDR;
         hdr.length = strlen(NETSCAPE_CERT_HDR);
         nx.header = &hdr;
         nx.cert = x;
 
         i = ASN1_item_i2d_bio(ASN1_ITEM_rptr(NETSCAPE_X509), out, &nx);
     } else {
         BIO_printf(bio_err, "bad output format specified for outfile\n");
         goto end;
     }
     if (!i) {
         BIO_printf(bio_err, "unable to write certificate\n");
         ERR_print_errors(bio_err);
         goto end;
     }
     ret = 0;
  end:
     if (need_rand)
         app_RAND_write_file(NULL, bio_err);
     OBJ_cleanup();
     NCONF_free(extconf);
     BIO_free_all(out);
     BIO_free_all(STDout);
     X509_STORE_free(ctx);
     X509_REQ_free(req);
     X509_free(x);
     X509_free(xca);
     EVP_PKEY_free(Upkey);
     EVP_PKEY_free(CApkey);
     if (sigopts)
         sk_OPENSSL_STRING_free(sigopts);
     X509_REQ_free(rq);
     ASN1_INTEGER_free(sno);
     sk_ASN1_OBJECT_pop_free(trust, ASN1_OBJECT_free);
     sk_ASN1_OBJECT_pop_free(reject, ASN1_OBJECT_free);
     if (passin)
         OPENSSL_free(passin);
     apps_shutdown();
     OPENSSL_EXIT(ret);
 }
 
 static ASN1_INTEGER *x509_load_serial(char *CAfile, char *serialfile,
                                       int create)
 {
     char *buf = NULL, *p;
     ASN1_INTEGER *bs = NULL;
     BIGNUM *serial = NULL;
     size_t len;
 
     len = ((serialfile == NULL)
            ? (strlen(CAfile) + strlen(POSTFIX) + 1)
            : (strlen(serialfile))) + 1;
     buf = OPENSSL_malloc(len);
     if (buf == NULL) {
         BIO_printf(bio_err, "out of mem\n");
         goto end;
     }
     if (serialfile == NULL) {
         BUF_strlcpy(buf, CAfile, len);
         for (p = buf; *p; p++)
             if (*p == '.') {
                 *p = '\0';
                 break;
             }
         BUF_strlcat(buf, POSTFIX, len);
     } else
         BUF_strlcpy(buf, serialfile, len);
 
     serial = load_serial(buf, create, NULL);
     if (serial == NULL)
         goto end;
 
     if (!BN_add_word(serial, 1)) {
         BIO_printf(bio_err, "add_word failure\n");
         goto end;
     }
 
     if (!save_serial(buf, NULL, serial, &bs))
         goto end;
 
  end:
     if (buf)
         OPENSSL_free(buf);
     BN_free(serial);
     return bs;
 }
 
 static int x509_certify(X509_STORE *ctx, char *CAfile, const EVP_MD *digest,
                         X509 *x, X509 *xca, EVP_PKEY *pkey,
                         STACK_OF(OPENSSL_STRING) *sigopts,
                         char *serialfile, int create,
                         int days, int clrext, CONF *conf, char *section,
                         ASN1_INTEGER *sno)
 {
     int ret = 0;
     ASN1_INTEGER *bs = NULL;
     X509_STORE_CTX xsc;
     EVP_PKEY *upkey;
 
     upkey = X509_get_pubkey(xca);
+    if (upkey == NULL)  {
+        BIO_printf(bio_err, "Error obtaining CA X509 public key\n");
+        goto end;
+    }
     EVP_PKEY_copy_parameters(upkey, pkey);
     EVP_PKEY_free(upkey);
 
     if (!X509_STORE_CTX_init(&xsc, ctx, x, NULL)) {
         BIO_printf(bio_err, "Error initialising X509 store\n");
         goto end;
     }
     if (sno)
         bs = sno;
     else if (!(bs = x509_load_serial(CAfile, serialfile, create)))
         goto end;
 
 /*      if (!X509_STORE_add_cert(ctx,x)) goto end;*/
 
     /*
      * NOTE: this certificate can/should be self signed, unless it was a
      * certificate request in which case it is not.
      */
     X509_STORE_CTX_set_cert(&xsc, x);
     X509_STORE_CTX_set_flags(&xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
     if (!reqfile && X509_verify_cert(&xsc) <= 0)
         goto end;
 
     if (!X509_check_private_key(xca, pkey)) {
         BIO_printf(bio_err,
                    "CA certificate and CA private key do not match\n");
         goto end;
     }
 
     if (!X509_set_issuer_name(x, X509_get_subject_name(xca)))
         goto end;
     if (!X509_set_serialNumber(x, bs))
         goto end;
 
     if (X509_gmtime_adj(X509_get_notBefore(x), 0L) == NULL)
         goto end;
 
     /* hardwired expired */
     if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
         goto end;
 
     if (clrext) {
         while (X509_get_ext_count(x) > 0)
             X509_delete_ext(x, 0);
     }
 
     if (conf) {
         X509V3_CTX ctx2;
         X509_set_version(x, 2); /* version 3 certificate */
         X509V3_set_ctx(&ctx2, xca, x, NULL, NULL, 0);
         X509V3_set_nconf(&ctx2, conf);
         if (!X509V3_EXT_add_nconf(conf, &ctx2, section, x))
             goto end;
     }
 
     if (!do_X509_sign(bio_err, x, pkey, digest, sigopts))
         goto end;
     ret = 1;
  end:
     X509_STORE_CTX_cleanup(&xsc);
     if (!ret)
         ERR_print_errors(bio_err);
     if (!sno)
         ASN1_INTEGER_free(bs);
     return ret;
 }
 
 static int MS_CALLBACK callb(int ok, X509_STORE_CTX *ctx)
 {
     int err;
     X509 *err_cert;
 
     /*
      * it is ok to use a self signed certificate This case will catch both
      * the initial ok == 0 and the final ok == 1 calls to this function
      */
     err = X509_STORE_CTX_get_error(ctx);
     if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT)
         return 1;
 
     /*
      * BAD we should have gotten an error.  Normally if everything worked
      * X509_STORE_CTX_get_error(ctx) will still be set to
      * DEPTH_ZERO_SELF_....
      */
     if (ok) {
         BIO_printf(bio_err,
                    "error with certificate to be certified - should be self signed\n");
         return 0;
     } else {
         err_cert = X509_STORE_CTX_get_current_cert(ctx);
         print_name(bio_err, NULL, X509_get_subject_name(err_cert), 0);
         BIO_printf(bio_err,
                    "error with certificate - error %d at depth %d\n%s\n", err,
                    X509_STORE_CTX_get_error_depth(ctx),
                    X509_verify_cert_error_string(err));
         return 1;
     }
 }
 
 /* self sign */
 static int sign(X509 *x, EVP_PKEY *pkey, int days, int clrext,
                 const EVP_MD *digest, CONF *conf, char *section)
 {
 
     EVP_PKEY *pktmp;
 
     pktmp = X509_get_pubkey(x);
+    if (pktmp == NULL)
+        goto err;
     EVP_PKEY_copy_parameters(pktmp, pkey);
     EVP_PKEY_save_parameters(pktmp, 1);
     EVP_PKEY_free(pktmp);
 
     if (!X509_set_issuer_name(x, X509_get_subject_name(x)))
         goto err;
     if (X509_gmtime_adj(X509_get_notBefore(x), 0) == NULL)
         goto err;
 
     if (X509_time_adj_ex(X509_get_notAfter(x), days, 0, NULL) == NULL)
         goto err;
 
     if (!X509_set_pubkey(x, pkey))
         goto err;
     if (clrext) {
         while (X509_get_ext_count(x) > 0)
             X509_delete_ext(x, 0);
     }
     if (conf) {
         X509V3_CTX ctx;
         X509_set_version(x, 2); /* version 3 certificate */
         X509V3_set_ctx(&ctx, x, x, NULL, NULL, 0);
         X509V3_set_nconf(&ctx, conf);
         if (!X509V3_EXT_add_nconf(conf, &ctx, section, x))
             goto err;
     }
     if (!X509_sign(x, pkey, digest))
         goto err;
     return 1;
  err:
     ERR_print_errors(bio_err);
     return 0;
 }
 
 static int purpose_print(BIO *bio, X509 *cert, X509_PURPOSE *pt)
 {
     int id, i, idret;
     char *pname;
     id = X509_PURPOSE_get_id(pt);
     pname = X509_PURPOSE_get0_name(pt);
     for (i = 0; i < 2; i++) {
         idret = X509_check_purpose(cert, id, i);
         BIO_printf(bio, "%s%s : ", pname, i ? " CA" : "");
         if (idret == 1)
             BIO_printf(bio, "Yes\n");
         else if (idret == 0)
             BIO_printf(bio, "No\n");
         else
             BIO_printf(bio, "Yes (WARNING code=%d)\n", idret);
     }
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_bytes.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_bytes.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_bytes.c	(revision 306191)
@@ -1,306 +1,334 @@
 /* crypto/asn1/a_bytes.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
+                                  int depth);
+static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
+                                       const unsigned char **pp, long length,
+                                       int Ptag, int Pclass, int depth,
+                                       int *perr);
 /*
  * type is a 'bitmap' of acceptable string types.
  */
 ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
                                  long length, int type)
 {
     ASN1_STRING *ret = NULL;
     const unsigned char *p;
     unsigned char *s;
     long len;
     int inf, tag, xclass;
     int i = 0;
 
     p = *pp;
     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
     if (inf & 0x80)
         goto err;
 
     if (tag >= 32) {
         i = ASN1_R_TAG_VALUE_TOO_HIGH;
         goto err;
     }
     if (!(ASN1_tag2bit(tag) & type)) {
         i = ASN1_R_WRONG_TYPE;
         goto err;
     }
 
     /* If a bit-string, exit early */
     if (tag == V_ASN1_BIT_STRING)
         return (d2i_ASN1_BIT_STRING(a, pp, length));
 
     if ((a == NULL) || ((*a) == NULL)) {
         if ((ret = ASN1_STRING_new()) == NULL)
             return (NULL);
     } else
         ret = (*a);
 
     if (len != 0) {
-        s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+        s = OPENSSL_malloc((int)len + 1);
         if (s == NULL) {
             i = ERR_R_MALLOC_FAILURE;
             goto err;
         }
         memcpy(s, p, (int)len);
         s[len] = '\0';
         p += len;
     } else
         s = NULL;
 
     if (ret->data != NULL)
         OPENSSL_free(ret->data);
     ret->length = (int)len;
     ret->data = s;
     ret->type = tag;
     if (a != NULL)
         (*a) = ret;
     *pp = p;
     return (ret);
  err:
     ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
         ASN1_STRING_free(ret);
     return (NULL);
 }
 
 int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
 {
     int ret, r, constructed;
     unsigned char *p;
 
     if (a == NULL)
         return (0);
 
     if (tag == V_ASN1_BIT_STRING)
         return (i2d_ASN1_BIT_STRING(a, pp));
 
     ret = a->length;
     r = ASN1_object_size(0, ret, tag);
     if (pp == NULL)
         return (r);
     p = *pp;
 
     if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
         constructed = 1;
     else
         constructed = 0;
     ASN1_put_object(&p, constructed, ret, tag, xclass);
     memcpy(p, a->data, a->length);
     p += a->length;
     *pp = p;
     return (r);
 }
 
+/*
+ * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be
+ * encountered in pratice.
+ */
+
+#define ASN1_BYTES_MAXDEPTH 20
+
 ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
                             long length, int Ptag, int Pclass)
 {
+    int err = 0;
+    ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err);
+    if (err != 0)
+        ASN1err(ASN1_F_D2I_ASN1_BYTES, err);
+    return s;
+}
+
+static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
+                                       const unsigned char **pp, long length,
+                                       int Ptag, int Pclass,
+                                       int depth, int *perr)
+{
     ASN1_STRING *ret = NULL;
     const unsigned char *p;
     unsigned char *s;
     long len;
     int inf, tag, xclass;
-    int i = 0;
 
+    if (depth > ASN1_BYTES_MAXDEPTH) {
+        *perr = ASN1_R_NESTED_ASN1_STRING;
+        return NULL;
+    }
+
     if ((a == NULL) || ((*a) == NULL)) {
         if ((ret = ASN1_STRING_new()) == NULL)
             return (NULL);
     } else
         ret = (*a);
 
     p = *pp;
     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
     if (inf & 0x80) {
-        i = ASN1_R_BAD_OBJECT_HEADER;
+        *perr = ASN1_R_BAD_OBJECT_HEADER;
         goto err;
     }
 
     if (tag != Ptag) {
-        i = ASN1_R_WRONG_TAG;
+        *perr = ASN1_R_WRONG_TAG;
         goto err;
     }
 
     if (inf & V_ASN1_CONSTRUCTED) {
         ASN1_const_CTX c;
 
+        c.error = 0;
         c.pp = pp;
         c.p = p;
         c.inf = inf;
         c.slen = len;
         c.tag = Ptag;
         c.xclass = Pclass;
         c.max = (length == 0) ? 0 : (p + length);
-        if (!asn1_collate_primitive(ret, &c))
+        if (!asn1_collate_primitive(ret, &c, depth)) {
+            *perr = c.error;
             goto err;
-        else {
+        } else {
             p = c.p;
         }
     } else {
         if (len != 0) {
             if ((ret->length < len) || (ret->data == NULL)) {
-                s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+                s = OPENSSL_malloc((int)len + 1);
                 if (s == NULL) {
-                    i = ERR_R_MALLOC_FAILURE;
+                    *perr = ERR_R_MALLOC_FAILURE;
                     goto err;
                 }
                 if (ret->data != NULL)
                     OPENSSL_free(ret->data);
             } else
                 s = ret->data;
             memcpy(s, p, (int)len);
             s[len] = '\0';
             p += len;
         } else {
             s = NULL;
             if (ret->data != NULL)
                 OPENSSL_free(ret->data);
         }
 
         ret->length = (int)len;
         ret->data = s;
         ret->type = Ptag;
     }
 
     if (a != NULL)
         (*a) = ret;
     *pp = p;
     return (ret);
  err:
     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
         ASN1_STRING_free(ret);
-    ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
     return (NULL);
 }
 
 /*
  * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
  * into the one structure that is then returned
  */
 /*
  * There have been a few bug fixes for this function from Paul Keogh
  * <paul.keogh@sse.ie>, many thanks to him
  */
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
+                                  int depth)
 {
     ASN1_STRING *os = NULL;
     BUF_MEM b;
     int num;
 
     b.length = 0;
     b.max = 0;
     b.data = NULL;
 
     if (a == NULL) {
         c->error = ERR_R_PASSED_NULL_PARAMETER;
         goto err;
     }
 
     num = 0;
     for (;;) {
         if (c->inf & 1) {
             c->eos = ASN1_const_check_infinite_end(&c->p,
                                                    (long)(c->max - c->p));
             if (c->eos)
                 break;
         } else {
             if (c->slen <= 0)
                 break;
         }
 
         c->q = c->p;
-        if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
-            == NULL) {
-            c->error = ERR_R_ASN1_LIB;
+        if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass,
+                               depth + 1, &c->error) == NULL) {
             goto err;
         }
 
         if (!BUF_MEM_grow_clean(&b, num + os->length)) {
             c->error = ERR_R_BUF_LIB;
             goto err;
         }
         memcpy(&(b.data[num]), os->data, os->length);
         if (!(c->inf & 1))
             c->slen -= (c->p - c->q);
         num += os->length;
     }
 
     if (!asn1_const_Finish(c))
         goto err;
 
     a->length = num;
     if (a->data != NULL)
         OPENSSL_free(a->data);
     a->data = (unsigned char *)b.data;
     if (os != NULL)
         ASN1_STRING_free(os);
     return (1);
  err:
-    ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
     if (os != NULL)
         ASN1_STRING_free(os);
     if (b.data != NULL)
         OPENSSL_free(b.data);
     return (0);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_object.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_object.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_object.c	(revision 306191)
@@ -1,402 +1,406 @@
 /* crypto/asn1/a_object.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.]
  */
 
 #include <stdio.h>
 #include <limits.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/asn1.h>
 #include <openssl/objects.h>
 #include <openssl/bn.h>
 
 int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
 {
     unsigned char *p;
     int objsize;
 
     if ((a == NULL) || (a->data == NULL))
         return (0);
 
     objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
-    if (pp == NULL)
+    if (pp == NULL || objsize == -1)
         return objsize;
 
     p = *pp;
     ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
     memcpy(p, a->data, a->length);
     p += a->length;
 
     *pp = p;
     return (objsize);
 }
 
 int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
 {
     int i, first, len = 0, c, use_bn;
     char ftmp[24], *tmp = ftmp;
     int tmpsize = sizeof ftmp;
     const char *p;
     unsigned long l;
     BIGNUM *bl = NULL;
 
     if (num == 0)
         return (0);
     else if (num == -1)
         num = strlen(buf);
 
     p = buf;
     c = *(p++);
     num--;
     if ((c >= '0') && (c <= '2')) {
         first = c - '0';
     } else {
         ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
         goto err;
     }
 
     if (num <= 0) {
         ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
         goto err;
     }
     c = *(p++);
     num--;
     for (;;) {
         if (num <= 0)
             break;
         if ((c != '.') && (c != ' ')) {
             ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
             goto err;
         }
         l = 0;
         use_bn = 0;
         for (;;) {
             if (num <= 0)
                 break;
             num--;
             c = *(p++);
             if ((c == ' ') || (c == '.'))
                 break;
             if ((c < '0') || (c > '9')) {
                 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
                 goto err;
             }
             if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
                 use_bn = 1;
                 if (!bl)
                     bl = BN_new();
                 if (!bl || !BN_set_word(bl, l))
                     goto err;
             }
             if (use_bn) {
                 if (!BN_mul_word(bl, 10L)
                     || !BN_add_word(bl, c - '0'))
                     goto err;
             } else
                 l = l * 10L + (long)(c - '0');
         }
         if (len == 0) {
             if ((first < 2) && (l >= 40)) {
                 ASN1err(ASN1_F_A2D_ASN1_OBJECT,
                         ASN1_R_SECOND_NUMBER_TOO_LARGE);
                 goto err;
             }
             if (use_bn) {
                 if (!BN_add_word(bl, first * 40))
                     goto err;
             } else
                 l += (long)first *40;
         }
         i = 0;
         if (use_bn) {
             int blsize;
             blsize = BN_num_bits(bl);
             blsize = (blsize + 6) / 7;
             if (blsize > tmpsize) {
                 if (tmp != ftmp)
                     OPENSSL_free(tmp);
                 tmpsize = blsize + 32;
                 tmp = OPENSSL_malloc(tmpsize);
                 if (!tmp)
                     goto err;
             }
-            while (blsize--)
-                tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+            while (blsize--) {
+                BN_ULONG t = BN_div_word(bl, 0x80L);
+                if (t == (BN_ULONG)-1)
+                    goto err;
+                tmp[i++] = (unsigned char)t;
+            }
         } else {
 
             for (;;) {
                 tmp[i++] = (unsigned char)l & 0x7f;
                 l >>= 7L;
                 if (l == 0L)
                     break;
             }
 
         }
         if (out != NULL) {
             if (len + i > olen) {
                 ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
                 goto err;
             }
             while (--i > 0)
                 out[len++] = tmp[i] | 0x80;
             out[len++] = tmp[0];
         } else
             len += i;
     }
     if (tmp != ftmp)
         OPENSSL_free(tmp);
     if (bl)
         BN_free(bl);
     return (len);
  err:
     if (tmp != ftmp)
         OPENSSL_free(tmp);
     if (bl)
         BN_free(bl);
     return (0);
 }
 
 int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
 {
     return OBJ_obj2txt(buf, buf_len, a, 0);
 }
 
 int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
 {
     char buf[80], *p = buf;
     int i;
 
     if ((a == NULL) || (a->data == NULL))
         return (BIO_write(bp, "NULL", 4));
     i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
     if (i > (int)(sizeof(buf) - 1)) {
         p = OPENSSL_malloc(i + 1);
         if (!p)
             return -1;
         i2t_ASN1_OBJECT(p, i + 1, a);
     }
     if (i <= 0)
         return BIO_write(bp, "<INVALID>", 9);
     BIO_write(bp, p, i);
     if (p != buf)
         OPENSSL_free(p);
     return (i);
 }
 
 ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
                              long length)
 {
     const unsigned char *p;
     long len;
     int tag, xclass;
     int inf, i;
     ASN1_OBJECT *ret = NULL;
     p = *pp;
     inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
     if (inf & 0x80) {
         i = ASN1_R_BAD_OBJECT_HEADER;
         goto err;
     }
 
     if (tag != V_ASN1_OBJECT) {
         i = ASN1_R_EXPECTING_AN_OBJECT;
         goto err;
     }
     ret = c2i_ASN1_OBJECT(a, &p, len);
     if (ret)
         *pp = p;
     return ret;
  err:
     ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
     return (NULL);
 }
 
 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
                              long len)
 {
     ASN1_OBJECT *ret = NULL;
     const unsigned char *p;
     unsigned char *data;
     int i, length;
 
     /*
      * Sanity check OID encoding. Need at least one content octet. MSB must
      * be clear in the last octet. can't have leading 0x80 in subidentifiers,
      * see: X.690 8.19.2
      */
     if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
         p[len - 1] & 0x80) {
         ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
         return NULL;
     }
     /* Now 0 < len <= INT_MAX, so the cast is safe. */
     length = (int)len;
     for (i = 0; i < length; i++, p++) {
         if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
             ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
             return NULL;
         }
     }
 
     /*
      * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
      * ->ln
      */
     if ((a == NULL) || ((*a) == NULL) ||
         !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
         if ((ret = ASN1_OBJECT_new()) == NULL)
             return (NULL);
     } else
         ret = (*a);
 
     p = *pp;
     /* detach data from object */
     data = (unsigned char *)ret->data;
     ret->data = NULL;
     /* once detached we can change it */
     if ((data == NULL) || (ret->length < length)) {
         ret->length = 0;
         if (data != NULL)
             OPENSSL_free(data);
         data = (unsigned char *)OPENSSL_malloc(length);
         if (data == NULL) {
             i = ERR_R_MALLOC_FAILURE;
             goto err;
         }
         ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     }
     memcpy(data, p, length);
     /* reattach data to object, after which it remains const */
     ret->data = data;
     ret->length = length;
     ret->sn = NULL;
     ret->ln = NULL;
     /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
     p += length;
 
     if (a != NULL)
         (*a) = ret;
     *pp = p;
     return (ret);
  err:
     ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
         ASN1_OBJECT_free(ret);
     return (NULL);
 }
 
 ASN1_OBJECT *ASN1_OBJECT_new(void)
 {
     ASN1_OBJECT *ret;
 
     ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
     if (ret == NULL) {
         ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
         return (NULL);
     }
     ret->length = 0;
     ret->data = NULL;
     ret->nid = 0;
     ret->sn = NULL;
     ret->ln = NULL;
     ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
     return (ret);
 }
 
 void ASN1_OBJECT_free(ASN1_OBJECT *a)
 {
     if (a == NULL)
         return;
     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
 #ifndef CONST_STRICT            /* disable purely for compile-time strict
                                  * const checking. Doing this on a "real"
                                  * compile will cause memory leaks */
         if (a->sn != NULL)
             OPENSSL_free((void *)a->sn);
         if (a->ln != NULL)
             OPENSSL_free((void *)a->ln);
 #endif
         a->sn = a->ln = NULL;
     }
     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
         if (a->data != NULL)
             OPENSSL_free((void *)a->data);
         a->data = NULL;
         a->length = 0;
     }
     if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
         OPENSSL_free(a);
 }
 
 ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
                                 const char *sn, const char *ln)
 {
     ASN1_OBJECT o;
 
     o.sn = sn;
     o.ln = ln;
     o.data = data;
     o.nid = nid;
     o.length = len;
     o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
         ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     return (OBJ_dup(&o));
 }
 
 IMPLEMENT_STACK_OF(ASN1_OBJECT)
 
 IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_set.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_set.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/a_set.c	(revision 306191)
@@ -1,238 +1,243 @@
 /* crypto/asn1/a_set.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.]
  */
 
 #include <stdio.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/asn1_mac.h>
 
 #ifndef NO_ASN1_OLD
 
 typedef struct {
     unsigned char *pbData;
     int cbData;
 } MYBLOB;
 
 /*
  * SetBlobCmp This function compares two elements of SET_OF block
  */
 static int SetBlobCmp(const void *elem1, const void *elem2)
 {
     const MYBLOB *b1 = (const MYBLOB *)elem1;
     const MYBLOB *b2 = (const MYBLOB *)elem2;
     int r;
 
     r = memcmp(b1->pbData, b2->pbData,
                b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
     if (r != 0)
         return r;
     return b1->cbData - b2->cbData;
 }
 
 /*
  * int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)
  */
 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)
 {
     int ret = 0, r;
     int i;
     unsigned char *p;
     unsigned char *pStart, *pTempMem;
     MYBLOB *rgSetBlob;
     int totSize;
 
     if (a == NULL)
         return (0);
-    for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
+    for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) {
+        int tmplen = i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
+        if (tmplen > INT_MAX - ret)
+            return -1;
         ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
+    }
     r = ASN1_object_size(1, ret, ex_tag);
-    if (pp == NULL)
+    if (pp == NULL || r == -1)
         return (r);
 
     p = *pp;
     ASN1_put_object(&p, 1, ret, ex_tag, ex_class);
 
 /* Modified by gp@nsj.co.jp */
     /* And then again by Ben */
     /* And again by Steve */
 
     if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
         for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
             i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
 
         *pp = p;
         return (r);
     }
 
     pStart = p;                 /* Catch the beg of Setblobs */
     /* In this array we will store the SET blobs */
     rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
     if (rgSetBlob == NULL) {
         ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
         return (0);
     }
 
     for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
         rgSetBlob[i].pbData = p; /* catch each set encode blob */
         i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
         rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
                                                         * SetBlob */
     }
     *pp = p;
     totSize = p - pStart;       /* This is the total size of all set blobs */
 
     /*
      * Now we have to sort the blobs. I am using a simple algo. *Sort ptrs
      * *Copy to temp-mem *Copy from temp-mem to user-mem
      */
     qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
     if (!(pTempMem = OPENSSL_malloc(totSize))) {
         ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
         return (0);
     }
 
 /* Copy to temp mem */
     p = pTempMem;
     for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
         memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
         p += rgSetBlob[i].cbData;
     }
 
 /* Copy back to user mem*/
     memcpy(pStart, pTempMem, totSize);
     OPENSSL_free(pTempMem);
     OPENSSL_free(rgSetBlob);
 
     return (r);
 }
 
 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)
 {
     ASN1_const_CTX c;
     STACK_OF(OPENSSL_BLOCK) *ret = NULL;
 
     if ((a == NULL) || ((*a) == NULL)) {
         if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
             ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE);
             goto err;
         }
     } else
         ret = (*a);
 
     c.p = *pp;
     c.max = (length == 0) ? 0 : (c.p + length);
 
     c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p);
     if (c.inf & 0x80)
         goto err;
     if (ex_class != c.xclass) {
         ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS);
         goto err;
     }
     if (ex_tag != c.tag) {
         ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG);
         goto err;
     }
     if ((c.slen + c.p) > c.max) {
         ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR);
         goto err;
     }
     /*
      * check for infinite constructed - it can be as long as the amount of
      * data passed to us
      */
     if (c.inf == (V_ASN1_CONSTRUCTED + 1))
         c.slen = length + *pp - c.p;
     c.max = c.p + c.slen;
 
     while (c.p < c.max) {
         char *s;
 
         if (M_ASN1_D2I_end_sequence())
             break;
         /*
          * XXX: This was called with 4 arguments, incorrectly, it seems if
          * ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL)
          */
         if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
             ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT);
             asn1_add_error(*pp, (int)(c.p - *pp));
             goto err;
         }
         if (!sk_OPENSSL_BLOCK_push(ret, s))
             goto err;
     }
     if (a != NULL)
         (*a) = ret;
     *pp = c.p;
     return (ret);
  err:
     if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
         if (free_func != NULL)
             sk_OPENSSL_BLOCK_pop_free(ret, free_func);
         else
             sk_OPENSSL_BLOCK_free(ret);
     }
     return (NULL);
 }
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn1_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn1_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn1_lib.c	(revision 306191)
@@ -1,479 +1,483 @@
 /* crypto/asn1/asn1_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.]
  */
 
 #include <stdio.h>
 #include <limits.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/asn1_mac.h>
 
 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
                            long max);
 static void asn1_put_length(unsigned char **pp, int length);
 const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT;
 
 static int _asn1_check_infinite_end(const unsigned char **p, long len)
 {
     /*
      * If there is 0 or 1 byte left, the length check should pick things up
      */
     if (len <= 0)
         return (1);
     else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
         (*p) += 2;
         return (1);
     }
     return (0);
 }
 
 int ASN1_check_infinite_end(unsigned char **p, long len)
 {
     return _asn1_check_infinite_end((const unsigned char **)p, len);
 }
 
 int ASN1_const_check_infinite_end(const unsigned char **p, long len)
 {
     return _asn1_check_infinite_end(p, len);
 }
 
 int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
                     int *pclass, long omax)
 {
     int i, ret;
     long l;
     const unsigned char *p = *pp;
     int tag, xclass, inf;
     long max = omax;
 
     if (!max)
         goto err;
     ret = (*p & V_ASN1_CONSTRUCTED);
     xclass = (*p & V_ASN1_PRIVATE);
     i = *p & V_ASN1_PRIMITIVE_TAG;
     if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
         p++;
         if (--max == 0)
             goto err;
         l = 0;
         while (*p & 0x80) {
             l <<= 7L;
             l |= *(p++) & 0x7f;
             if (--max == 0)
                 goto err;
             if (l > (INT_MAX >> 7L))
                 goto err;
         }
         l <<= 7L;
         l |= *(p++) & 0x7f;
         tag = (int)l;
         if (--max == 0)
             goto err;
     } else {
         tag = i;
         p++;
         if (--max == 0)
             goto err;
     }
     *ptag = tag;
     *pclass = xclass;
     if (!asn1_get_length(&p, &inf, plength, max))
         goto err;
 
     if (inf && !(ret & V_ASN1_CONSTRUCTED))
         goto err;
 
 #if 0
     fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d  (%d > %d)\n",
             (int)p, *plength, omax, (int)*pp, (int)(p + *plength),
             (int)(omax + *pp));
 
 #endif
     if (*plength > (omax - (p - *pp))) {
         ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
         /*
          * Set this so that even if things are not long enough the values are
          * set correctly
          */
         ret |= 0x80;
     }
     *pp = p;
     return (ret | inf);
  err:
     ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
     return (0x80);
 }
 
 static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
                            long max)
 {
     const unsigned char *p = *pp;
     unsigned long ret = 0;
     unsigned long i;
 
     if (max-- < 1)
         return 0;
     if (*p == 0x80) {
         *inf = 1;
         ret = 0;
         p++;
     } else {
         *inf = 0;
         i = *p & 0x7f;
         if (*(p++) & 0x80) {
             if (i > sizeof(ret) || max < (long)i)
                 return 0;
             while (i-- > 0) {
                 ret <<= 8L;
                 ret |= *(p++);
             }
         } else
             ret = i;
     }
     if (ret > LONG_MAX)
         return 0;
     *pp = p;
     *rl = (long)ret;
     return 1;
 }
 
 /*
  * class 0 is constructed constructed == 2 for indefinite length constructed
  */
 void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
                      int xclass)
 {
     unsigned char *p = *pp;
     int i, ttag;
 
     i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
     i |= (xclass & V_ASN1_PRIVATE);
     if (tag < 31)
         *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
     else {
         *(p++) = i | V_ASN1_PRIMITIVE_TAG;
         for (i = 0, ttag = tag; ttag > 0; i++)
             ttag >>= 7;
         ttag = i;
         while (i-- > 0) {
             p[i] = tag & 0x7f;
             if (i != (ttag - 1))
                 p[i] |= 0x80;
             tag >>= 7;
         }
         p += ttag;
     }
     if (constructed == 2)
         *(p++) = 0x80;
     else
         asn1_put_length(&p, length);
     *pp = p;
 }
 
 int ASN1_put_eoc(unsigned char **pp)
 {
     unsigned char *p = *pp;
     *p++ = 0;
     *p++ = 0;
     *pp = p;
     return 2;
 }
 
 static void asn1_put_length(unsigned char **pp, int length)
 {
     unsigned char *p = *pp;
     int i, l;
     if (length <= 127)
         *(p++) = (unsigned char)length;
     else {
         l = length;
         for (i = 0; l > 0; i++)
             l >>= 8;
         *(p++) = i | 0x80;
         l = i;
         while (i-- > 0) {
             p[i] = length & 0xff;
             length >>= 8;
         }
         p += l;
     }
     *pp = p;
 }
 
 int ASN1_object_size(int constructed, int length, int tag)
 {
-    int ret;
-
-    ret = length;
-    ret++;
+    int ret = 1;
+    if (length < 0)
+        return -1;
     if (tag >= 31) {
         while (tag > 0) {
             tag >>= 7;
             ret++;
         }
     }
-    if (constructed == 2)
-        return ret + 3;
-    ret++;
-    if (length > 127) {
-        while (length > 0) {
-            length >>= 8;
-            ret++;
+    if (constructed == 2) {
+        ret += 3;
+    } else {
+        ret++;
+        if (length > 127) {
+            int tmplen = length;
+            while (tmplen > 0) {
+                tmplen >>= 8;
+                ret++;
+            }
         }
     }
-    return (ret);
+    if (ret >= INT_MAX - length)
+        return -1;
+    return ret + length;
 }
 
 static int _asn1_Finish(ASN1_const_CTX *c)
 {
     if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
         if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
             c->error = ERR_R_MISSING_ASN1_EOS;
             return (0);
         }
     }
     if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
         c->error = ERR_R_ASN1_LENGTH_MISMATCH;
         return (0);
     }
     return (1);
 }
 
 int asn1_Finish(ASN1_CTX *c)
 {
     return _asn1_Finish((ASN1_const_CTX *)c);
 }
 
 int asn1_const_Finish(ASN1_const_CTX *c)
 {
     return _asn1_Finish(c);
 }
 
 int asn1_GetSequence(ASN1_const_CTX *c, long *length)
 {
     const unsigned char *q;
 
     q = c->p;
     c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
                              *length);
     if (c->inf & 0x80) {
         c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
         return (0);
     }
     if (c->tag != V_ASN1_SEQUENCE) {
         c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
         return (0);
     }
     (*length) -= (c->p - q);
     if (c->max && (*length < 0)) {
         c->error = ERR_R_ASN1_LENGTH_MISMATCH;
         return (0);
     }
     if (c->inf == (1 | V_ASN1_CONSTRUCTED))
-        c->slen = *length + *(c->pp) - c->p;
+        c->slen = *length;
     c->eos = 0;
     return (1);
 }
 
 int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
 {
     if (str == NULL)
         return 0;
     dst->type = str->type;
     if (!ASN1_STRING_set(dst, str->data, str->length))
         return 0;
     dst->flags = str->flags;
     return 1;
 }
 
 ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
 {
     ASN1_STRING *ret;
     if (!str)
         return NULL;
     ret = ASN1_STRING_new();
     if (!ret)
         return NULL;
     if (!ASN1_STRING_copy(ret, str)) {
         ASN1_STRING_free(ret);
         return NULL;
     }
     return ret;
 }
 
 int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
 {
     unsigned char *c;
     const char *data = _data;
 
     if (len < 0) {
         if (data == NULL)
             return (0);
         else
             len = strlen(data);
     }
-    if ((str->length < len) || (str->data == NULL)) {
+    if ((str->length <= len) || (str->data == NULL)) {
         c = str->data;
         if (c == NULL)
             str->data = OPENSSL_malloc(len + 1);
         else
             str->data = OPENSSL_realloc(c, len + 1);
 
         if (str->data == NULL) {
             ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
             str->data = c;
             return (0);
         }
     }
     str->length = len;
     if (data != NULL) {
         memcpy(str->data, data, len);
         /* an allowance for strings :-) */
         str->data[len] = '\0';
     }
     return (1);
 }
 
 void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
 {
     if (str->data)
         OPENSSL_free(str->data);
     str->data = data;
     str->length = len;
 }
 
 ASN1_STRING *ASN1_STRING_new(void)
 {
     return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
 }
 
 ASN1_STRING *ASN1_STRING_type_new(int type)
 {
     ASN1_STRING *ret;
 
     ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
     if (ret == NULL) {
         ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
         return (NULL);
     }
     ret->length = 0;
     ret->type = type;
     ret->data = NULL;
     ret->flags = 0;
     return (ret);
 }
 
 void ASN1_STRING_free(ASN1_STRING *a)
 {
     if (a == NULL)
         return;
     if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
         OPENSSL_free(a->data);
     OPENSSL_free(a);
 }
 
 void ASN1_STRING_clear_free(ASN1_STRING *a)
 {
     if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
         OPENSSL_cleanse(a->data, a->length);
     ASN1_STRING_free(a);
 }
 
 int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
 {
     int i;
 
     i = (a->length - b->length);
     if (i == 0) {
         i = memcmp(a->data, b->data, a->length);
         if (i == 0)
             return (a->type - b->type);
         else
             return (i);
     } else
         return (i);
 }
 
 void asn1_add_error(const unsigned char *address, int offset)
 {
     char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1];
 
     BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address);
     BIO_snprintf(buf2, sizeof buf2, "%d", offset);
     ERR_add_error_data(4, "address=", buf1, " offset=", buf2);
 }
 
 int ASN1_STRING_length(const ASN1_STRING *x)
 {
     return M_ASN1_STRING_length(x);
 }
 
 void ASN1_STRING_length_set(ASN1_STRING *x, int len)
 {
     M_ASN1_STRING_length_set(x, len);
     return;
 }
 
 int ASN1_STRING_type(ASN1_STRING *x)
 {
     return M_ASN1_STRING_type(x);
 }
 
 unsigned char *ASN1_STRING_data(ASN1_STRING *x)
 {
     return M_ASN1_STRING_data(x);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn_mime.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn_mime.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/asn_mime.c	(revision 306191)
@@ -1,974 +1,974 @@
 /* asn_mime.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
  * Copyright (c) 1999-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 <ctype.h>
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #include "asn1_locl.h"
 
 /*
  * Generalised MIME like utilities for streaming ASN1. Although many have a
  * PKCS7/CMS like flavour others are more general purpose.
  */
 
 /*
  * MIME format structures Note that all are translated to lower case apart
  * from parameter values. Quotes are stripped off
  */
 
 typedef struct {
     char *param_name;           /* Param name e.g. "micalg" */
     char *param_value;          /* Param value e.g. "sha1" */
 } MIME_PARAM;
 
 DECLARE_STACK_OF(MIME_PARAM)
 IMPLEMENT_STACK_OF(MIME_PARAM)
 
 typedef struct {
     char *name;                 /* Name of line e.g. "content-type" */
     char *value;                /* Value of line e.g. "text/plain" */
     STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
 } MIME_HEADER;
 
 DECLARE_STACK_OF(MIME_HEADER)
 IMPLEMENT_STACK_OF(MIME_HEADER)
 
 static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
                             const ASN1_ITEM *it);
 static char *strip_ends(char *name);
 static char *strip_start(char *name);
 static char *strip_end(char *name);
 static MIME_HEADER *mime_hdr_new(char *name, char *value);
 static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
 static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
 static int mime_hdr_cmp(const MIME_HEADER *const *a,
                         const MIME_HEADER *const *b);
 static int mime_param_cmp(const MIME_PARAM *const *a,
                           const MIME_PARAM *const *b);
 static void mime_param_free(MIME_PARAM *param);
 static int mime_bound_check(char *line, int linelen, char *bound, int blen);
 static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
 static int strip_eol(char *linebuf, int *plen);
 static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
 static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
 static void mime_hdr_free(MIME_HEADER *hdr);
 
 #define MAX_SMLEN 1024
 #define mime_debug(x)           /* x */
 
 /* Output an ASN1 structure in BER format streaming if necessary */
 
 int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                         const ASN1_ITEM *it)
 {
     /* If streaming create stream BIO and copy all content through it */
     if (flags & SMIME_STREAM) {
         BIO *bio, *tbio;
         bio = BIO_new_NDEF(out, val, it);
         if (!bio) {
             ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE);
             return 0;
         }
         SMIME_crlf_copy(in, bio, flags);
         (void)BIO_flush(bio);
         /* Free up successive BIOs until we hit the old output BIO */
         do {
             tbio = BIO_pop(bio);
             BIO_free(bio);
             bio = tbio;
         } while (bio != out);
     }
     /*
      * else just write out ASN1 structure which will have all content stored
      * internally
      */
     else
         ASN1_item_i2d_bio(it, out, val);
     return 1;
 }
 
 /* Base 64 read and write of ASN1 structure */
 
 static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                           const ASN1_ITEM *it)
 {
     BIO *b64;
     int r;
     b64 = BIO_new(BIO_f_base64());
     if (!b64) {
         ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     /*
      * prepend the b64 BIO so all data is base64 encoded.
      */
     out = BIO_push(b64, out);
     r = i2d_ASN1_bio_stream(out, val, in, flags, it);
     (void)BIO_flush(out);
     BIO_pop(out);
     BIO_free(b64);
     return r;
 }
 
 /* Streaming ASN1 PEM write */
 
 int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags,
                               const char *hdr, const ASN1_ITEM *it)
 {
     int r;
     BIO_printf(out, "-----BEGIN %s-----\n", hdr);
     r = B64_write_ASN1(out, val, in, flags, it);
     BIO_printf(out, "-----END %s-----\n", hdr);
     return r;
 }
 
 static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it)
 {
     BIO *b64;
     ASN1_VALUE *val;
     if (!(b64 = BIO_new(BIO_f_base64()))) {
         ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     bio = BIO_push(b64, bio);
     val = ASN1_item_d2i_bio(it, bio, NULL);
     if (!val)
         ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR);
     (void)BIO_flush(bio);
     bio = BIO_pop(bio);
     BIO_free(b64);
     return val;
 }
 
 /* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */
 
 static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
 {
     const EVP_MD *md;
     int i, have_unknown = 0, write_comma, ret = 0, md_nid;
     have_unknown = 0;
     write_comma = 0;
     for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) {
         if (write_comma)
             BIO_write(out, ",", 1);
         write_comma = 1;
         md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm);
         md = EVP_get_digestbynid(md_nid);
         if (md && md->md_ctrl) {
             int rv;
             char *micstr;
             rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr);
             if (rv > 0) {
                 BIO_puts(out, micstr);
                 OPENSSL_free(micstr);
                 continue;
             }
             if (rv != -2)
                 goto err;
         }
         switch (md_nid) {
         case NID_sha1:
             BIO_puts(out, "sha1");
             break;
 
         case NID_md5:
             BIO_puts(out, "md5");
             break;
 
         case NID_sha256:
             BIO_puts(out, "sha-256");
             break;
 
         case NID_sha384:
             BIO_puts(out, "sha-384");
             break;
 
         case NID_sha512:
             BIO_puts(out, "sha-512");
             break;
 
         case NID_id_GostR3411_94:
             BIO_puts(out, "gostr3411-94");
             goto err;
             break;
 
         default:
             if (have_unknown)
                 write_comma = 0;
             else {
                 BIO_puts(out, "unknown");
                 have_unknown = 1;
             }
             break;
 
         }
     }
 
     ret = 1;
  err:
 
     return ret;
 
 }
 
 /* SMIME sender */
 
 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)
 {
     char bound[33], c;
     int i;
     const char *mime_prefix, *mime_eol, *cname = "smime.p7m";
     const char *msg_type = NULL;
     if (flags & SMIME_OLDMIME)
         mime_prefix = "application/x-pkcs7-";
     else
         mime_prefix = "application/pkcs7-";
 
     if (flags & SMIME_CRLFEOL)
         mime_eol = "\r\n";
     else
         mime_eol = "\n";
     if ((flags & SMIME_DETACHED) && data) {
         /* We want multipart/signed */
         /* Generate a random boundary */
-        if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+        if (RAND_bytes((unsigned char *)bound, 32) <= 0)
             return 0;
         for (i = 0; i < 32; i++) {
             c = bound[i] & 0xf;
             if (c < 10)
                 c += '0';
             else
                 c += 'A' - 10;
             bound[i] = c;
         }
         bound[32] = 0;
         BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
         BIO_printf(bio, "Content-Type: multipart/signed;");
         BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
         BIO_puts(bio, " micalg=\"");
         asn1_write_micalg(bio, mdalgs);
         BIO_printf(bio, "\"; boundary=\"----%s\"%s%s",
                    bound, mime_eol, mime_eol);
         BIO_printf(bio, "This is an S/MIME signed message%s%s",
                    mime_eol, mime_eol);
         /* Now write out the first part */
         BIO_printf(bio, "------%s%s", bound, mime_eol);
         if (!asn1_output_data(bio, data, val, flags, it))
             return 0;
         BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
 
         /* Headers for signature */
 
         BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
         BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
         BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol);
         BIO_printf(bio, "Content-Disposition: attachment;");
         BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol);
         B64_write_ASN1(bio, val, NULL, 0, it);
         BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound,
                    mime_eol, mime_eol);
         return 1;
     }
 
     /* Determine smime-type header */
 
     if (ctype_nid == NID_pkcs7_enveloped)
         msg_type = "enveloped-data";
     else if (ctype_nid == NID_pkcs7_signed) {
         if (econt_nid == NID_id_smime_ct_receipt)
             msg_type = "signed-receipt";
         else if (sk_X509_ALGOR_num(mdalgs) >= 0)
             msg_type = "signed-data";
         else
             msg_type = "certs-only";
     } else if (ctype_nid == NID_id_smime_ct_compressedData) {
         msg_type = "compressed-data";
         cname = "smime.p7z";
     }
     /* MIME headers */
     BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
     BIO_printf(bio, "Content-Disposition: attachment;");
     BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol);
     BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
     if (msg_type)
         BIO_printf(bio, " smime-type=%s;", msg_type);
     BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol);
     BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
                mime_eol, mime_eol);
     if (!B64_write_ASN1(bio, val, data, flags, it))
         return 0;
     BIO_printf(bio, "%s", mime_eol);
     return 1;
 }
 
 /* Handle output of ASN1 data */
 
 static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags,
                             const ASN1_ITEM *it)
 {
     BIO *tmpbio;
     const ASN1_AUX *aux = it->funcs;
     ASN1_STREAM_ARG sarg;
     int rv = 1;
 
     /*
      * If data is not deteched or resigning then the output BIO is already
      * set up to finalise when it is written through.
      */
     if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) {
         SMIME_crlf_copy(data, out, flags);
         return 1;
     }
 
     if (!aux || !aux->asn1_cb) {
         ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED);
         return 0;
     }
 
     sarg.out = out;
     sarg.ndef_bio = NULL;
     sarg.boundary = NULL;
 
     /* Let ASN1 code prepend any needed BIOs */
 
     if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0)
         return 0;
 
     /* Copy data across, passing through filter BIOs for processing */
     SMIME_crlf_copy(data, sarg.ndef_bio, flags);
 
     /* Finalize structure */
     if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0)
         rv = 0;
 
     /* Now remove any digests prepended to the BIO */
 
     while (sarg.ndef_bio != out) {
         tmpbio = BIO_pop(sarg.ndef_bio);
         BIO_free(sarg.ndef_bio);
         sarg.ndef_bio = tmpbio;
     }
 
     return rv;
 
 }
 
 /*
  * SMIME reader: handle multipart/signed and opaque signing. in multipart
  * case the content is placed in a memory BIO pointed to by "bcont". In
  * opaque this is set to NULL
  */
 
 ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it)
 {
     BIO *asnin;
     STACK_OF(MIME_HEADER) *headers = NULL;
     STACK_OF(BIO) *parts = NULL;
     MIME_HEADER *hdr;
     MIME_PARAM *prm;
     ASN1_VALUE *val;
     int ret;
 
     if (bcont)
         *bcont = NULL;
 
     if (!(headers = mime_parse_hdr(bio))) {
         ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR);
         return NULL;
     }
 
     if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE);
         return NULL;
     }
 
     /* Handle multipart/signed */
 
     if (!strcmp(hdr->value, "multipart/signed")) {
         /* Split into two parts */
         prm = mime_param_find(hdr, "boundary");
         if (!prm || !prm->param_value) {
             sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY);
             return NULL;
         }
         ret = multi_split(bio, prm->param_value, &parts);
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         if (!ret || (sk_BIO_num(parts) != 2)) {
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE);
             sk_BIO_pop_free(parts, BIO_vfree);
             return NULL;
         }
 
         /* Parse the signature piece */
         asnin = sk_BIO_value(parts, 1);
 
         if (!(headers = mime_parse_hdr(asnin))) {
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR);
             sk_BIO_pop_free(parts, BIO_vfree);
             return NULL;
         }
 
         /* Get content type */
 
         if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
             sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE);
             return NULL;
         }
 
         if (strcmp(hdr->value, "application/x-pkcs7-signature") &&
             strcmp(hdr->value, "application/pkcs7-signature")) {
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE);
             ERR_add_error_data(2, "type: ", hdr->value);
             sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
             sk_BIO_pop_free(parts, BIO_vfree);
             return NULL;
         }
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         /* Read in ASN1 */
         if (!(val = b64_read_asn1(asnin, it))) {
             ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR);
             sk_BIO_pop_free(parts, BIO_vfree);
             return NULL;
         }
 
         if (bcont) {
             *bcont = sk_BIO_value(parts, 0);
             BIO_free(asnin);
             sk_BIO_free(parts);
         } else
             sk_BIO_pop_free(parts, BIO_vfree);
         return val;
     }
 
     /* OK, if not multipart/signed try opaque signature */
 
     if (strcmp(hdr->value, "application/x-pkcs7-mime") &&
         strcmp(hdr->value, "application/pkcs7-mime")) {
         ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE);
         ERR_add_error_data(2, "type: ", hdr->value);
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         return NULL;
     }
 
     sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
 
     if (!(val = b64_read_asn1(bio, it))) {
         ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR);
         return NULL;
     }
     return val;
 
 }
 
 /* Copy text from one BIO to another making the output CRLF at EOL */
 int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
 {
     BIO *bf;
     char eol;
     int len;
     char linebuf[MAX_SMLEN];
     /*
      * Buffer output so we don't write one line at a time. This is useful
      * when streaming as we don't end up with one OCTET STRING per line.
      */
     bf = BIO_new(BIO_f_buffer());
     if (!bf)
         return 0;
     out = BIO_push(bf, out);
     if (flags & SMIME_BINARY) {
         while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
             BIO_write(out, linebuf, len);
     } else {
         if (flags & SMIME_TEXT)
             BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
         while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
             eol = strip_eol(linebuf, &len);
             if (len)
                 BIO_write(out, linebuf, len);
             if (eol)
                 BIO_write(out, "\r\n", 2);
         }
     }
     (void)BIO_flush(out);
     BIO_pop(out);
     BIO_free(bf);
     return 1;
 }
 
 /* Strip off headers if they are text/plain */
 int SMIME_text(BIO *in, BIO *out)
 {
     char iobuf[4096];
     int len;
     STACK_OF(MIME_HEADER) *headers;
     MIME_HEADER *hdr;
 
     if (!(headers = mime_parse_hdr(in))) {
         ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR);
         return 0;
     }
     if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
         ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE);
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         return 0;
     }
     if (strcmp(hdr->value, "text/plain")) {
         ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE);
         ERR_add_error_data(2, "type: ", hdr->value);
         sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
         return 0;
     }
     sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
     while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
         BIO_write(out, iobuf, len);
     if (len < 0)
         return 0;
     return 1;
 }
 
 /*
  * Split a multipart/XXX message body into component parts: result is
  * canonical parts in a STACK of bios
  */
 
 static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
 {
     char linebuf[MAX_SMLEN];
     int len, blen;
     int eol = 0, next_eol = 0;
     BIO *bpart = NULL;
     STACK_OF(BIO) *parts;
     char state, part, first;
 
     blen = strlen(bound);
     part = 0;
     state = 0;
     first = 1;
     parts = sk_BIO_new_null();
     *ret = parts;
     while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
         state = mime_bound_check(linebuf, len, bound, blen);
         if (state == 1) {
             first = 1;
             part++;
         } else if (state == 2) {
             sk_BIO_push(parts, bpart);
             return 1;
         } else if (part) {
             /* Strip CR+LF from linebuf */
             next_eol = strip_eol(linebuf, &len);
             if (first) {
                 first = 0;
                 if (bpart)
                     sk_BIO_push(parts, bpart);
                 bpart = BIO_new(BIO_s_mem());
                 BIO_set_mem_eof_return(bpart, 0);
             } else if (eol)
                 BIO_write(bpart, "\r\n", 2);
             eol = next_eol;
             if (len)
                 BIO_write(bpart, linebuf, len);
         }
     }
     return 0;
 }
 
 /* This is the big one: parse MIME header lines up to message body */
 
 #define MIME_INVALID    0
 #define MIME_START      1
 #define MIME_TYPE       2
 #define MIME_NAME       3
 #define MIME_VALUE      4
 #define MIME_QUOTE      5
 #define MIME_COMMENT    6
 
 static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
 {
     char *p, *q, c;
     char *ntmp;
     char linebuf[MAX_SMLEN];
     MIME_HEADER *mhdr = NULL;
     STACK_OF(MIME_HEADER) *headers;
     int len, state, save_state = 0;
 
     headers = sk_MIME_HEADER_new(mime_hdr_cmp);
     if (!headers)
         return NULL;
     while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
         /* If whitespace at line start then continuation line */
         if (mhdr && isspace((unsigned char)linebuf[0]))
             state = MIME_NAME;
         else
             state = MIME_START;
         ntmp = NULL;
         /* Go through all characters */
         for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n');
              p++) {
 
             /*
              * State machine to handle MIME headers if this looks horrible
              * that's because it *is*
              */
 
             switch (state) {
             case MIME_START:
                 if (c == ':') {
                     state = MIME_TYPE;
                     *p = 0;
                     ntmp = strip_ends(q);
                     q = p + 1;
                 }
                 break;
 
             case MIME_TYPE:
                 if (c == ';') {
                     mime_debug("Found End Value\n");
                     *p = 0;
                     mhdr = mime_hdr_new(ntmp, strip_ends(q));
                     sk_MIME_HEADER_push(headers, mhdr);
                     ntmp = NULL;
                     q = p + 1;
                     state = MIME_NAME;
                 } else if (c == '(') {
                     save_state = state;
                     state = MIME_COMMENT;
                 }
                 break;
 
             case MIME_COMMENT:
                 if (c == ')') {
                     state = save_state;
                 }
                 break;
 
             case MIME_NAME:
                 if (c == '=') {
                     state = MIME_VALUE;
                     *p = 0;
                     ntmp = strip_ends(q);
                     q = p + 1;
                 }
                 break;
 
             case MIME_VALUE:
                 if (c == ';') {
                     state = MIME_NAME;
                     *p = 0;
                     mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
                     ntmp = NULL;
                     q = p + 1;
                 } else if (c == '"') {
                     mime_debug("Found Quote\n");
                     state = MIME_QUOTE;
                 } else if (c == '(') {
                     save_state = state;
                     state = MIME_COMMENT;
                 }
                 break;
 
             case MIME_QUOTE:
                 if (c == '"') {
                     mime_debug("Found Match Quote\n");
                     state = MIME_VALUE;
                 }
                 break;
             }
         }
 
         if (state == MIME_TYPE) {
             mhdr = mime_hdr_new(ntmp, strip_ends(q));
             sk_MIME_HEADER_push(headers, mhdr);
         } else if (state == MIME_VALUE)
             mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
         if (p == linebuf)
             break;              /* Blank line means end of headers */
     }
 
     return headers;
 
 }
 
 static char *strip_ends(char *name)
 {
     return strip_end(strip_start(name));
 }
 
 /* Strip a parameter of whitespace from start of param */
 static char *strip_start(char *name)
 {
     char *p, c;
     /* Look for first non white space or quote */
     for (p = name; (c = *p); p++) {
         if (c == '"') {
             /* Next char is start of string if non null */
             if (p[1])
                 return p + 1;
             /* Else null string */
             return NULL;
         }
         if (!isspace((unsigned char)c))
             return p;
     }
     return NULL;
 }
 
 /* As above but strip from end of string : maybe should handle brackets? */
 static char *strip_end(char *name)
 {
     char *p, c;
     if (!name)
         return NULL;
     /* Look for first non white space or quote */
     for (p = name + strlen(name) - 1; p >= name; p--) {
         c = *p;
         if (c == '"') {
             if (p - 1 == name)
                 return NULL;
             *p = 0;
             return name;
         }
         if (isspace((unsigned char)c))
             *p = 0;
         else
             return name;
     }
     return NULL;
 }
 
 static MIME_HEADER *mime_hdr_new(char *name, char *value)
 {
     MIME_HEADER *mhdr;
     char *tmpname, *tmpval, *p;
     int c;
     if (name) {
         if (!(tmpname = BUF_strdup(name)))
             return NULL;
         for (p = tmpname; *p; p++) {
             c = (unsigned char)*p;
             if (isupper(c)) {
                 c = tolower(c);
                 *p = c;
             }
         }
     } else
         tmpname = NULL;
     if (value) {
         if (!(tmpval = BUF_strdup(value)))
             return NULL;
         for (p = tmpval; *p; p++) {
             c = (unsigned char)*p;
             if (isupper(c)) {
                 c = tolower(c);
                 *p = c;
             }
         }
     } else
         tmpval = NULL;
     mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER));
     if (!mhdr)
         return NULL;
     mhdr->name = tmpname;
     mhdr->value = tmpval;
     if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp)))
         return NULL;
     return mhdr;
 }
 
 static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
 {
     char *tmpname, *tmpval, *p;
     int c;
     MIME_PARAM *mparam;
     if (name) {
         tmpname = BUF_strdup(name);
         if (!tmpname)
             return 0;
         for (p = tmpname; *p; p++) {
             c = (unsigned char)*p;
             if (isupper(c)) {
                 c = tolower(c);
                 *p = c;
             }
         }
     } else
         tmpname = NULL;
     if (value) {
         tmpval = BUF_strdup(value);
         if (!tmpval)
             return 0;
     } else
         tmpval = NULL;
     /* Parameter values are case sensitive so leave as is */
     mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM));
     if (!mparam)
         return 0;
     mparam->param_name = tmpname;
     mparam->param_value = tmpval;
     sk_MIME_PARAM_push(mhdr->params, mparam);
     return 1;
 }
 
 static int mime_hdr_cmp(const MIME_HEADER *const *a,
                         const MIME_HEADER *const *b)
 {
     if (!(*a)->name || !(*b)->name)
         return ! !(*a)->name - ! !(*b)->name;
 
     return (strcmp((*a)->name, (*b)->name));
 }
 
 static int mime_param_cmp(const MIME_PARAM *const *a,
                           const MIME_PARAM *const *b)
 {
     if (!(*a)->param_name || !(*b)->param_name)
         return ! !(*a)->param_name - ! !(*b)->param_name;
     return (strcmp((*a)->param_name, (*b)->param_name));
 }
 
 /* Find a header with a given name (if possible) */
 
 static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
 {
     MIME_HEADER htmp;
     int idx;
     htmp.name = name;
     idx = sk_MIME_HEADER_find(hdrs, &htmp);
     if (idx < 0)
         return NULL;
     return sk_MIME_HEADER_value(hdrs, idx);
 }
 
 static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
 {
     MIME_PARAM param;
     int idx;
     param.param_name = name;
     idx = sk_MIME_PARAM_find(hdr->params, &param);
     if (idx < 0)
         return NULL;
     return sk_MIME_PARAM_value(hdr->params, idx);
 }
 
 static void mime_hdr_free(MIME_HEADER *hdr)
 {
     if (hdr->name)
         OPENSSL_free(hdr->name);
     if (hdr->value)
         OPENSSL_free(hdr->value);
     if (hdr->params)
         sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
     OPENSSL_free(hdr);
 }
 
 static void mime_param_free(MIME_PARAM *param)
 {
     if (param->param_name)
         OPENSSL_free(param->param_name);
     if (param->param_value)
         OPENSSL_free(param->param_value);
     OPENSSL_free(param);
 }
 
 /*-
  * Check for a multipart boundary. Returns:
  * 0 : no boundary
  * 1 : part boundary
  * 2 : final boundary
  */
 static int mime_bound_check(char *line, int linelen, char *bound, int blen)
 {
     if (linelen == -1)
         linelen = strlen(line);
     if (blen == -1)
         blen = strlen(bound);
     /* Quickly eliminate if line length too short */
     if (blen + 2 > linelen)
         return 0;
     /* Check for part boundary */
     if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
         if (!strncmp(line + blen + 2, "--", 2))
             return 2;
         else
             return 1;
     }
     return 0;
 }
 
 static int strip_eol(char *linebuf, int *plen)
 {
     int len = *plen;
     char *p, c;
     int is_eol = 0;
     p = linebuf + len - 1;
     for (p = linebuf + len - 1; len > 0; len--, p--) {
         c = *p;
         if (c == '\n')
             is_eol = 1;
         else if (c != '\r')
             break;
     }
     *plen = len;
     return is_eol;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/d2i_pr.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/d2i_pr.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/d2i_pr.c	(revision 306191)
@@ -1,175 +1,177 @@
 /* crypto/asn1/d2i_pr.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/objects.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 #include <openssl/x509.h>
 #include <openssl/asn1.h>
 #include "asn1_locl.h"
 
 EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
                          long length)
 {
     EVP_PKEY *ret;
     const unsigned char *p = *pp;
 
     if ((a == NULL) || (*a == NULL)) {
         if ((ret = EVP_PKEY_new()) == NULL) {
             ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
             return (NULL);
         }
     } else {
         ret = *a;
 #ifndef OPENSSL_NO_ENGINE
         if (ret->engine) {
             ENGINE_finish(ret->engine);
             ret->engine = NULL;
         }
 #endif
     }
 
     if (!EVP_PKEY_set_type(ret, type)) {
         ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
         goto err;
     }
 
     if (!ret->ameth->old_priv_decode ||
         !ret->ameth->old_priv_decode(ret, &p, length)) {
         if (ret->ameth->priv_decode) {
+            EVP_PKEY *tmp;
             PKCS8_PRIV_KEY_INFO *p8 = NULL;
             p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
             if (!p8)
                 goto err;
-            EVP_PKEY_free(ret);
-            ret = EVP_PKCS82PKEY(p8);
+            tmp = EVP_PKCS82PKEY(p8);
             PKCS8_PRIV_KEY_INFO_free(p8);
-            if (ret == NULL)
+            if (tmp == NULL)
                 goto err;
+            EVP_PKEY_free(ret);
+            ret = tmp;
         } else {
             ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
             goto err;
         }
     }
     *pp = p;
     if (a != NULL)
         (*a) = ret;
     return (ret);
  err:
     if ((ret != NULL) && ((a == NULL) || (*a != ret)))
         EVP_PKEY_free(ret);
     return (NULL);
 }
 
 /*
  * This works like d2i_PrivateKey() except it automatically works out the
  * type
  */
 
 EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
                              long length)
 {
     STACK_OF(ASN1_TYPE) *inkey;
     const unsigned char *p;
     int keytype;
     p = *pp;
     /*
      * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
      * analyzing it we can determine the passed structure: this assumes the
      * input is surrounded by an ASN1 SEQUENCE.
      */
     inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
     p = *pp;
     /*
      * Since we only need to discern "traditional format" RSA and DSA keys we
      * can just count the elements.
      */
     if (sk_ASN1_TYPE_num(inkey) == 6)
         keytype = EVP_PKEY_DSA;
     else if (sk_ASN1_TYPE_num(inkey) == 4)
         keytype = EVP_PKEY_EC;
     else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
                                               * traditional format */
         PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
         EVP_PKEY *ret;
 
         sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
         if (!p8) {
             ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
                     ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
             return NULL;
         }
         ret = EVP_PKCS82PKEY(p8);
         PKCS8_PRIV_KEY_INFO_free(p8);
         if (ret == NULL)
             return NULL;
         *pp = p;
         if (a) {
             *a = ret;
         }
         return ret;
     } else
         keytype = EVP_PKEY_RSA;
     sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
     return d2i_PrivateKey(keytype, a, pp, length);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_enum.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_enum.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_enum.c	(revision 306191)
@@ -1,203 +1,203 @@
 /* crypto/asn1/f_enum.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/asn1.h>
 
 /* Based on a_int.c: equivalent ENUMERATED functions */
 
 int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
 {
     int i, n = 0;
     static const char *h = "0123456789ABCDEF";
     char buf[2];
 
     if (a == NULL)
         return (0);
 
     if (a->length == 0) {
         if (BIO_write(bp, "00", 2) != 2)
             goto err;
         n = 2;
     } else {
         for (i = 0; i < a->length; i++) {
             if ((i != 0) && (i % 35 == 0)) {
                 if (BIO_write(bp, "\\\n", 2) != 2)
                     goto err;
                 n += 2;
             }
             buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
             buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
             if (BIO_write(bp, buf, 2) != 2)
                 goto err;
             n += 2;
         }
     }
     return (n);
  err:
     return (-1);
 }
 
 int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
 {
     int ret = 0;
     int i, j, k, m, n, again, bufsize;
     unsigned char *s = NULL, *sp;
     unsigned char *bufp;
     int num = 0, slen = 0, first = 1;
 
     bs->type = V_ASN1_ENUMERATED;
 
     bufsize = BIO_gets(bp, buf, size);
     for (;;) {
         if (bufsize < 1)
             goto err_sl;
         i = bufsize;
         if (buf[i - 1] == '\n')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         if (buf[i - 1] == '\r')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         again = (buf[i - 1] == '\\');
 
         for (j = 0; j < i; j++) {
             if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
                   ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                   ((buf[j] >= 'A') && (buf[j] <= 'F')))) {
                 i = j;
                 break;
             }
         }
         buf[i] = '\0';
         /*
          * We have now cleared all the crap off the end of the line
          */
         if (i < 2)
             goto err_sl;
 
         bufp = (unsigned char *)buf;
         if (first) {
             first = 0;
             if ((bufp[0] == '0') && (buf[1] == '0')) {
                 bufp += 2;
                 i -= 2;
             }
         }
         k = 0;
         i -= again;
         if (i % 2 != 0) {
             ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
             goto err;
         }
         i /= 2;
         if (num + i > slen) {
             if (s == NULL)
                 sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
                                                      i * 2);
             else
                 sp = (unsigned char *)OPENSSL_realloc(s,
                                                       (unsigned int)num +
                                                       i * 2);
             if (sp == NULL) {
                 ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
-                if (s != NULL)
-                    OPENSSL_free(s);
                 goto err;
             }
             s = sp;
             slen = num + i * 2;
         }
         for (j = 0; j < i; j++, k += 2) {
             for (n = 0; n < 2; n++) {
                 m = bufp[k + n];
                 if ((m >= '0') && (m <= '9'))
                     m -= '0';
                 else if ((m >= 'a') && (m <= 'f'))
                     m = m - 'a' + 10;
                 else if ((m >= 'A') && (m <= 'F'))
                     m = m - 'A' + 10;
                 else {
                     ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
                             ASN1_R_NON_HEX_CHARACTERS);
                     goto err;
                 }
                 s[num + j] <<= 4;
                 s[num + j] |= m;
             }
         }
         num += i;
         if (again)
             bufsize = BIO_gets(bp, buf, size);
         else
             break;
     }
     bs->length = num;
     bs->data = s;
     ret = 1;
  err:
     if (0) {
  err_sl:
         ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
     }
+    if (ret != 1)
+        OPENSSL_free(s);
     return (ret);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_int.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_int.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_int.c	(revision 306191)
@@ -1,215 +1,215 @@
 /* crypto/asn1/f_int.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/asn1.h>
 
 int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
 {
     int i, n = 0;
     static const char *h = "0123456789ABCDEF";
     char buf[2];
 
     if (a == NULL)
         return (0);
 
     if (a->type & V_ASN1_NEG) {
         if (BIO_write(bp, "-", 1) != 1)
             goto err;
         n = 1;
     }
 
     if (a->length == 0) {
         if (BIO_write(bp, "00", 2) != 2)
             goto err;
         n += 2;
     } else {
         for (i = 0; i < a->length; i++) {
             if ((i != 0) && (i % 35 == 0)) {
                 if (BIO_write(bp, "\\\n", 2) != 2)
                     goto err;
                 n += 2;
             }
             buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
             buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
             if (BIO_write(bp, buf, 2) != 2)
                 goto err;
             n += 2;
         }
     }
     return (n);
  err:
     return (-1);
 }
 
 int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
 {
     int ret = 0;
     int i, j, k, m, n, again, bufsize;
     unsigned char *s = NULL, *sp;
     unsigned char *bufp;
     int num = 0, slen = 0, first = 1;
 
     bs->type = V_ASN1_INTEGER;
 
     bufsize = BIO_gets(bp, buf, size);
     for (;;) {
         if (bufsize < 1)
             goto err_sl;
         i = bufsize;
         if (buf[i - 1] == '\n')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         if (buf[i - 1] == '\r')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         again = (buf[i - 1] == '\\');
 
         for (j = 0; j < i; j++) {
 #ifndef CHARSET_EBCDIC
             if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
                   ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                   ((buf[j] >= 'A') && (buf[j] <= 'F'))))
 #else
             /*
              * This #ifdef is not strictly necessary, since the characters
              * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
              * not the whole alphabet). Nevertheless, isxdigit() is faster.
              */
             if (!isxdigit(buf[j]))
 #endif
             {
                 i = j;
                 break;
             }
         }
         buf[i] = '\0';
         /*
          * We have now cleared all the crap off the end of the line
          */
         if (i < 2)
             goto err_sl;
 
         bufp = (unsigned char *)buf;
         if (first) {
             first = 0;
             if ((bufp[0] == '0') && (buf[1] == '0')) {
                 bufp += 2;
                 i -= 2;
             }
         }
         k = 0;
         i -= again;
         if (i % 2 != 0) {
             ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
             goto err;
         }
         i /= 2;
         if (num + i > slen) {
             if (s == NULL)
                 sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
                                                      i * 2);
             else
                 sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
             if (sp == NULL) {
                 ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
-                if (s != NULL)
-                    OPENSSL_free(s);
                 goto err;
             }
             s = sp;
             slen = num + i * 2;
         }
         for (j = 0; j < i; j++, k += 2) {
             for (n = 0; n < 2; n++) {
                 m = bufp[k + n];
                 if ((m >= '0') && (m <= '9'))
                     m -= '0';
                 else if ((m >= 'a') && (m <= 'f'))
                     m = m - 'a' + 10;
                 else if ((m >= 'A') && (m <= 'F'))
                     m = m - 'A' + 10;
                 else {
                     ASN1err(ASN1_F_A2I_ASN1_INTEGER,
                             ASN1_R_NON_HEX_CHARACTERS);
                     goto err;
                 }
                 s[num + j] <<= 4;
                 s[num + j] |= m;
             }
         }
         num += i;
         if (again)
             bufsize = BIO_gets(bp, buf, size);
         else
             break;
     }
     bs->length = num;
     bs->data = s;
     ret = 1;
  err:
     if (0) {
  err_sl:
         ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
     }
+    if (ret != 1)
+        OPENSSL_free(s);
     return (ret);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_string.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_string.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/f_string.c	(revision 306191)
@@ -1,209 +1,209 @@
 /* crypto/asn1/f_string.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/asn1.h>
 
 int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
 {
     int i, n = 0;
     static const char *h = "0123456789ABCDEF";
     char buf[2];
 
     if (a == NULL)
         return (0);
 
     if (a->length == 0) {
         if (BIO_write(bp, "0", 1) != 1)
             goto err;
         n = 1;
     } else {
         for (i = 0; i < a->length; i++) {
             if ((i != 0) && (i % 35 == 0)) {
                 if (BIO_write(bp, "\\\n", 2) != 2)
                     goto err;
                 n += 2;
             }
             buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
             buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
             if (BIO_write(bp, buf, 2) != 2)
                 goto err;
             n += 2;
         }
     }
     return (n);
  err:
     return (-1);
 }
 
 int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
 {
     int ret = 0;
     int i, j, k, m, n, again, bufsize;
     unsigned char *s = NULL, *sp;
     unsigned char *bufp;
     int num = 0, slen = 0, first = 1;
 
     bufsize = BIO_gets(bp, buf, size);
     for (;;) {
         if (bufsize < 1) {
             if (first)
                 break;
             else
                 goto err_sl;
         }
         first = 0;
 
         i = bufsize;
         if (buf[i - 1] == '\n')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         if (buf[i - 1] == '\r')
             buf[--i] = '\0';
         if (i == 0)
             goto err_sl;
         again = (buf[i - 1] == '\\');
 
         for (j = i - 1; j > 0; j--) {
 #ifndef CHARSET_EBCDIC
             if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
                   ((buf[j] >= 'a') && (buf[j] <= 'f')) ||
                   ((buf[j] >= 'A') && (buf[j] <= 'F'))))
 #else
             /*
              * This #ifdef is not strictly necessary, since the characters
              * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
              * not the whole alphabet). Nevertheless, isxdigit() is faster.
              */
             if (!isxdigit(buf[j]))
 #endif
             {
                 i = j;
                 break;
             }
         }
         buf[i] = '\0';
         /*
          * We have now cleared all the crap off the end of the line
          */
         if (i < 2)
             goto err_sl;
 
         bufp = (unsigned char *)buf;
 
         k = 0;
         i -= again;
         if (i % 2 != 0) {
             ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
             goto err;
         }
         i /= 2;
         if (num + i > slen) {
             if (s == NULL)
                 sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
                                                      i * 2);
             else
                 sp = (unsigned char *)OPENSSL_realloc(s,
                                                       (unsigned int)num +
                                                       i * 2);
             if (sp == NULL) {
                 ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
-                if (s != NULL)
-                    OPENSSL_free(s);
                 goto err;
             }
             s = sp;
             slen = num + i * 2;
         }
         for (j = 0; j < i; j++, k += 2) {
             for (n = 0; n < 2; n++) {
                 m = bufp[k + n];
                 if ((m >= '0') && (m <= '9'))
                     m -= '0';
                 else if ((m >= 'a') && (m <= 'f'))
                     m = m - 'a' + 10;
                 else if ((m >= 'A') && (m <= 'F'))
                     m = m - 'A' + 10;
                 else {
                     ASN1err(ASN1_F_A2I_ASN1_STRING,
                             ASN1_R_NON_HEX_CHARACTERS);
                     goto err;
                 }
                 s[num + j] <<= 4;
                 s[num + j] |= m;
             }
         }
         num += i;
         if (again)
             bufsize = BIO_gets(bp, buf, size);
         else
             break;
     }
     bs->length = num;
     bs->data = s;
     ret = 1;
  err:
     if (0) {
  err_sl:
         ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
     }
+    if (ret != 1)
+        OPENSSL_free(s);
     return (ret);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbe.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbe.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbe.c	(revision 306191)
@@ -1,143 +1,143 @@
 /* p5_pbe.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 "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include <openssl/rand.h>
 
 /* PKCS#5 password based encryption structure */
 
 ASN1_SEQUENCE(PBEPARAM) = {
         ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
         ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
 } ASN1_SEQUENCE_END(PBEPARAM)
 
 IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
 
 /* Set an algorithm identifier for a PKCS#5 PBE algorithm */
 
 int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
                          const unsigned char *salt, int saltlen)
 {
     PBEPARAM *pbe = NULL;
     ASN1_STRING *pbe_str = NULL;
     unsigned char *sstr;
 
     pbe = PBEPARAM_new();
     if (!pbe) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     if (iter <= 0)
         iter = PKCS5_DEFAULT_ITER;
     if (!ASN1_INTEGER_set(pbe->iter, iter)) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     if (!saltlen)
         saltlen = PKCS5_SALT_LEN;
     if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     sstr = ASN1_STRING_data(pbe->salt);
     if (salt)
         memcpy(sstr, salt, saltlen);
-    else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
+    else if (RAND_bytes(sstr, saltlen) <= 0)
         goto err;
 
     if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
         ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     PBEPARAM_free(pbe);
     pbe = NULL;
 
     if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
         return 1;
 
  err:
     if (pbe != NULL)
         PBEPARAM_free(pbe);
     if (pbe_str != NULL)
         ASN1_STRING_free(pbe_str);
     return 0;
 }
 
 /* Return an algorithm identifier for a PKCS#5 PBE algorithm */
 
 X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
                           const unsigned char *salt, int saltlen)
 {
     X509_ALGOR *ret;
     ret = X509_ALGOR_new();
     if (!ret) {
         ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
 
     if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
         return ret;
 
     X509_ALGOR_free(ret);
     return NULL;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbev2.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbev2.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/p5_pbev2.c	(revision 306191)
@@ -1,280 +1,280 @@
 /* p5_pbev2.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 1999-2004.
  */
 /* ====================================================================
  * 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 "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include <openssl/rand.h>
 
 /* PKCS#5 v2.0 password based encryption structures */
 
 ASN1_SEQUENCE(PBE2PARAM) = {
         ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
         ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
 } ASN1_SEQUENCE_END(PBE2PARAM)
 
 IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
 
 ASN1_SEQUENCE(PBKDF2PARAM) = {
         ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
         ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
         ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
         ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
 } ASN1_SEQUENCE_END(PBKDF2PARAM)
 
 IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
 
 /*
  * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
  * this is horrible! Extended version to allow application supplied PRF NID
  * and IV.
  */
 
 X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                               unsigned char *salt, int saltlen,
                               unsigned char *aiv, int prf_nid)
 {
     X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
     int alg_nid, keylen;
     EVP_CIPHER_CTX ctx;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     PBE2PARAM *pbe2 = NULL;
     ASN1_OBJECT *obj;
 
     alg_nid = EVP_CIPHER_type(cipher);
     if (alg_nid == NID_undef) {
         ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
                 ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
         goto err;
     }
     obj = OBJ_nid2obj(alg_nid);
 
     if (!(pbe2 = PBE2PARAM_new()))
         goto merr;
 
     /* Setup the AlgorithmIdentifier for the encryption scheme */
     scheme = pbe2->encryption;
 
     scheme->algorithm = obj;
     if (!(scheme->parameter = ASN1_TYPE_new()))
         goto merr;
 
     /* Create random IV */
     if (EVP_CIPHER_iv_length(cipher)) {
         if (aiv)
             memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
-        else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+        else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
             goto err;
     }
 
     EVP_CIPHER_CTX_init(&ctx);
 
     /* Dummy cipherinit to just setup the IV, and PRF */
     if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
         goto err;
     if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
         ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
         EVP_CIPHER_CTX_cleanup(&ctx);
         goto err;
     }
     /*
      * If prf NID unspecified see if cipher has a preference. An error is OK
      * here: just means use default PRF.
      */
     if ((prf_nid == -1) &&
         EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
         ERR_clear_error();
         prf_nid = NID_hmacWithSHA1;
     }
     EVP_CIPHER_CTX_cleanup(&ctx);
 
     /* If its RC2 then we'd better setup the key length */
 
     if (alg_nid == NID_rc2_cbc)
         keylen = EVP_CIPHER_key_length(cipher);
     else
         keylen = -1;
 
     /* Setup keyfunc */
 
     X509_ALGOR_free(pbe2->keyfunc);
 
     pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
 
     if (!pbe2->keyfunc)
         goto merr;
 
     /* Now set up top level AlgorithmIdentifier */
 
     if (!(ret = X509_ALGOR_new()))
         goto merr;
     if (!(ret->parameter = ASN1_TYPE_new()))
         goto merr;
 
     ret->algorithm = OBJ_nid2obj(NID_pbes2);
 
     /* Encode PBE2PARAM into parameter */
 
     if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
                         &ret->parameter->value.sequence))
          goto merr;
     ret->parameter->type = V_ASN1_SEQUENCE;
 
     PBE2PARAM_free(pbe2);
     pbe2 = NULL;
 
     return ret;
 
  merr:
     ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
 
  err:
     PBE2PARAM_free(pbe2);
     /* Note 'scheme' is freed as part of pbe2 */
     X509_ALGOR_free(kalg);
     X509_ALGOR_free(ret);
 
     return NULL;
 
 }
 
 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                            unsigned char *salt, int saltlen)
 {
     return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
 }
 
 X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                              int prf_nid, int keylen)
 {
     X509_ALGOR *keyfunc = NULL;
     PBKDF2PARAM *kdf = NULL;
     ASN1_OCTET_STRING *osalt = NULL;
 
     if (!(kdf = PBKDF2PARAM_new()))
         goto merr;
     if (!(osalt = M_ASN1_OCTET_STRING_new()))
         goto merr;
 
     kdf->salt->value.octet_string = osalt;
     kdf->salt->type = V_ASN1_OCTET_STRING;
 
     if (!saltlen)
         saltlen = PKCS5_SALT_LEN;
     if (!(osalt->data = OPENSSL_malloc(saltlen)))
         goto merr;
 
     osalt->length = saltlen;
 
     if (salt)
         memcpy(osalt->data, salt, saltlen);
-    else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
+    else if (RAND_bytes(osalt->data, saltlen) <= 0)
         goto merr;
 
     if (iter <= 0)
         iter = PKCS5_DEFAULT_ITER;
 
     if (!ASN1_INTEGER_set(kdf->iter, iter))
         goto merr;
 
     /* If have a key len set it up */
 
     if (keylen > 0) {
         if (!(kdf->keylength = M_ASN1_INTEGER_new()))
             goto merr;
         if (!ASN1_INTEGER_set(kdf->keylength, keylen))
             goto merr;
     }
 
     /* prf can stay NULL if we are using hmacWithSHA1 */
     if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
         kdf->prf = X509_ALGOR_new();
         if (!kdf->prf)
             goto merr;
         X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
     }
 
     /* Finally setup the keyfunc structure */
 
     keyfunc = X509_ALGOR_new();
     if (!keyfunc)
         goto merr;
 
     keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
 
     /* Encode PBKDF2PARAM into parameter of pbe2 */
 
     if (!(keyfunc->parameter = ASN1_TYPE_new()))
         goto merr;
 
     if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
                         &keyfunc->parameter->value.sequence))
          goto merr;
     keyfunc->parameter->type = V_ASN1_SEQUENCE;
 
     PBKDF2PARAM_free(kdf);
     return keyfunc;
 
  merr:
     ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
     PBKDF2PARAM_free(kdf);
     X509_ALGOR_free(keyfunc);
     return NULL;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_enc.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_enc.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_enc.c	(revision 306191)
@@ -1,659 +1,667 @@
 /* tasn_enc.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2000.
  */
 /* ====================================================================
  * Copyright (c) 2000-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).
  *
  */
 
 #include <stddef.h>
 #include <string.h>
+#include <limits.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #include <openssl/objects.h>
 
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
                                  const ASN1_ITEM *it, int tag, int aclass);
 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
                             int skcontlen, const ASN1_ITEM *item,
                             int do_sort, int iclass);
 static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_TEMPLATE *tt, int tag, int aclass);
 static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
                                const ASN1_ITEM *it, int flags);
 
 /*
  * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use
  * indefinite length constructed encoding, where appropriate
  */
 
 int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out,
                        const ASN1_ITEM *it)
 {
     return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
 }
 
 int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
 {
     return asn1_item_flags_i2d(val, out, it, 0);
 }
 
 /*
  * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out'
  * points to a buffer to output the data to. The new i2d has one additional
  * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is
  * allocated and populated with the encoding.
  */
 
 static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
                                const ASN1_ITEM *it, int flags)
 {
     if (out && !*out) {
         unsigned char *p, *buf;
         int len;
         len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
         if (len <= 0)
             return len;
         buf = OPENSSL_malloc(len);
         if (!buf)
             return -1;
         p = buf;
         ASN1_item_ex_i2d(&val, &p, it, -1, flags);
         *out = buf;
         return len;
     }
 
     return ASN1_item_ex_i2d(&val, out, it, -1, flags);
 }
 
 /*
  * Encode an item, taking care of IMPLICIT tagging (if any). This function
  * performs the normal item handling: it can be used in external types.
  */
 
 int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                      const ASN1_ITEM *it, int tag, int aclass)
 {
     const ASN1_TEMPLATE *tt = NULL;
     unsigned char *p = NULL;
     int i, seqcontlen, seqlen, ndef = 1;
     const ASN1_COMPAT_FUNCS *cf;
     const ASN1_EXTERN_FUNCS *ef;
     const ASN1_AUX *aux = it->funcs;
     ASN1_aux_cb *asn1_cb = 0;
 
     if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
         return 0;
 
     if (aux && aux->asn1_cb)
         asn1_cb = aux->asn1_cb;
 
     switch (it->itype) {
 
     case ASN1_ITYPE_PRIMITIVE:
         if (it->templates)
             return asn1_template_ex_i2d(pval, out, it->templates,
                                         tag, aclass);
         return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
         break;
 
     case ASN1_ITYPE_MSTRING:
         return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
 
     case ASN1_ITYPE_CHOICE:
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
             return 0;
         i = asn1_get_choice_selector(pval, it);
         if ((i >= 0) && (i < it->tcount)) {
             ASN1_VALUE **pchval;
             const ASN1_TEMPLATE *chtt;
             chtt = it->templates + i;
             pchval = asn1_get_field_ptr(pval, chtt);
             return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
         }
         /* Fixme: error condition if selector out of range */
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
             return 0;
         break;
 
     case ASN1_ITYPE_EXTERN:
         /* If new style i2d it does all the work */
         ef = it->funcs;
         return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
 
     case ASN1_ITYPE_COMPAT:
         /* old style hackery... */
         cf = it->funcs;
         if (out)
             p = *out;
         i = cf->asn1_i2d(*pval, out);
         /*
          * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so
          * did the old code. Tags > 30 are very rare anyway.
          */
         if (out && (tag != -1))
             *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED);
         return i;
 
     case ASN1_ITYPE_NDEF_SEQUENCE:
         /* Use indefinite length constructed if requested */
         if (aclass & ASN1_TFLG_NDEF)
             ndef = 2;
         /* fall through */
 
     case ASN1_ITYPE_SEQUENCE:
         i = asn1_enc_restore(&seqcontlen, out, pval, it);
         /* An error occurred */
         if (i < 0)
             return 0;
         /* We have a valid cached encoding... */
         if (i > 0)
             return seqcontlen;
         /* Otherwise carry on */
         seqcontlen = 0;
         /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
         if (tag == -1) {
             tag = V_ASN1_SEQUENCE;
             /* Retain any other flags in aclass */
             aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
                 | V_ASN1_UNIVERSAL;
         }
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
             return 0;
         /* First work out sequence content length */
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             const ASN1_TEMPLATE *seqtt;
             ASN1_VALUE **pseqval;
+            int tmplen;
             seqtt = asn1_do_adb(pval, tt, 1);
             if (!seqtt)
                 return 0;
             pseqval = asn1_get_field_ptr(pval, seqtt);
-            /* FIXME: check for errors in enhanced version */
-            seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-                                               -1, aclass);
+            tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+            if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+                return -1;
+            seqcontlen += tmplen;
         }
 
         seqlen = ASN1_object_size(ndef, seqcontlen, tag);
-        if (!out)
+        if (!out || seqlen == -1)
             return seqlen;
         /* Output SEQUENCE header */
         ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
         for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
             const ASN1_TEMPLATE *seqtt;
             ASN1_VALUE **pseqval;
             seqtt = asn1_do_adb(pval, tt, 1);
             if (!seqtt)
                 return 0;
             pseqval = asn1_get_field_ptr(pval, seqtt);
             /* FIXME: check for errors in enhanced version */
             asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
         }
         if (ndef == 2)
             ASN1_put_eoc(out);
         if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
             return 0;
         return seqlen;
 
     default:
         return 0;
 
     }
     return 0;
 }
 
 int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
                       const ASN1_TEMPLATE *tt)
 {
     return asn1_template_ex_i2d(pval, out, tt, -1, 0);
 }
 
 static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
                                 const ASN1_TEMPLATE *tt, int tag, int iclass)
 {
     int i, ret, flags, ttag, tclass, ndef;
     flags = tt->flags;
     /*
      * Work out tag and class to use: tagging may come either from the
      * template or the arguments, not both because this would create
      * ambiguity. Additionally the iclass argument may contain some
      * additional flags which should be noted and passed down to other
      * levels.
      */
     if (flags & ASN1_TFLG_TAG_MASK) {
         /* Error if argument and template tagging */
         if (tag != -1)
             /* FIXME: error code here */
             return -1;
         /* Get tagging from template */
         ttag = tt->tag;
         tclass = flags & ASN1_TFLG_TAG_CLASS;
     } else if (tag != -1) {
         /* No template tagging, get from arguments */
         ttag = tag;
         tclass = iclass & ASN1_TFLG_TAG_CLASS;
     } else {
         ttag = -1;
         tclass = 0;
     }
     /*
      * Remove any class mask from iflag.
      */
     iclass &= ~ASN1_TFLG_TAG_CLASS;
 
     /*
      * At this point 'ttag' contains the outer tag to use, 'tclass' is the
      * class and iclass is any flags passed to this function.
      */
 
     /* if template and arguments require ndef, use it */
     if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
         ndef = 2;
     else
         ndef = 1;
 
     if (flags & ASN1_TFLG_SK_MASK) {
         /* SET OF, SEQUENCE OF */
         STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
         int isset, sktag, skaclass;
         int skcontlen, sklen;
         ASN1_VALUE *skitem;
 
         if (!*pval)
             return 0;
 
         if (flags & ASN1_TFLG_SET_OF) {
             isset = 1;
             /* 2 means we reorder */
             if (flags & ASN1_TFLG_SEQUENCE_OF)
                 isset = 2;
         } else
             isset = 0;
 
         /*
          * Work out inner tag value: if EXPLICIT or no tagging use underlying
          * type.
          */
         if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
             sktag = ttag;
             skaclass = tclass;
         } else {
             skaclass = V_ASN1_UNIVERSAL;
             if (isset)
                 sktag = V_ASN1_SET;
             else
                 sktag = V_ASN1_SEQUENCE;
         }
 
         /* Determine total length of items */
         skcontlen = 0;
         for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+            int tmplen;
             skitem = sk_ASN1_VALUE_value(sk, i);
-            skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
-                                          ASN1_ITEM_ptr(tt->item),
-                                          -1, iclass);
+            tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+                                      -1, iclass);
+            if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+                return -1;
+            skcontlen += tmplen;
         }
         sklen = ASN1_object_size(ndef, skcontlen, sktag);
+        if (sklen == -1)
+            return -1;
         /* If EXPLICIT need length of surrounding tag */
         if (flags & ASN1_TFLG_EXPTAG)
             ret = ASN1_object_size(ndef, sklen, ttag);
         else
             ret = sklen;
 
-        if (!out)
+        if (!out || ret == -1)
             return ret;
 
         /* Now encode this lot... */
         /* EXPLICIT tag */
         if (flags & ASN1_TFLG_EXPTAG)
             ASN1_put_object(out, ndef, sklen, ttag, tclass);
         /* SET or SEQUENCE and IMPLICIT tag */
         ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
         /* And the stuff itself */
         asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item),
                          isset, iclass);
         if (ndef == 2) {
             ASN1_put_eoc(out);
             if (flags & ASN1_TFLG_EXPTAG)
                 ASN1_put_eoc(out);
         }
 
         return ret;
     }
 
     if (flags & ASN1_TFLG_EXPTAG) {
         /* EXPLICIT tagging */
         /* Find length of tagged item */
         i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass);
         if (!i)
             return 0;
         /* Find length of EXPLICIT tag */
         ret = ASN1_object_size(ndef, i, ttag);
-        if (out) {
+        if (out && ret != -1) {
             /* Output tag and item */
             ASN1_put_object(out, ndef, i, ttag, tclass);
             ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
             if (ndef == 2)
                 ASN1_put_eoc(out);
         }
         return ret;
     }
 
     /* Either normal or IMPLICIT tagging: combine class and flags */
     return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item),
                             ttag, tclass | iclass);
 
 }
 
 /* Temporary structure used to hold DER encoding of items for SET OF */
 
 typedef struct {
     unsigned char *data;
     int length;
     ASN1_VALUE *field;
 } DER_ENC;
 
 static int der_cmp(const void *a, const void *b)
 {
     const DER_ENC *d1 = a, *d2 = b;
     int cmplen, i;
     cmplen = (d1->length < d2->length) ? d1->length : d2->length;
     i = memcmp(d1->data, d2->data, cmplen);
     if (i)
         return i;
     return d1->length - d2->length;
 }
 
 /* Output the content octets of SET OF or SEQUENCE OF */
 
 static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
                             int skcontlen, const ASN1_ITEM *item,
                             int do_sort, int iclass)
 {
     int i;
     ASN1_VALUE *skitem;
     unsigned char *tmpdat = NULL, *p = NULL;
     DER_ENC *derlst = NULL, *tder;
     if (do_sort) {
         /* Don't need to sort less than 2 items */
         if (sk_ASN1_VALUE_num(sk) < 2)
             do_sort = 0;
         else {
             derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk)
                                     * sizeof(*derlst));
             if (!derlst)
                 return 0;
             tmpdat = OPENSSL_malloc(skcontlen);
             if (!tmpdat) {
                 OPENSSL_free(derlst);
                 return 0;
             }
         }
     }
     /* If not sorting just output each item */
     if (!do_sort) {
         for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
             skitem = sk_ASN1_VALUE_value(sk, i);
             ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
         }
         return 1;
     }
     p = tmpdat;
 
     /* Doing sort: build up a list of each member's DER encoding */
     for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
         skitem = sk_ASN1_VALUE_value(sk, i);
         tder->data = p;
         tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
         tder->field = skitem;
     }
 
     /* Now sort them */
     qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
     /* Output sorted DER encoding */
     p = *out;
     for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
         memcpy(p, tder->data, tder->length);
         p += tder->length;
     }
     *out = p;
     /* If do_sort is 2 then reorder the STACK */
     if (do_sort == 2) {
         for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
             (void)sk_ASN1_VALUE_set(sk, i, tder->field);
     }
     OPENSSL_free(derlst);
     OPENSSL_free(tmpdat);
     return 1;
 }
 
 static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
                                  const ASN1_ITEM *it, int tag, int aclass)
 {
     int len;
     int utype;
     int usetag;
     int ndef = 0;
 
     utype = it->utype;
 
     /*
      * Get length of content octets and maybe find out the underlying type.
      */
 
     len = asn1_ex_i2c(pval, NULL, &utype, it);
 
     /*
      * If SEQUENCE, SET or OTHER then header is included in pseudo content
      * octets so don't include tag+length. We need to check here because the
      * call to asn1_ex_i2c() could change utype.
      */
     if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
         (utype == V_ASN1_OTHER))
         usetag = 0;
     else
         usetag = 1;
 
     /* -1 means omit type */
 
     if (len == -1)
         return 0;
 
     /* -2 return is special meaning use ndef */
     if (len == -2) {
         ndef = 2;
         len = 0;
     }
 
     /* If not implicitly tagged get tag from underlying type */
     if (tag == -1)
         tag = utype;
 
     /* Output tag+length followed by content octets */
     if (out) {
         if (usetag)
             ASN1_put_object(out, ndef, len, tag, aclass);
         asn1_ex_i2c(pval, *out, &utype, it);
         if (ndef)
             ASN1_put_eoc(out);
         else
             *out += len;
     }
 
     if (usetag)
         return ASN1_object_size(ndef, len, tag);
     return len;
 }
 
 /* Produce content octets from a structure */
 
 int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
                 const ASN1_ITEM *it)
 {
     ASN1_BOOLEAN *tbool = NULL;
     ASN1_STRING *strtmp;
     ASN1_OBJECT *otmp;
     int utype;
     const unsigned char *cont;
     unsigned char c;
     int len;
     const ASN1_PRIMITIVE_FUNCS *pf;
     pf = it->funcs;
     if (pf && pf->prim_i2c)
         return pf->prim_i2c(pval, cout, putype, it);
 
     /* Should type be omitted? */
     if ((it->itype != ASN1_ITYPE_PRIMITIVE)
         || (it->utype != V_ASN1_BOOLEAN)) {
         if (!*pval)
             return -1;
     }
 
     if (it->itype == ASN1_ITYPE_MSTRING) {
         /* If MSTRING type set the underlying type */
         strtmp = (ASN1_STRING *)*pval;
         utype = strtmp->type;
         *putype = utype;
     } else if (it->utype == V_ASN1_ANY) {
         /* If ANY set type and pointer to value */
         ASN1_TYPE *typ;
         typ = (ASN1_TYPE *)*pval;
         utype = typ->type;
         *putype = utype;
         pval = &typ->value.asn1_value;
     } else
         utype = *putype;
 
     switch (utype) {
     case V_ASN1_OBJECT:
         otmp = (ASN1_OBJECT *)*pval;
         cont = otmp->data;
         len = otmp->length;
         break;
 
     case V_ASN1_NULL:
         cont = NULL;
         len = 0;
         break;
 
     case V_ASN1_BOOLEAN:
         tbool = (ASN1_BOOLEAN *)pval;
         if (*tbool == -1)
             return -1;
         if (it->utype != V_ASN1_ANY) {
             /*
              * Default handling if value == size field then omit
              */
             if (*tbool && (it->size > 0))
                 return -1;
             if (!*tbool && !it->size)
                 return -1;
         }
         c = (unsigned char)*tbool;
         cont = &c;
         len = 1;
         break;
 
     case V_ASN1_BIT_STRING:
         return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
                                    cout ? &cout : NULL);
         break;
 
     case V_ASN1_INTEGER:
     case V_ASN1_ENUMERATED:
         /*
          * These are all have the same content format as ASN1_INTEGER
          */
         return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL);
         break;
 
     case V_ASN1_OCTET_STRING:
     case V_ASN1_NUMERICSTRING:
     case V_ASN1_PRINTABLESTRING:
     case V_ASN1_T61STRING:
     case V_ASN1_VIDEOTEXSTRING:
     case V_ASN1_IA5STRING:
     case V_ASN1_UTCTIME:
     case V_ASN1_GENERALIZEDTIME:
     case V_ASN1_GRAPHICSTRING:
     case V_ASN1_VISIBLESTRING:
     case V_ASN1_GENERALSTRING:
     case V_ASN1_UNIVERSALSTRING:
     case V_ASN1_BMPSTRING:
     case V_ASN1_UTF8STRING:
     case V_ASN1_SEQUENCE:
     case V_ASN1_SET:
     default:
         /* All based on ASN1_STRING and handled the same */
         strtmp = (ASN1_STRING *)*pval;
         /* Special handling for NDEF */
         if ((it->size == ASN1_TFLG_NDEF)
             && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
             if (cout) {
                 strtmp->data = cout;
                 strtmp->length = 0;
             }
             /* Special return code */
             return -2;
         }
         cont = strtmp->data;
         len = strtmp->length;
 
         break;
 
     }
     if (cout && len)
         memcpy(cout, cont, len);
     return len;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_prn.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_prn.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/tasn_prn.c	(revision 306191)
@@ -1,585 +1,587 @@
 /* tasn_prn.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2000.
  */
 /* ====================================================================
  * Copyright (c) 2000,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
  *    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 <stddef.h>
 #include "cryptlib.h"
 #include <openssl/asn1.h>
 #include <openssl/asn1t.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
 #include <openssl/err.h>
 #include <openssl/x509v3.h>
 #include "asn1_locl.h"
 
 /*
  * Print routines.
  */
 
 /* ASN1_PCTX routines */
 
 ASN1_PCTX default_pctx = {
     ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
     0,                          /* nm_flags */
     0,                          /* cert_flags */
     0,                          /* oid_flags */
     0                           /* str_flags */
 };
 
 ASN1_PCTX *ASN1_PCTX_new(void)
 {
     ASN1_PCTX *ret;
     ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
     if (ret == NULL) {
         ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
     ret->flags = 0;
     ret->nm_flags = 0;
     ret->cert_flags = 0;
     ret->oid_flags = 0;
     ret->str_flags = 0;
     return ret;
 }
 
 void ASN1_PCTX_free(ASN1_PCTX *p)
 {
     OPENSSL_free(p);
 }
 
 unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
 {
     return p->flags;
 }
 
 void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
 {
     p->flags = flags;
 }
 
 unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
 {
     return p->nm_flags;
 }
 
 void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
 {
     p->nm_flags = flags;
 }
 
 unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
 {
     return p->cert_flags;
 }
 
 void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
 {
     p->cert_flags = flags;
 }
 
 unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
 {
     return p->oid_flags;
 }
 
 void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
 {
     p->oid_flags = flags;
 }
 
 unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
 {
     return p->str_flags;
 }
 
 void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
 {
     p->str_flags = flags;
 }
 
 /* Main print routines */
 
 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                                const ASN1_ITEM *it,
                                const char *fname, const char *sname,
                                int nohdr, const ASN1_PCTX *pctx);
 
 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
 
 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
                                 const ASN1_ITEM *it, int indent,
                                 const char *fname, const char *sname,
                                 const ASN1_PCTX *pctx);
 
 static int asn1_print_fsname(BIO *out, int indent,
                              const char *fname, const char *sname,
                              const ASN1_PCTX *pctx);
 
 int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
                     const ASN1_ITEM *it, const ASN1_PCTX *pctx)
 {
     const char *sname;
     if (pctx == NULL)
         pctx = &default_pctx;
     if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
         sname = NULL;
     else
         sname = it->sname;
     return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
 }
 
 static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                                const ASN1_ITEM *it,
                                const char *fname, const char *sname,
                                int nohdr, const ASN1_PCTX *pctx)
 {
     const ASN1_TEMPLATE *tt;
     const ASN1_EXTERN_FUNCS *ef;
     ASN1_VALUE **tmpfld;
     const ASN1_AUX *aux = it->funcs;
     ASN1_aux_cb *asn1_cb;
     ASN1_PRINT_ARG parg;
     int i;
     if (aux && aux->asn1_cb) {
         parg.out = out;
         parg.indent = indent;
         parg.pctx = pctx;
         asn1_cb = aux->asn1_cb;
     } else
         asn1_cb = 0;
 
     if (*fld == NULL) {
         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
             if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
                 return 0;
             if (BIO_puts(out, "<ABSENT>\n") <= 0)
                 return 0;
         }
         return 1;
     }
 
     switch (it->itype) {
     case ASN1_ITYPE_PRIMITIVE:
         if (it->templates) {
             if (!asn1_template_print_ctx(out, fld, indent,
                                          it->templates, pctx))
                 return 0;
             break;
         }
         /* fall thru */
     case ASN1_ITYPE_MSTRING:
         if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
             return 0;
         break;
 
     case ASN1_ITYPE_EXTERN:
         if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
             return 0;
         /* Use new style print routine if possible */
         ef = it->funcs;
         if (ef && ef->asn1_ex_print) {
             i = ef->asn1_ex_print(out, fld, indent, "", pctx);
             if (!i)
                 return 0;
             if ((i == 2) && (BIO_puts(out, "\n") <= 0))
                 return 0;
             return 1;
         } else if (sname &&
                    BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
             return 0;
         break;
 
     case ASN1_ITYPE_CHOICE:
 #if 0
         if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
             return 0;
 #endif
         /* CHOICE type, get selector */
         i = asn1_get_choice_selector(fld, it);
         /* This should never happen... */
         if ((i < 0) || (i >= it->tcount)) {
             if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
                 return 0;
             return 1;
         }
         tt = it->templates + i;
         tmpfld = asn1_get_field_ptr(fld, tt);
         if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
             return 0;
         break;
 
     case ASN1_ITYPE_SEQUENCE:
     case ASN1_ITYPE_NDEF_SEQUENCE:
         if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
             return 0;
         if (fname || sname) {
             if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
                 if (BIO_puts(out, " {\n") <= 0)
                     return 0;
             } else {
                 if (BIO_puts(out, "\n") <= 0)
                     return 0;
             }
         }
 
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
             if (i == 0)
                 return 0;
             if (i == 2)
                 return 1;
         }
 
         /* Print each field entry */
         for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
             const ASN1_TEMPLATE *seqtt;
             seqtt = asn1_do_adb(fld, tt, 1);
             if (!seqtt)
                 return 0;
             tmpfld = asn1_get_field_ptr(fld, seqtt);
             if (!asn1_template_print_ctx(out, tmpfld,
                                          indent + 2, seqtt, pctx))
                 return 0;
         }
         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
             if (BIO_printf(out, "%*s}\n", indent, "") < 0)
                 return 0;
         }
 
         if (asn1_cb) {
             i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
             if (i == 0)
                 return 0;
         }
         break;
 
     default:
         BIO_printf(out, "Unprocessed type %d\n", it->itype);
         return 0;
     }
 
     return 1;
 }
 
 int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
                             const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
 {
     int i, flags;
     const char *sname, *fname;
     flags = tt->flags;
     if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
         sname = ASN1_ITEM_ptr(tt->item)->sname;
     else
         sname = NULL;
     if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
         fname = NULL;
     else
         fname = tt->field_name;
     if (flags & ASN1_TFLG_SK_MASK) {
         char *tname;
         ASN1_VALUE *skitem;
         STACK_OF(ASN1_VALUE) *stack;
 
         /* SET OF, SEQUENCE OF */
         if (fname) {
             if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
                 if (flags & ASN1_TFLG_SET_OF)
                     tname = "SET";
                 else
                     tname = "SEQUENCE";
                 if (BIO_printf(out, "%*s%s OF %s {\n",
                                indent, "", tname, tt->field_name) <= 0)
                     return 0;
             } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
                 return 0;
         }
         stack = (STACK_OF(ASN1_VALUE) *)*fld;
         for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
             if ((i > 0) && (BIO_puts(out, "\n") <= 0))
                 return 0;
 
             skitem = sk_ASN1_VALUE_value(stack, i);
             if (!asn1_item_print_ctx(out, &skitem, indent + 2,
                                      ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
                                      pctx))
                 return 0;
         }
         if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
             return 0;
         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
             if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
                 return 0;
         }
         return 1;
     }
     return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
                                fname, sname, 0, pctx);
 }
 
 static int asn1_print_fsname(BIO *out, int indent,
                              const char *fname, const char *sname,
                              const ASN1_PCTX *pctx)
 {
     static char spaces[] = "                    ";
     const int nspaces = sizeof(spaces) - 1;
 
 #if 0
     if (!sname && !fname)
         return 1;
 #endif
 
     while (indent > nspaces) {
         if (BIO_write(out, spaces, nspaces) != nspaces)
             return 0;
         indent -= nspaces;
     }
     if (BIO_write(out, spaces, indent) != indent)
         return 0;
     if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
         sname = NULL;
     if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
         fname = NULL;
     if (!sname && !fname)
         return 1;
     if (fname) {
         if (BIO_puts(out, fname) <= 0)
             return 0;
     }
     if (sname) {
         if (fname) {
             if (BIO_printf(out, " (%s)", sname) <= 0)
                 return 0;
         } else {
             if (BIO_puts(out, sname) <= 0)
                 return 0;
         }
     }
     if (BIO_write(out, ": ", 2) != 2)
         return 0;
     return 1;
 }
 
 static int asn1_print_boolean_ctx(BIO *out, int boolval,
                                   const ASN1_PCTX *pctx)
 {
     const char *str;
     switch (boolval) {
     case -1:
         str = "BOOL ABSENT";
         break;
 
     case 0:
         str = "FALSE";
         break;
 
     default:
         str = "TRUE";
         break;
 
     }
 
     if (BIO_puts(out, str) <= 0)
         return 0;
     return 1;
 
 }
 
 static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
                                   const ASN1_PCTX *pctx)
 {
     char *s;
     int ret = 1;
     s = i2s_ASN1_INTEGER(NULL, str);
+    if (s == NULL)
+        return 0;
     if (BIO_puts(out, s) <= 0)
         ret = 0;
     OPENSSL_free(s);
     return ret;
 }
 
 static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
                               const ASN1_PCTX *pctx)
 {
     char objbuf[80];
     const char *ln;
     ln = OBJ_nid2ln(OBJ_obj2nid(oid));
     if (!ln)
         ln = "";
     OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
     if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
         return 0;
     return 1;
 }
 
 static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
                                    const ASN1_PCTX *pctx)
 {
     if (str->type == V_ASN1_BIT_STRING) {
         if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
             return 0;
     } else if (BIO_puts(out, "\n") <= 0)
         return 0;
     if ((str->length > 0)
         && BIO_dump_indent(out, (char *)str->data, str->length,
                            indent + 2) <= 0)
         return 0;
     return 1;
 }
 
 static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
                                 const ASN1_ITEM *it, int indent,
                                 const char *fname, const char *sname,
                                 const ASN1_PCTX *pctx)
 {
     long utype;
     ASN1_STRING *str;
     int ret = 1, needlf = 1;
     const char *pname;
     const ASN1_PRIMITIVE_FUNCS *pf;
     pf = it->funcs;
     if (!asn1_print_fsname(out, indent, fname, sname, pctx))
         return 0;
     if (pf && pf->prim_print)
         return pf->prim_print(out, fld, it, indent, pctx);
     str = (ASN1_STRING *)*fld;
     if (it->itype == ASN1_ITYPE_MSTRING)
         utype = str->type & ~V_ASN1_NEG;
     else
         utype = it->utype;
     if (utype == V_ASN1_ANY) {
         ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
         utype = atype->type;
         fld = &atype->value.asn1_value;
         str = (ASN1_STRING *)*fld;
         if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
             pname = NULL;
         else
             pname = ASN1_tag2str(utype);
     } else {
         if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
             pname = ASN1_tag2str(utype);
         else
             pname = NULL;
     }
 
     if (utype == V_ASN1_NULL) {
         if (BIO_puts(out, "NULL\n") <= 0)
             return 0;
         return 1;
     }
 
     if (pname) {
         if (BIO_puts(out, pname) <= 0)
             return 0;
         if (BIO_puts(out, ":") <= 0)
             return 0;
     }
 
     switch (utype) {
     case V_ASN1_BOOLEAN:
         {
             int boolval = *(int *)fld;
             if (boolval == -1)
                 boolval = it->size;
             ret = asn1_print_boolean_ctx(out, boolval, pctx);
         }
         break;
 
     case V_ASN1_INTEGER:
     case V_ASN1_ENUMERATED:
         ret = asn1_print_integer_ctx(out, str, pctx);
         break;
 
     case V_ASN1_UTCTIME:
         ret = ASN1_UTCTIME_print(out, str);
         break;
 
     case V_ASN1_GENERALIZEDTIME:
         ret = ASN1_GENERALIZEDTIME_print(out, str);
         break;
 
     case V_ASN1_OBJECT:
         ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
         break;
 
     case V_ASN1_OCTET_STRING:
     case V_ASN1_BIT_STRING:
         ret = asn1_print_obstring_ctx(out, str, indent, pctx);
         needlf = 0;
         break;
 
     case V_ASN1_SEQUENCE:
     case V_ASN1_SET:
     case V_ASN1_OTHER:
         if (BIO_puts(out, "\n") <= 0)
             return 0;
         if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
             ret = 0;
         needlf = 0;
         break;
 
     default:
         ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
 
     }
     if (!ret)
         return 0;
     if (needlf && BIO_puts(out, "\n") <= 0)
         return 0;
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/asn1/x_name.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/asn1/x_name.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/asn1/x_name.c	(revision 306191)
@@ -1,538 +1,536 @@
 /* crypto/asn1/x_name.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.]
  */
 
 #include <stdio.h>
 #include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/x509.h>
 #include "asn1_locl.h"
 
 typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
 DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
 
 /*
  * Maximum length of X509_NAME: much larger than anything we should
  * ever see in practice.
  */
 
 #define X509_NAME_MAX (1024 * 1024)
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const unsigned char **in, long len,
                             const ASN1_ITEM *it,
                             int tag, int aclass, char opt, ASN1_TLC *ctx);
 
 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
                             const ASN1_ITEM *it, int tag, int aclass);
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
 static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
 
 static int x509_name_encode(X509_NAME *a);
 static int x509_name_canon(X509_NAME *a);
 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
 static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
                           unsigned char **in);
 
 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
                               int indent,
                               const char *fname, const ASN1_PCTX *pctx);
 
 ASN1_SEQUENCE(X509_NAME_ENTRY) = {
         ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
         ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
 } ASN1_SEQUENCE_END(X509_NAME_ENTRY)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
 
 /*
  * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
  * declare two template wrappers for this
  */
 
 ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
 ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
 
 ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
         ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
 ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
 
 /*
  * Normally that's where it would end: we'd have two nested STACK structures
  * representing the ASN1. Unfortunately X509_NAME uses a completely different
  * form and caches encodings so we have to process the internal form and
  * convert to the external form.
  */
 
 const ASN1_EXTERN_FUNCS x509_name_ff = {
     NULL,
     x509_name_ex_new,
     x509_name_ex_free,
     0,                          /* Default clear behaviour is OK */
     x509_name_ex_d2i,
     x509_name_ex_i2d,
     x509_name_ex_print
 };
 
 IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
 
 IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
 
 static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
 {
     X509_NAME *ret = NULL;
     ret = OPENSSL_malloc(sizeof(X509_NAME));
     if (!ret)
         goto memerr;
     if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
         goto memerr;
     if ((ret->bytes = BUF_MEM_new()) == NULL)
         goto memerr;
     ret->canon_enc = NULL;
     ret->canon_enclen = 0;
     ret->modified = 1;
     *val = (ASN1_VALUE *)ret;
     return 1;
 
  memerr:
     ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
     if (ret) {
         if (ret->entries)
             sk_X509_NAME_ENTRY_free(ret->entries);
         OPENSSL_free(ret);
     }
     return 0;
 }
 
 static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
 {
     X509_NAME *a;
     if (!pval || !*pval)
         return;
     a = (X509_NAME *)*pval;
 
     BUF_MEM_free(a->bytes);
     sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
     if (a->canon_enc)
         OPENSSL_free(a->canon_enc);
     OPENSSL_free(a);
     *pval = NULL;
 }
 
 static int x509_name_ex_d2i(ASN1_VALUE **val,
                             const unsigned char **in, long len,
                             const ASN1_ITEM *it, int tag, int aclass,
                             char opt, ASN1_TLC *ctx)
 {
     const unsigned char *p = *in, *q;
     union {
         STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
         ASN1_VALUE *a;
     } intname = {
         NULL
     };
     union {
         X509_NAME *x;
         ASN1_VALUE *a;
     } nm = {
         NULL
     };
     int i, j, ret;
     STACK_OF(X509_NAME_ENTRY) *entries;
     X509_NAME_ENTRY *entry;
-    if (len > X509_NAME_MAX) {
-        ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG);
-        return 0;
-    }
+    if (len > X509_NAME_MAX)
+        len = X509_NAME_MAX;
     q = p;
 
     /* Get internal representation of Name */
     ret = ASN1_item_ex_d2i(&intname.a,
                            &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
                            tag, aclass, opt, ctx);
 
     if (ret <= 0)
         return ret;
 
     if (*val)
         x509_name_ex_free(val, NULL);
     if (!x509_name_ex_new(&nm.a, NULL))
         goto err;
     /* We've decoded it: now cache encoding */
     if (!BUF_MEM_grow(nm.x->bytes, p - q))
         goto err;
     memcpy(nm.x->bytes->data, q, p - q);
 
     /* Convert internal representation to X509_NAME structure */
     for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
         entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
         for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
             entry = sk_X509_NAME_ENTRY_value(entries, j);
             entry->set = i;
             if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
                 goto err;
         }
         sk_X509_NAME_ENTRY_free(entries);
     }
     sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
     ret = x509_name_canon(nm.x);
     if (!ret)
         goto err;
     nm.x->modified = 0;
     *val = nm.a;
     *in = p;
     return ret;
  err:
     if (nm.x != NULL)
         X509_NAME_free(nm.x);
     ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
     return 0;
 }
 
 static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
                             const ASN1_ITEM *it, int tag, int aclass)
 {
     int ret;
     X509_NAME *a = (X509_NAME *)*val;
     if (a->modified) {
         ret = x509_name_encode(a);
         if (ret < 0)
             return ret;
         ret = x509_name_canon(a);
         if (ret < 0)
             return ret;
     }
     ret = a->bytes->length;
     if (out != NULL) {
         memcpy(*out, a->bytes->data, ret);
         *out += ret;
     }
     return ret;
 }
 
 static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
 {
     sk_X509_NAME_ENTRY_free(ne);
 }
 
 static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
 {
     sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
 }
 
 static int x509_name_encode(X509_NAME *a)
 {
     union {
         STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
         ASN1_VALUE *a;
     } intname = {
         NULL
     };
     int len;
     unsigned char *p;
     STACK_OF(X509_NAME_ENTRY) *entries = NULL;
     X509_NAME_ENTRY *entry;
     int i, set = -1;
     intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
     if (!intname.s)
         goto memerr;
     for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
         entry = sk_X509_NAME_ENTRY_value(a->entries, i);
         if (entry->set != set) {
             entries = sk_X509_NAME_ENTRY_new_null();
             if (!entries)
                 goto memerr;
             if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
                 goto memerr;
             set = entry->set;
         }
         if (!sk_X509_NAME_ENTRY_push(entries, entry))
             goto memerr;
     }
     len = ASN1_item_ex_i2d(&intname.a, NULL,
                            ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
     if (!BUF_MEM_grow(a->bytes, len))
         goto memerr;
     p = (unsigned char *)a->bytes->data;
     ASN1_item_ex_i2d(&intname.a,
                      &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
     sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
                                          local_sk_X509_NAME_ENTRY_free);
     a->modified = 0;
     return len;
  memerr:
     sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
                                          local_sk_X509_NAME_ENTRY_free);
     ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
     return -1;
 }
 
 static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
                               int indent,
                               const char *fname, const ASN1_PCTX *pctx)
 {
     if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
                            indent, pctx->nm_flags) <= 0)
         return 0;
     return 2;
 }
 
 /*
  * This function generates the canonical encoding of the Name structure. In
  * it all strings are converted to UTF8, leading, trailing and multiple
  * spaces collapsed, converted to lower case and the leading SEQUENCE header
  * removed. In future we could also normalize the UTF8 too. By doing this
  * comparison of Name structures can be rapidly perfomed by just using
  * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
  * constraints of type dirName can also be checked with a simple memcmp().
  */
 
 static int x509_name_canon(X509_NAME *a)
 {
     unsigned char *p;
     STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
     STACK_OF(X509_NAME_ENTRY) *entries = NULL;
     X509_NAME_ENTRY *entry, *tmpentry = NULL;
     int i, set = -1, ret = 0;
 
     if (a->canon_enc) {
         OPENSSL_free(a->canon_enc);
         a->canon_enc = NULL;
     }
     /* Special case: empty X509_NAME => null encoding */
     if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
         a->canon_enclen = 0;
         return 1;
     }
     intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
     if (!intname)
         goto err;
     for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
         entry = sk_X509_NAME_ENTRY_value(a->entries, i);
         if (entry->set != set) {
             entries = sk_X509_NAME_ENTRY_new_null();
             if (!entries)
                 goto err;
             if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
                 goto err;
             set = entry->set;
         }
         tmpentry = X509_NAME_ENTRY_new();
         if (!tmpentry)
             goto err;
         tmpentry->object = OBJ_dup(entry->object);
         if (!asn1_string_canon(tmpentry->value, entry->value))
             goto err;
         if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
             goto err;
         tmpentry = NULL;
     }
 
     /* Finally generate encoding */
 
     a->canon_enclen = i2d_name_canon(intname, NULL);
 
     p = OPENSSL_malloc(a->canon_enclen);
 
     if (!p)
         goto err;
 
     a->canon_enc = p;
 
     i2d_name_canon(intname, &p);
 
     ret = 1;
 
  err:
 
     if (tmpentry)
         X509_NAME_ENTRY_free(tmpentry);
     if (intname)
         sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
                                              local_sk_X509_NAME_ENTRY_pop_free);
     return ret;
 }
 
 /* Bitmap of all the types of string that will be canonicalized. */
 
 #define ASN1_MASK_CANON \
         (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
         | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
         | B_ASN1_VISIBLESTRING)
 
 static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
 {
     unsigned char *to, *from;
     int len, i;
 
     /* If type not in bitmask just copy string across */
     if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
         if (!ASN1_STRING_copy(out, in))
             return 0;
         return 1;
     }
 
     out->type = V_ASN1_UTF8STRING;
     out->length = ASN1_STRING_to_UTF8(&out->data, in);
     if (out->length == -1)
         return 0;
 
     to = out->data;
     from = to;
 
     len = out->length;
 
     /*
      * Convert string in place to canonical form. Ultimately we may need to
      * handle a wider range of characters but for now ignore anything with
      * MSB set and rely on the isspace() and tolower() functions.
      */
 
     /* Ignore leading spaces */
     while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
         from++;
         len--;
     }
 
     to = from + len - 1;
 
     /* Ignore trailing spaces */
     while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
         to--;
         len--;
     }
 
     to = out->data;
 
     i = 0;
     while (i < len) {
         /* If MSB set just copy across */
         if (*from & 0x80) {
             *to++ = *from++;
             i++;
         }
         /* Collapse multiple spaces */
         else if (isspace(*from)) {
             /* Copy one space across */
             *to++ = ' ';
             /*
              * Ignore subsequent spaces. Note: don't need to check len here
              * because we know the last character is a non-space so we can't
              * overflow.
              */
             do {
                 from++;
                 i++;
             }
             while (!(*from & 0x80) && isspace(*from));
         } else {
             *to++ = tolower(*from);
             from++;
             i++;
         }
     }
 
     out->length = to - out->data;
 
     return 1;
 
 }
 
 static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
                           unsigned char **in)
 {
     int i, len, ltmp;
     ASN1_VALUE *v;
     STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
 
     len = 0;
     for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
         v = sk_ASN1_VALUE_value(intname, i);
         ltmp = ASN1_item_ex_i2d(&v, in,
                                 ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
         if (ltmp < 0)
             return ltmp;
         len += ltmp;
     }
     return len;
 }
 
 int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
 {
     X509_NAME *in;
 
     if (!xn || !name)
         return (0);
 
     if (*xn != name) {
         in = X509_NAME_dup(name);
         if (in != NULL) {
             X509_NAME_free(*xn);
             *xn = in;
         }
     }
     return (*xn != NULL);
 }
 
 IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
 
 IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
Index: vendor-crypto/openssl/dist-1.0.1/crypto/bio/bf_nbio.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/bio/bf_nbio.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/bio/bf_nbio.c	(revision 306191)
@@ -1,253 +1,253 @@
 /* crypto/bio/bf_nbio.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.]
  */
 
 #include <stdio.h>
 #include <errno.h>
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include <openssl/bio.h>
 
 /*
  * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest
  */
 
 static int nbiof_write(BIO *h, const char *buf, int num);
 static int nbiof_read(BIO *h, char *buf, int size);
 static int nbiof_puts(BIO *h, const char *str);
 static int nbiof_gets(BIO *h, char *str, int size);
 static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int nbiof_new(BIO *h);
 static int nbiof_free(BIO *data);
 static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
 typedef struct nbio_test_st {
     /* only set if we sent a 'should retry' error */
     int lrn;
     int lwn;
 } NBIO_TEST;
 
 static BIO_METHOD methods_nbiof = {
     BIO_TYPE_NBIO_TEST,
     "non-blocking IO test filter",
     nbiof_write,
     nbiof_read,
     nbiof_puts,
     nbiof_gets,
     nbiof_ctrl,
     nbiof_new,
     nbiof_free,
     nbiof_callback_ctrl,
 };
 
 BIO_METHOD *BIO_f_nbio_test(void)
 {
     return (&methods_nbiof);
 }
 
 static int nbiof_new(BIO *bi)
 {
     NBIO_TEST *nt;
 
     if (!(nt = (NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST))))
         return (0);
     nt->lrn = -1;
     nt->lwn = -1;
     bi->ptr = (char *)nt;
     bi->init = 1;
     bi->flags = 0;
     return (1);
 }
 
 static int nbiof_free(BIO *a)
 {
     if (a == NULL)
         return (0);
     if (a->ptr != NULL)
         OPENSSL_free(a->ptr);
     a->ptr = NULL;
     a->init = 0;
     a->flags = 0;
     return (1);
 }
 
 static int nbiof_read(BIO *b, char *out, int outl)
 {
     int ret = 0;
 #if 1
     int num;
     unsigned char n;
 #endif
 
     if (out == NULL)
         return (0);
     if (b->next_bio == NULL)
         return (0);
 
     BIO_clear_retry_flags(b);
 #if 1
-    if (RAND_pseudo_bytes(&n, 1) < 0)
+    if (RAND_bytes(&n, 1) <= 0)
         return -1;
     num = (n & 0x07);
 
     if (outl > num)
         outl = num;
 
     if (num == 0) {
         ret = -1;
         BIO_set_retry_read(b);
     } else
 #endif
     {
         ret = BIO_read(b->next_bio, out, outl);
         if (ret < 0)
             BIO_copy_next_retry(b);
     }
     return (ret);
 }
 
 static int nbiof_write(BIO *b, const char *in, int inl)
 {
     NBIO_TEST *nt;
     int ret = 0;
     int num;
     unsigned char n;
 
     if ((in == NULL) || (inl <= 0))
         return (0);
     if (b->next_bio == NULL)
         return (0);
     nt = (NBIO_TEST *)b->ptr;
 
     BIO_clear_retry_flags(b);
 
 #if 1
     if (nt->lwn > 0) {
         num = nt->lwn;
         nt->lwn = 0;
     } else {
-        if (RAND_pseudo_bytes(&n, 1) < 0)
+        if (RAND_bytes(&n, 1) <= 0)
             return -1;
         num = (n & 7);
     }
 
     if (inl > num)
         inl = num;
 
     if (num == 0) {
         ret = -1;
         BIO_set_retry_write(b);
     } else
 #endif
     {
         ret = BIO_write(b->next_bio, in, inl);
         if (ret < 0) {
             BIO_copy_next_retry(b);
             nt->lwn = inl;
         }
     }
     return (ret);
 }
 
 static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     long ret;
 
     if (b->next_bio == NULL)
         return (0);
     switch (cmd) {
     case BIO_C_DO_STATE_MACHINE:
         BIO_clear_retry_flags(b);
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         BIO_copy_next_retry(b);
         break;
     case BIO_CTRL_DUP:
         ret = 0L;
         break;
     default:
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     }
     return (ret);
 }
 
 static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
 {
     long ret = 1;
 
     if (b->next_bio == NULL)
         return (0);
     switch (cmd) {
     default:
         ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
         break;
     }
     return (ret);
 }
 
 static int nbiof_gets(BIO *bp, char *buf, int size)
 {
     if (bp->next_bio == NULL)
         return (0);
     return (BIO_gets(bp->next_bio, buf, size));
 }
 
 static int nbiof_puts(BIO *bp, const char *str)
 {
     if (bp->next_bio == NULL)
         return (0);
     return (BIO_puts(bp->next_bio, str));
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_lib.c	(revision 306191)
@@ -1,916 +1,916 @@
 /* crypto/bn/bn_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.]
  */
 
 #ifndef BN_DEBUG
 # undef NDEBUG                  /* avoid conflicting definitions */
 # define NDEBUG
 #endif
 
 #include <assert.h>
 #include <limits.h>
 #include <stdio.h>
 #include "cryptlib.h"
 #include "bn_lcl.h"
 
 const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT;
 
 /* This stuff appears to be completely unused, so is deprecated */
 #ifndef OPENSSL_NO_DEPRECATED
 /*-
  * For a 32 bit machine
  * 2 -   4 ==  128
  * 3 -   8 ==  256
  * 4 -  16 ==  512
  * 5 -  32 == 1024
  * 6 -  64 == 2048
  * 7 - 128 == 4096
  * 8 - 256 == 8192
  */
 static int bn_limit_bits = 0;
 static int bn_limit_num = 8;    /* (1<<bn_limit_bits) */
 static int bn_limit_bits_low = 0;
 static int bn_limit_num_low = 8; /* (1<<bn_limit_bits_low) */
 static int bn_limit_bits_high = 0;
 static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
 static int bn_limit_bits_mont = 0;
 static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
 
 void BN_set_params(int mult, int high, int low, int mont)
 {
     if (mult >= 0) {
         if (mult > (int)(sizeof(int) * 8) - 1)
             mult = sizeof(int) * 8 - 1;
         bn_limit_bits = mult;
         bn_limit_num = 1 << mult;
     }
     if (high >= 0) {
         if (high > (int)(sizeof(int) * 8) - 1)
             high = sizeof(int) * 8 - 1;
         bn_limit_bits_high = high;
         bn_limit_num_high = 1 << high;
     }
     if (low >= 0) {
         if (low > (int)(sizeof(int) * 8) - 1)
             low = sizeof(int) * 8 - 1;
         bn_limit_bits_low = low;
         bn_limit_num_low = 1 << low;
     }
     if (mont >= 0) {
         if (mont > (int)(sizeof(int) * 8) - 1)
             mont = sizeof(int) * 8 - 1;
         bn_limit_bits_mont = mont;
         bn_limit_num_mont = 1 << mont;
     }
 }
 
 int BN_get_params(int which)
 {
     if (which == 0)
         return (bn_limit_bits);
     else if (which == 1)
         return (bn_limit_bits_high);
     else if (which == 2)
         return (bn_limit_bits_low);
     else if (which == 3)
         return (bn_limit_bits_mont);
     else
         return (0);
 }
 #endif
 
 const BIGNUM *BN_value_one(void)
 {
     static const BN_ULONG data_one = 1L;
     static const BIGNUM const_one =
         { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA };
 
     return (&const_one);
 }
 
 int BN_num_bits_word(BN_ULONG l)
 {
     static const unsigned char bits[256] = {
         0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
     };
 
 #if defined(SIXTY_FOUR_BIT_LONG)
     if (l & 0xffffffff00000000L) {
         if (l & 0xffff000000000000L) {
             if (l & 0xff00000000000000L) {
                 return (bits[(int)(l >> 56)] + 56);
             } else
                 return (bits[(int)(l >> 48)] + 48);
         } else {
             if (l & 0x0000ff0000000000L) {
                 return (bits[(int)(l >> 40)] + 40);
             } else
                 return (bits[(int)(l >> 32)] + 32);
         }
     } else
 #else
 # ifdef SIXTY_FOUR_BIT
     if (l & 0xffffffff00000000LL) {
         if (l & 0xffff000000000000LL) {
             if (l & 0xff00000000000000LL) {
                 return (bits[(int)(l >> 56)] + 56);
             } else
                 return (bits[(int)(l >> 48)] + 48);
         } else {
             if (l & 0x0000ff0000000000LL) {
                 return (bits[(int)(l >> 40)] + 40);
             } else
                 return (bits[(int)(l >> 32)] + 32);
         }
     } else
 # endif
 #endif
     {
 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
         if (l & 0xffff0000L) {
             if (l & 0xff000000L)
                 return (bits[(int)(l >> 24L)] + 24);
             else
                 return (bits[(int)(l >> 16L)] + 16);
         } else
 #endif
         {
 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
             if (l & 0xff00L)
                 return (bits[(int)(l >> 8)] + 8);
             else
 #endif
                 return (bits[(int)(l)]);
         }
     }
 }
 
 int BN_num_bits(const BIGNUM *a)
 {
     int i = a->top - 1;
     bn_check_top(a);
 
     if (BN_is_zero(a))
         return 0;
     return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
 }
 
 void BN_clear_free(BIGNUM *a)
 {
     int i;
 
     if (a == NULL)
         return;
     bn_check_top(a);
     if (a->d != NULL) {
         OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
         if (!(BN_get_flags(a, BN_FLG_STATIC_DATA)))
             OPENSSL_free(a->d);
     }
     i = BN_get_flags(a, BN_FLG_MALLOCED);
     OPENSSL_cleanse(a, sizeof(BIGNUM));
     if (i)
         OPENSSL_free(a);
 }
 
 void BN_free(BIGNUM *a)
 {
     if (a == NULL)
         return;
     bn_check_top(a);
     if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
         OPENSSL_free(a->d);
     if (a->flags & BN_FLG_MALLOCED)
         OPENSSL_free(a);
     else {
 #ifndef OPENSSL_NO_DEPRECATED
         a->flags |= BN_FLG_FREE;
 #endif
         a->d = NULL;
     }
 }
 
 void BN_init(BIGNUM *a)
 {
     memset(a, 0, sizeof(BIGNUM));
     bn_check_top(a);
 }
 
 BIGNUM *BN_new(void)
 {
     BIGNUM *ret;
 
     if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) {
         BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE);
         return (NULL);
     }
     ret->flags = BN_FLG_MALLOCED;
     ret->top = 0;
     ret->neg = 0;
     ret->dmax = 0;
     ret->d = NULL;
     bn_check_top(ret);
     return (ret);
 }
 
 /* This is used both by bn_expand2() and bn_dup_expand() */
 /* The caller MUST check that words > b->dmax before calling this */
 static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
 {
     BN_ULONG *A, *a = NULL;
     const BN_ULONG *B;
     int i;
 
     bn_check_top(b);
 
     if (words > (INT_MAX / (4 * BN_BITS2))) {
         BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG);
         return NULL;
     }
     if (BN_get_flags(b, BN_FLG_STATIC_DATA)) {
         BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
         return (NULL);
     }
     a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
     if (A == NULL) {
         BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE);
         return (NULL);
     }
 #ifdef PURIFY
     /*
      * Valgrind complains in BN_consttime_swap because we process the whole
      * array even if it's not initialised yet. This doesn't matter in that
      * function - what's important is constant time operation (we're not
      * actually going to use the data)
      */
     memset(a, 0, sizeof(BN_ULONG) * words);
 #endif
 
 #if 1
     B = b->d;
     /* Check if the previous number needs to be copied */
     if (B != NULL) {
         for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
             /*
              * The fact that the loop is unrolled
              * 4-wise is a tribute to Intel. It's
              * the one that doesn't have enough
              * registers to accomodate more data.
              * I'd unroll it 8-wise otherwise:-)
              *
              *              <appro@fy.chalmers.se>
              */
             BN_ULONG a0, a1, a2, a3;
             a0 = B[0];
             a1 = B[1];
             a2 = B[2];
             a3 = B[3];
             A[0] = a0;
             A[1] = a1;
             A[2] = a2;
             A[3] = a3;
         }
         /*
          * workaround for ultrix cc: without 'case 0', the optimizer does
          * the switch table by doing a=top&3; a--; goto jump_table[a];
          * which fails for top== 0
          */
         switch (b->top & 3) {
         case 3:
             A[2] = B[2];
         case 2:
             A[1] = B[1];
         case 1:
             A[0] = B[0];
         case 0:
             ;
         }
     }
 #else
     memset(A, 0, sizeof(BN_ULONG) * words);
     memcpy(A, b->d, sizeof(b->d[0]) * b->top);
 #endif
 
     return (a);
 }
 
 /*
  * This is an internal function that can be used instead of bn_expand2() when
  * there is a need to copy BIGNUMs instead of only expanding the data part,
  * while still expanding them. Especially useful when needing to expand
  * BIGNUMs that are declared 'const' and should therefore not be changed. The
  * reason to use this instead of a BN_dup() followed by a bn_expand2() is
  * memory allocation overhead.  A BN_dup() followed by a bn_expand2() will
  * allocate new memory for the BIGNUM data twice, and free it once, while
  * bn_dup_expand() makes sure allocation is made only once.
  */
 
 #ifndef OPENSSL_NO_DEPRECATED
 BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
 {
     BIGNUM *r = NULL;
 
     bn_check_top(b);
 
     /*
      * This function does not work if words <= b->dmax && top < words because
      * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used
      * anywhere yet.)
      */
 
     if (words > b->dmax) {
         BN_ULONG *a = bn_expand_internal(b, words);
 
         if (a) {
             r = BN_new();
             if (r) {
                 r->top = b->top;
                 r->dmax = words;
                 r->neg = b->neg;
                 r->d = a;
             } else {
                 /* r == NULL, BN_new failure */
                 OPENSSL_free(a);
             }
         }
         /*
          * If a == NULL, there was an error in allocation in
          * bn_expand_internal(), and NULL should be returned
          */
     } else {
         r = BN_dup(b);
     }
 
     bn_check_top(r);
     return r;
 }
 #endif
 
 /*
  * This is an internal function that should not be used in applications. It
  * ensures that 'b' has enough room for a 'words' word number and initialises
  * any unused part of b->d with leading zeros. It is mostly used by the
  * various BIGNUM routines. If there is an error, NULL is returned. If not,
  * 'b' is returned.
  */
 
 BIGNUM *bn_expand2(BIGNUM *b, int words)
 {
     bn_check_top(b);
 
     if (words > b->dmax) {
         BN_ULONG *a = bn_expand_internal(b, words);
         if (!a)
             return NULL;
         if (b->d)
             OPENSSL_free(b->d);
         b->d = a;
         b->dmax = words;
     }
 
 /* None of this should be necessary because of what b->top means! */
 #if 0
     /*
      * NB: bn_wexpand() calls this only if the BIGNUM really has to grow
      */
     if (b->top < b->dmax) {
         int i;
         BN_ULONG *A = &(b->d[b->top]);
         for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) {
             A[0] = 0;
             A[1] = 0;
             A[2] = 0;
             A[3] = 0;
             A[4] = 0;
             A[5] = 0;
             A[6] = 0;
             A[7] = 0;
         }
         for (i = (b->dmax - b->top) & 7; i > 0; i--, A++)
             A[0] = 0;
         assert(A == &(b->d[b->dmax]));
     }
 #endif
     bn_check_top(b);
     return b;
 }
 
 BIGNUM *BN_dup(const BIGNUM *a)
 {
     BIGNUM *t;
 
     if (a == NULL)
         return NULL;
     bn_check_top(a);
 
     t = BN_new();
     if (t == NULL)
         return NULL;
     if (!BN_copy(t, a)) {
         BN_free(t);
         return NULL;
     }
     bn_check_top(t);
     return t;
 }
 
 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
 {
     int i;
     BN_ULONG *A;
     const BN_ULONG *B;
 
     bn_check_top(b);
 
     if (a == b)
         return (a);
     if (bn_wexpand(a, b->top) == NULL)
         return (NULL);
 
 #if 1
     A = a->d;
     B = b->d;
     for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) {
         BN_ULONG a0, a1, a2, a3;
         a0 = B[0];
         a1 = B[1];
         a2 = B[2];
         a3 = B[3];
         A[0] = a0;
         A[1] = a1;
         A[2] = a2;
         A[3] = a3;
     }
     /* ultrix cc workaround, see comments in bn_expand_internal */
     switch (b->top & 3) {
     case 3:
         A[2] = B[2];
     case 2:
         A[1] = B[1];
     case 1:
         A[0] = B[0];
     case 0:;
     }
 #else
     memcpy(a->d, b->d, sizeof(b->d[0]) * b->top);
 #endif
 
     a->top = b->top;
     a->neg = b->neg;
     bn_check_top(a);
     return (a);
 }
 
 void BN_swap(BIGNUM *a, BIGNUM *b)
 {
     int flags_old_a, flags_old_b;
     BN_ULONG *tmp_d;
     int tmp_top, tmp_dmax, tmp_neg;
 
     bn_check_top(a);
     bn_check_top(b);
 
     flags_old_a = a->flags;
     flags_old_b = b->flags;
 
     tmp_d = a->d;
     tmp_top = a->top;
     tmp_dmax = a->dmax;
     tmp_neg = a->neg;
 
     a->d = b->d;
     a->top = b->top;
     a->dmax = b->dmax;
     a->neg = b->neg;
 
     b->d = tmp_d;
     b->top = tmp_top;
     b->dmax = tmp_dmax;
     b->neg = tmp_neg;
 
     a->flags =
         (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
     b->flags =
         (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
     bn_check_top(a);
     bn_check_top(b);
 }
 
 void BN_clear(BIGNUM *a)
 {
     bn_check_top(a);
     if (a->d != NULL)
-        memset(a->d, 0, a->dmax * sizeof(a->d[0]));
+        OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
     a->top = 0;
     a->neg = 0;
 }
 
 BN_ULONG BN_get_word(const BIGNUM *a)
 {
     if (a->top > 1)
         return BN_MASK2;
     else if (a->top == 1)
         return a->d[0];
     /* a->top == 0 */
     return 0;
 }
 
 int BN_set_word(BIGNUM *a, BN_ULONG w)
 {
     bn_check_top(a);
     if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
         return (0);
     a->neg = 0;
     a->d[0] = w;
     a->top = (w ? 1 : 0);
     bn_check_top(a);
     return (1);
 }
 
 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
 {
     unsigned int i, m;
     unsigned int n;
     BN_ULONG l;
     BIGNUM *bn = NULL;
 
     if (ret == NULL)
         ret = bn = BN_new();
     if (ret == NULL)
         return (NULL);
     bn_check_top(ret);
     l = 0;
     n = len;
     if (n == 0) {
         ret->top = 0;
         return (ret);
     }
     i = ((n - 1) / BN_BYTES) + 1;
     m = ((n - 1) % (BN_BYTES));
     if (bn_wexpand(ret, (int)i) == NULL) {
         if (bn)
             BN_free(bn);
         return NULL;
     }
     ret->top = i;
     ret->neg = 0;
     while (n--) {
         l = (l << 8L) | *(s++);
         if (m-- == 0) {
             ret->d[--i] = l;
             l = 0;
             m = BN_BYTES - 1;
         }
     }
     /*
      * need to call this due to clear byte at top if avoiding having the top
      * bit set (-ve number)
      */
     bn_correct_top(ret);
     return (ret);
 }
 
 /* ignore negative */
 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
 {
     int n, i;
     BN_ULONG l;
 
     bn_check_top(a);
     n = i = BN_num_bytes(a);
     while (i--) {
         l = a->d[i / BN_BYTES];
         *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
     }
     return (n);
 }
 
 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
 {
     int i;
     BN_ULONG t1, t2, *ap, *bp;
 
     bn_check_top(a);
     bn_check_top(b);
 
     i = a->top - b->top;
     if (i != 0)
         return (i);
     ap = a->d;
     bp = b->d;
     for (i = a->top - 1; i >= 0; i--) {
         t1 = ap[i];
         t2 = bp[i];
         if (t1 != t2)
             return ((t1 > t2) ? 1 : -1);
     }
     return (0);
 }
 
 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
 {
     int i;
     int gt, lt;
     BN_ULONG t1, t2;
 
     if ((a == NULL) || (b == NULL)) {
         if (a != NULL)
             return (-1);
         else if (b != NULL)
             return (1);
         else
             return (0);
     }
 
     bn_check_top(a);
     bn_check_top(b);
 
     if (a->neg != b->neg) {
         if (a->neg)
             return (-1);
         else
             return (1);
     }
     if (a->neg == 0) {
         gt = 1;
         lt = -1;
     } else {
         gt = -1;
         lt = 1;
     }
 
     if (a->top > b->top)
         return (gt);
     if (a->top < b->top)
         return (lt);
     for (i = a->top - 1; i >= 0; i--) {
         t1 = a->d[i];
         t2 = b->d[i];
         if (t1 > t2)
             return (gt);
         if (t1 < t2)
             return (lt);
     }
     return (0);
 }
 
 int BN_set_bit(BIGNUM *a, int n)
 {
     int i, j, k;
 
     if (n < 0)
         return 0;
 
     i = n / BN_BITS2;
     j = n % BN_BITS2;
     if (a->top <= i) {
         if (bn_wexpand(a, i + 1) == NULL)
             return (0);
         for (k = a->top; k < i + 1; k++)
             a->d[k] = 0;
         a->top = i + 1;
     }
 
     a->d[i] |= (((BN_ULONG)1) << j);
     bn_check_top(a);
     return (1);
 }
 
 int BN_clear_bit(BIGNUM *a, int n)
 {
     int i, j;
 
     bn_check_top(a);
     if (n < 0)
         return 0;
 
     i = n / BN_BITS2;
     j = n % BN_BITS2;
     if (a->top <= i)
         return (0);
 
     a->d[i] &= (~(((BN_ULONG)1) << j));
     bn_correct_top(a);
     return (1);
 }
 
 int BN_is_bit_set(const BIGNUM *a, int n)
 {
     int i, j;
 
     bn_check_top(a);
     if (n < 0)
         return 0;
     i = n / BN_BITS2;
     j = n % BN_BITS2;
     if (a->top <= i)
         return 0;
     return (int)(((a->d[i]) >> j) & ((BN_ULONG)1));
 }
 
 int BN_mask_bits(BIGNUM *a, int n)
 {
     int b, w;
 
     bn_check_top(a);
     if (n < 0)
         return 0;
 
     w = n / BN_BITS2;
     b = n % BN_BITS2;
     if (w >= a->top)
         return 0;
     if (b == 0)
         a->top = w;
     else {
         a->top = w + 1;
         a->d[w] &= ~(BN_MASK2 << b);
     }
     bn_correct_top(a);
     return (1);
 }
 
 void BN_set_negative(BIGNUM *a, int b)
 {
     if (b && !BN_is_zero(a))
         a->neg = 1;
     else
         a->neg = 0;
 }
 
 int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
 {
     int i;
     BN_ULONG aa, bb;
 
     aa = a[n - 1];
     bb = b[n - 1];
     if (aa != bb)
         return ((aa > bb) ? 1 : -1);
     for (i = n - 2; i >= 0; i--) {
         aa = a[i];
         bb = b[i];
         if (aa != bb)
             return ((aa > bb) ? 1 : -1);
     }
     return (0);
 }
 
 /*
  * Here follows a specialised variants of bn_cmp_words().  It has the
  * property of performing the operation on arrays of different sizes. The
  * sizes of those arrays is expressed through cl, which is the common length
  * ( basicall, min(len(a),len(b)) ), and dl, which is the delta between the
  * two lengths, calculated as len(a)-len(b). All lengths are the number of
  * BN_ULONGs...
  */
 
 int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl)
 {
     int n, i;
     n = cl - 1;
 
     if (dl < 0) {
         for (i = dl; i < 0; i++) {
             if (b[n - i] != 0)
                 return -1;      /* a < b */
         }
     }
     if (dl > 0) {
         for (i = dl; i > 0; i--) {
             if (a[n + i] != 0)
                 return 1;       /* a > b */
         }
     }
     return bn_cmp_words(a, b, cl);
 }
 
 /*
  * Constant-time conditional swap of a and b.
  * a and b are swapped if condition is not 0.  The code assumes that at most one bit of condition is set.
  * nwords is the number of words to swap.  The code assumes that at least nwords are allocated in both a and b,
  * and that no more than nwords are used by either a or b.
  * a and b cannot be the same number
  */
 void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords)
 {
     BN_ULONG t;
     int i;
 
     bn_wcheck_size(a, nwords);
     bn_wcheck_size(b, nwords);
 
     assert(a != b);
     assert((condition & (condition - 1)) == 0);
     assert(sizeof(BN_ULONG) >= sizeof(int));
 
     condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1;
 
     t = (a->top ^ b->top) & condition;
     a->top ^= t;
     b->top ^= t;
 
 #define BN_CONSTTIME_SWAP(ind) \
         do { \
                 t = (a->d[ind] ^ b->d[ind]) & condition; \
                 a->d[ind] ^= t; \
                 b->d[ind] ^= t; \
         } while (0)
 
     switch (nwords) {
     default:
         for (i = 10; i < nwords; i++)
             BN_CONSTTIME_SWAP(i);
         /* Fallthrough */
     case 10:
         BN_CONSTTIME_SWAP(9);   /* Fallthrough */
     case 9:
         BN_CONSTTIME_SWAP(8);   /* Fallthrough */
     case 8:
         BN_CONSTTIME_SWAP(7);   /* Fallthrough */
     case 7:
         BN_CONSTTIME_SWAP(6);   /* Fallthrough */
     case 6:
         BN_CONSTTIME_SWAP(5);   /* Fallthrough */
     case 5:
         BN_CONSTTIME_SWAP(4);   /* Fallthrough */
     case 4:
         BN_CONSTTIME_SWAP(3);   /* Fallthrough */
     case 3:
         BN_CONSTTIME_SWAP(2);   /* Fallthrough */
     case 2:
         BN_CONSTTIME_SWAP(1);   /* Fallthrough */
     case 1:
         BN_CONSTTIME_SWAP(0);
     }
 #undef BN_CONSTTIME_SWAP
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_print.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_print.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_print.c	(revision 306191)
@@ -1,397 +1,401 @@
 /* crypto/bn/bn_print.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.]
  */
 
 #include <stdio.h>
 #include <ctype.h>
 #include <limits.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include "bn_lcl.h"
 
 static const char Hex[] = "0123456789ABCDEF";
 
 /* Must 'OPENSSL_free' the returned data */
 char *BN_bn2hex(const BIGNUM *a)
 {
     int i, j, v, z = 0;
     char *buf;
     char *p;
 
     if (a->neg && BN_is_zero(a)) {
         /* "-0" == 3 bytes including NULL terminator */
         buf = OPENSSL_malloc(3);
     } else {
         buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
     }
     if (buf == NULL) {
         BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     p = buf;
     if (a->neg)
         *(p++) = '-';
     if (BN_is_zero(a))
         *(p++) = '0';
     for (i = a->top - 1; i >= 0; i--) {
         for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
             /* strip leading zeros */
             v = ((int)(a->d[i] >> (long)j)) & 0xff;
             if (z || (v != 0)) {
                 *(p++) = Hex[v >> 4];
                 *(p++) = Hex[v & 0x0f];
                 z = 1;
             }
         }
     }
     *p = '\0';
  err:
     return (buf);
 }
 
 /* Must 'OPENSSL_free' the returned data */
 char *BN_bn2dec(const BIGNUM *a)
 {
     int i = 0, num, ok = 0;
     char *buf = NULL;
     char *p;
     BIGNUM *t = NULL;
     BN_ULONG *bn_data = NULL, *lp;
+    int bn_data_num;
 
     /*-
      * get an upper bound for the length of the decimal integer
      * num <= (BN_num_bits(a) + 1) * log(2)
      *     <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1     (rounding error)
      *     <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1
      */
     i = BN_num_bits(a) * 3;
     num = (i / 10 + i / 1000 + 1) + 1;
-    bn_data =
-        (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
-    buf = (char *)OPENSSL_malloc(num + 3);
+    bn_data_num = num / BN_DEC_NUM + 1;
+    bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
+    buf = OPENSSL_malloc(num + 3);
     if ((buf == NULL) || (bn_data == NULL)) {
         BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     if ((t = BN_dup(a)) == NULL)
         goto err;
 
 #define BUF_REMAIN (num+3 - (size_t)(p - buf))
     p = buf;
     lp = bn_data;
     if (BN_is_zero(t)) {
         *(p++) = '0';
         *(p++) = '\0';
     } else {
         if (BN_is_negative(t))
             *p++ = '-';
 
-        i = 0;
         while (!BN_is_zero(t)) {
+            if (lp - bn_data >= bn_data_num)
+                goto err;
             *lp = BN_div_word(t, BN_DEC_CONV);
+            if (*lp == (BN_ULONG)-1)
+                goto err;
             lp++;
         }
         lp--;
         /*
          * We now have a series of blocks, BN_DEC_NUM chars in length, where
          * the last one needs truncation. The blocks need to be reversed in
          * order.
          */
         BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp);
         while (*p)
             p++;
         while (lp != bn_data) {
             lp--;
             BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp);
             while (*p)
                 p++;
         }
     }
     ok = 1;
  err:
     if (bn_data != NULL)
         OPENSSL_free(bn_data);
     if (t != NULL)
         BN_free(t);
     if (!ok && buf) {
         OPENSSL_free(buf);
         buf = NULL;
     }
 
     return (buf);
 }
 
 int BN_hex2bn(BIGNUM **bn, const char *a)
 {
     BIGNUM *ret = NULL;
     BN_ULONG l = 0;
     int neg = 0, h, m, i, j, k, c;
     int num;
 
     if ((a == NULL) || (*a == '\0'))
         return (0);
 
     if (*a == '-') {
         neg = 1;
         a++;
     }
 
     for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++)
         continue;
 
     if (i > INT_MAX/4)
         goto err;
 
     num = i + neg;
     if (bn == NULL)
         return (num);
 
     /* a is the start of the hex digits, and it is 'i' long */
     if (*bn == NULL) {
         if ((ret = BN_new()) == NULL)
             return (0);
     } else {
         ret = *bn;
         BN_zero(ret);
     }
 
     /* i is the number of hex digits */
     if (bn_expand(ret, i * 4) == NULL)
         goto err;
 
     j = i;                      /* least significant 'hex' */
     m = 0;
     h = 0;
     while (j > 0) {
         m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
         l = 0;
         for (;;) {
             c = a[j - m];
             if ((c >= '0') && (c <= '9'))
                 k = c - '0';
             else if ((c >= 'a') && (c <= 'f'))
                 k = c - 'a' + 10;
             else if ((c >= 'A') && (c <= 'F'))
                 k = c - 'A' + 10;
             else
                 k = 0;          /* paranoia */
             l = (l << 4) | k;
 
             if (--m <= 0) {
                 ret->d[h++] = l;
                 break;
             }
         }
         j -= (BN_BYTES * 2);
     }
     ret->top = h;
     bn_correct_top(ret);
     ret->neg = neg;
 
     *bn = ret;
     bn_check_top(ret);
     return (num);
  err:
     if (*bn == NULL)
         BN_free(ret);
     return (0);
 }
 
 int BN_dec2bn(BIGNUM **bn, const char *a)
 {
     BIGNUM *ret = NULL;
     BN_ULONG l = 0;
     int neg = 0, i, j;
     int num;
 
     if ((a == NULL) || (*a == '\0'))
         return (0);
     if (*a == '-') {
         neg = 1;
         a++;
     }
 
     for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++)
         continue;
 
     if (i > INT_MAX/4)
         goto err;
 
     num = i + neg;
     if (bn == NULL)
         return (num);
 
     /*
      * a is the start of the digits, and it is 'i' long. We chop it into
      * BN_DEC_NUM digits at a time
      */
     if (*bn == NULL) {
         if ((ret = BN_new()) == NULL)
             return (0);
     } else {
         ret = *bn;
         BN_zero(ret);
     }
 
     /* i is the number of digits, a bit of an over expand */
     if (bn_expand(ret, i * 4) == NULL)
         goto err;
 
     j = BN_DEC_NUM - (i % BN_DEC_NUM);
     if (j == BN_DEC_NUM)
         j = 0;
     l = 0;
     while (*a) {
         l *= 10;
         l += *a - '0';
         a++;
         if (++j == BN_DEC_NUM) {
             BN_mul_word(ret, BN_DEC_CONV);
             BN_add_word(ret, l);
             l = 0;
             j = 0;
         }
     }
     ret->neg = neg;
 
     bn_correct_top(ret);
     *bn = ret;
     bn_check_top(ret);
     return (num);
  err:
     if (*bn == NULL)
         BN_free(ret);
     return (0);
 }
 
 int BN_asc2bn(BIGNUM **bn, const char *a)
 {
     const char *p = a;
     if (*p == '-')
         p++;
 
     if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) {
         if (!BN_hex2bn(bn, p + 2))
             return 0;
     } else {
         if (!BN_dec2bn(bn, p))
             return 0;
     }
     if (*a == '-')
         (*bn)->neg = 1;
     return 1;
 }
 
 #ifndef OPENSSL_NO_BIO
 # ifndef OPENSSL_NO_FP_API
 int BN_print_fp(FILE *fp, const BIGNUM *a)
 {
     BIO *b;
     int ret;
 
     if ((b = BIO_new(BIO_s_file())) == NULL)
         return (0);
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     ret = BN_print(b, a);
     BIO_free(b);
     return (ret);
 }
 # endif
 
 int BN_print(BIO *bp, const BIGNUM *a)
 {
     int i, j, v, z = 0;
     int ret = 0;
 
     if ((a->neg) && (BIO_write(bp, "-", 1) != 1))
         goto end;
     if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1))
         goto end;
     for (i = a->top - 1; i >= 0; i--) {
         for (j = BN_BITS2 - 4; j >= 0; j -= 4) {
             /* strip leading zeros */
             v = ((int)(a->d[i] >> (long)j)) & 0x0f;
             if (z || (v != 0)) {
                 if (BIO_write(bp, &(Hex[v]), 1) != 1)
                     goto end;
                 z = 1;
             }
         }
     }
     ret = 1;
  end:
     return (ret);
 }
 #endif
 
 char *BN_options(void)
 {
     static int init = 0;
     static char data[16];
 
     if (!init) {
         init++;
 #ifdef BN_LLONG
         BIO_snprintf(data, sizeof data, "bn(%d,%d)",
                      (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8);
 #else
         BIO_snprintf(data, sizeof data, "bn(%d,%d)",
                      (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8);
 #endif
     }
     return (data);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_rand.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_rand.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/bn/bn_rand.c	(revision 306191)
@@ -1,295 +1,291 @@
 /* crypto/bn/bn_rand.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 <stdio.h>
 #include <time.h>
 #include "cryptlib.h"
 #include "bn_lcl.h"
 #include <openssl/rand.h>
 
 static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
 {
     unsigned char *buf = NULL;
     int ret = 0, bit, bytes, mask;
     time_t tim;
 
     if (bits < 0 || (bits == 1 && top > 0)) {
         BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
         return 0;
     }
 
     if (bits == 0) {
         BN_zero(rnd);
         return 1;
     }
 
     bytes = (bits + 7) / 8;
     bit = (bits - 1) % 8;
     mask = 0xff << (bit + 1);
 
     buf = (unsigned char *)OPENSSL_malloc(bytes);
     if (buf == NULL) {
         BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     /* make a random number and set the top and bottom bits */
     time(&tim);
     RAND_add(&tim, sizeof(tim), 0.0);
 
-    if (pseudorand) {
-        if (RAND_pseudo_bytes(buf, bytes) == -1)
-            goto err;
-    } else {
-        if (RAND_bytes(buf, bytes) <= 0)
-            goto err;
-    }
+    /* We ignore the value of pseudorand and always call RAND_bytes */
+    if (RAND_bytes(buf, bytes) <= 0)
+        goto err;
 
 #if 1
     if (pseudorand == 2) {
         /*
          * generate patterns that are more likely to trigger BN library bugs
          */
         int i;
         unsigned char c;
 
         for (i = 0; i < bytes; i++) {
             if (RAND_pseudo_bytes(&c, 1) < 0)
                 goto err;
             if (c >= 128 && i > 0)
                 buf[i] = buf[i - 1];
             else if (c < 42)
                 buf[i] = 0;
             else if (c < 84)
                 buf[i] = 255;
         }
     }
 #endif
 
     if (top >= 0) {
         if (top) {
             if (bit == 0) {
                 buf[0] = 1;
                 buf[1] |= 0x80;
             } else {
                 buf[0] |= (3 << (bit - 1));
             }
         } else {
             buf[0] |= (1 << bit);
         }
     }
     buf[0] &= ~mask;
     if (bottom)                 /* set bottom bit if requested */
         buf[bytes - 1] |= 1;
     if (!BN_bin2bn(buf, bytes, rnd))
         goto err;
     ret = 1;
  err:
     if (buf != NULL) {
         OPENSSL_cleanse(buf, bytes);
         OPENSSL_free(buf);
     }
     bn_check_top(rnd);
     return (ret);
 }
 
 int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
 {
     return bnrand(0, rnd, bits, top, bottom);
 }
 
 int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom)
 {
     return bnrand(1, rnd, bits, top, bottom);
 }
 
 #if 1
 int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom)
 {
     return bnrand(2, rnd, bits, top, bottom);
 }
 #endif
 
 /* random number r:  0 <= r < range */
 static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range)
 {
     int (*bn_rand) (BIGNUM *, int, int, int) =
         pseudo ? BN_pseudo_rand : BN_rand;
     int n;
     int count = 100;
 
     if (range->neg || BN_is_zero(range)) {
         BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE);
         return 0;
     }
 
     n = BN_num_bits(range);     /* n > 0 */
 
     /* BN_is_bit_set(range, n - 1) always holds */
 
     if (n == 1)
         BN_zero(r);
     else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) {
         /*
          * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer
          * than range
          */
         do {
             if (!bn_rand(r, n + 1, -1, 0))
                 return 0;
             /*
              * If r < 3*range, use r := r MOD range (which is either r, r -
              * range, or r - 2*range). Otherwise, iterate once more. Since
              * 3*range = 11..._2, each iteration succeeds with probability >=
              * .75.
              */
             if (BN_cmp(r, range) >= 0) {
                 if (!BN_sub(r, r, range))
                     return 0;
                 if (BN_cmp(r, range) >= 0)
                     if (!BN_sub(r, r, range))
                         return 0;
             }
 
             if (!--count) {
                 BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
                 return 0;
             }
 
         }
         while (BN_cmp(r, range) >= 0);
     } else {
         do {
             /* range = 11..._2  or  range = 101..._2 */
             if (!bn_rand(r, n, -1, 0))
                 return 0;
 
             if (!--count) {
                 BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS);
                 return 0;
             }
         }
         while (BN_cmp(r, range) >= 0);
     }
 
     bn_check_top(r);
     return 1;
 }
 
 int BN_rand_range(BIGNUM *r, const BIGNUM *range)
 {
     return bn_rand_range(0, r, range);
 }
 
 int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range)
 {
     return bn_rand_range(1, r, range);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_enc.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_enc.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_enc.c	(revision 306191)
@@ -1,260 +1,264 @@
 /* crypto/cms/cms_enc.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 "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/pem.h>
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include <openssl/rand.h>
 #include "cms_lcl.h"
 
 /* CMS EncryptedData Utilities */
 
 DECLARE_ASN1_ITEM(CMS_EncryptedData)
 
 /* Return BIO based on EncryptedContentInfo and key */
 
 BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
 {
     BIO *b;
     EVP_CIPHER_CTX *ctx;
     const EVP_CIPHER *ciph;
     X509_ALGOR *calg = ec->contentEncryptionAlgorithm;
     unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL;
     unsigned char *tkey = NULL;
     size_t tkeylen = 0;
 
     int ok = 0;
 
     int enc, keep_key = 0;
 
     enc = ec->cipher ? 1 : 0;
 
     b = BIO_new(BIO_f_cipher());
     if (!b) {
         CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
 
     BIO_get_cipher_ctx(b, &ctx);
 
     if (enc) {
         ciph = ec->cipher;
         /*
          * If not keeping key set cipher to NULL so subsequent calls decrypt.
          */
         if (ec->key)
             ec->cipher = NULL;
     } else {
         ciph = EVP_get_cipherbyobj(calg->algorithm);
 
         if (!ciph) {
             CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER);
             goto err;
         }
     }
 
     if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) {
         CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                CMS_R_CIPHER_INITIALISATION_ERROR);
         goto err;
     }
 
     if (enc) {
         int ivlen;
         calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx));
         /* Generate a random IV if we need one */
         ivlen = EVP_CIPHER_CTX_iv_length(ctx);
         if (ivlen > 0) {
-            if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+            if (RAND_bytes(iv, ivlen) <= 0)
                 goto err;
             piv = iv;
         }
     } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) {
         CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
         goto err;
     }
     tkeylen = EVP_CIPHER_CTX_key_length(ctx);
     /* Generate random session key */
     if (!enc || !ec->key) {
         tkey = OPENSSL_malloc(tkeylen);
         if (!tkey) {
             CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0)
             goto err;
     }
 
     if (!ec->key) {
         ec->key = tkey;
         ec->keylen = tkeylen;
         tkey = NULL;
         if (enc)
             keep_key = 1;
         else
             ERR_clear_error();
 
     }
 
     if (ec->keylen != tkeylen) {
         /* If necessary set key length */
         if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) {
             /*
              * Only reveal failure if debugging so we don't leak information
              * which may be useful in MMA.
              */
             if (enc || ec->debug) {
                 CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                        CMS_R_INVALID_KEY_LENGTH);
                 goto err;
             } else {
                 /* Use random key */
                 OPENSSL_cleanse(ec->key, ec->keylen);
                 OPENSSL_free(ec->key);
                 ec->key = tkey;
                 ec->keylen = tkeylen;
                 tkey = NULL;
                 ERR_clear_error();
             }
         }
     }
 
     if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) {
         CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                CMS_R_CIPHER_INITIALISATION_ERROR);
         goto err;
     }
-
-    if (piv) {
+    if (enc) {
         calg->parameter = ASN1_TYPE_new();
-        if (!calg->parameter) {
+        if (calg->parameter == NULL) {
             CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) {
             CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO,
                    CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
             goto err;
+        }
+        /* If parameter type not set omit parameter */
+        if (calg->parameter->type == V_ASN1_UNDEF) {
+            ASN1_TYPE_free(calg->parameter);
+            calg->parameter = NULL;
         }
     }
     ok = 1;
 
  err:
     if (ec->key && (!keep_key || !ok)) {
         OPENSSL_cleanse(ec->key, ec->keylen);
         OPENSSL_free(ec->key);
         ec->key = NULL;
     }
     if (tkey) {
         OPENSSL_cleanse(tkey, tkeylen);
         OPENSSL_free(tkey);
     }
     if (ok)
         return b;
     BIO_free(b);
     return NULL;
 }
 
 int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
                               const EVP_CIPHER *cipher,
                               const unsigned char *key, size_t keylen)
 {
     ec->cipher = cipher;
     if (key) {
         ec->key = OPENSSL_malloc(keylen);
         if (!ec->key)
             return 0;
         memcpy(ec->key, key, keylen);
     }
     ec->keylen = keylen;
     if (cipher)
         ec->contentType = OBJ_nid2obj(NID_pkcs7_data);
     return 1;
 }
 
 int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
                                const unsigned char *key, size_t keylen)
 {
     CMS_EncryptedContentInfo *ec;
     if (!key || !keylen) {
         CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY);
         return 0;
     }
     if (ciph) {
         cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData);
         if (!cms->d.encryptedData) {
             CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE);
             return 0;
         }
         cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted);
         cms->d.encryptedData->version = 0;
     } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) {
         CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA);
         return 0;
     }
     ec = cms->d.encryptedData->encryptedContentInfo;
     return cms_EncryptedContent_init(ec, ciph, key, keylen);
 }
 
 BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms)
 {
     CMS_EncryptedData *enc = cms->d.encryptedData;
     if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs)
         enc->version = 2;
     return cms_EncryptedContent_init_bio(enc->encryptedContentInfo);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_ess.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_ess.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_ess.c	(revision 306191)
@@ -1,395 +1,394 @@
 /* crypto/cms/cms_ess.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 "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include "cms_lcl.h"
 
 DECLARE_ASN1_ITEM(CMS_ReceiptRequest)
 DECLARE_ASN1_ITEM(CMS_Receipt)
 
 IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest)
 
 /* ESS services: for now just Signed Receipt related */
 
 int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr)
 {
     ASN1_STRING *str;
     CMS_ReceiptRequest *rr = NULL;
     if (prr)
         *prr = NULL;
     str = CMS_signed_get0_data_by_OBJ(si,
                                       OBJ_nid2obj
                                       (NID_id_smime_aa_receiptRequest), -3,
                                       V_ASN1_SEQUENCE);
     if (!str)
         return 0;
 
     rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest));
     if (!rr)
         return -1;
     if (prr)
         *prr = rr;
     else
         CMS_ReceiptRequest_free(rr);
     return 1;
 }
 
 CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
                                                int allorfirst,
                                                STACK_OF(GENERAL_NAMES)
                                                *receiptList, STACK_OF(GENERAL_NAMES)
                                                *receiptsTo)
 {
     CMS_ReceiptRequest *rr = NULL;
 
     rr = CMS_ReceiptRequest_new();
     if (!rr)
         goto merr;
     if (id)
         ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen);
     else {
         if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
             goto merr;
-        if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32)
-            <= 0)
+        if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
             goto err;
     }
 
     sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free);
     rr->receiptsTo = receiptsTo;
 
     if (receiptList) {
         rr->receiptsFrom->type = 1;
         rr->receiptsFrom->d.receiptList = receiptList;
     } else {
         rr->receiptsFrom->type = 0;
         rr->receiptsFrom->d.allOrFirstTier = allorfirst;
     }
 
     return rr;
 
  merr:
     CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE);
 
  err:
     if (rr)
         CMS_ReceiptRequest_free(rr);
 
     return NULL;
 
 }
 
 int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr)
 {
     unsigned char *rrder = NULL;
     int rrderlen, r = 0;
 
     rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder);
     if (rrderlen < 0)
         goto merr;
 
     if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest,
                                      V_ASN1_SEQUENCE, rrder, rrderlen))
         goto merr;
 
     r = 1;
 
  merr:
     if (!r)
         CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE);
 
     if (rrder)
         OPENSSL_free(rrder);
 
     return r;
 
 }
 
 void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
                                     ASN1_STRING **pcid,
                                     int *pallorfirst,
                                     STACK_OF(GENERAL_NAMES) **plist,
                                     STACK_OF(GENERAL_NAMES) **prto)
 {
     if (pcid)
         *pcid = rr->signedContentIdentifier;
     if (rr->receiptsFrom->type == 0) {
         if (pallorfirst)
             *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier;
         if (plist)
             *plist = NULL;
     } else {
         if (pallorfirst)
             *pallorfirst = -1;
         if (plist)
             *plist = rr->receiptsFrom->d.receiptList;
     }
     if (prto)
         *prto = rr->receiptsTo;
 }
 
 /* Digest a SignerInfo structure for msgSigDigest attribute processing */
 
 static int cms_msgSigDigest(CMS_SignerInfo *si,
                             unsigned char *dig, unsigned int *diglen)
 {
     const EVP_MD *md;
     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
     if (md == NULL)
         return 0;
     if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md,
                           si->signedAttrs, dig, diglen))
         return 0;
     return 1;
 }
 
 /* Add a msgSigDigest attribute to a SignerInfo */
 
 int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src)
 {
     unsigned char dig[EVP_MAX_MD_SIZE];
     unsigned int diglen;
     if (!cms_msgSigDigest(src, dig, &diglen)) {
         CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR);
         return 0;
     }
     if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest,
                                      V_ASN1_OCTET_STRING, dig, diglen)) {
         CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     return 1;
 }
 
 /* Verify signed receipt after it has already passed normal CMS verify */
 
 int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms)
 {
     int r = 0, i;
     CMS_ReceiptRequest *rr = NULL;
     CMS_Receipt *rct = NULL;
     STACK_OF(CMS_SignerInfo) *sis, *osis;
     CMS_SignerInfo *si, *osi = NULL;
     ASN1_OCTET_STRING *msig, **pcont;
     ASN1_OBJECT *octype;
     unsigned char dig[EVP_MAX_MD_SIZE];
     unsigned int diglen;
 
     /* Get SignerInfos, also checks SignedData content type */
     osis = CMS_get0_SignerInfos(req_cms);
     sis = CMS_get0_SignerInfos(cms);
     if (!osis || !sis)
         goto err;
 
     if (sk_CMS_SignerInfo_num(sis) != 1) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER);
         goto err;
     }
 
     /* Check receipt content type */
     if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT);
         goto err;
     }
 
     /* Extract and decode receipt content */
     pcont = CMS_get0_content(cms);
     if (!pcont || !*pcont) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT);
         goto err;
     }
 
     rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt));
 
     if (!rct) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR);
         goto err;
     }
 
     /* Locate original request */
 
     for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) {
         osi = sk_CMS_SignerInfo_value(osis, i);
         if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue))
             break;
     }
 
     if (i == sk_CMS_SignerInfo_num(osis)) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE);
         goto err;
     }
 
     si = sk_CMS_SignerInfo_value(sis, 0);
 
     /* Get msgSigDigest value and compare */
 
     msig = CMS_signed_get0_data_by_OBJ(si,
                                        OBJ_nid2obj
                                        (NID_id_smime_aa_msgSigDigest), -3,
                                        V_ASN1_OCTET_STRING);
 
     if (!msig) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST);
         goto err;
     }
 
     if (!cms_msgSigDigest(osi, dig, &diglen)) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR);
         goto err;
     }
 
     if (diglen != (unsigned int)msig->length) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH);
         goto err;
     }
 
     if (memcmp(dig, msig->data, diglen)) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY,
                CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE);
         goto err;
     }
 
     /* Compare content types */
 
     octype = CMS_signed_get0_data_by_OBJ(osi,
                                          OBJ_nid2obj(NID_pkcs9_contentType),
                                          -3, V_ASN1_OBJECT);
     if (!octype) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE);
         goto err;
     }
 
     /* Compare details in receipt request */
 
     if (OBJ_cmp(octype, rct->contentType)) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH);
         goto err;
     }
 
     /* Get original receipt request details */
 
     if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST);
         goto err;
     }
 
     if (ASN1_STRING_cmp(rr->signedContentIdentifier,
                         rct->signedContentIdentifier)) {
         CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH);
         goto err;
     }
 
     r = 1;
 
  err:
     if (rr)
         CMS_ReceiptRequest_free(rr);
     if (rct)
         M_ASN1_free_of(rct, CMS_Receipt);
 
     return r;
 
 }
 
 /*
  * Encode a Receipt into an OCTET STRING read for including into content of a
  * SignedData ContentInfo.
  */
 
 ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si)
 {
     CMS_Receipt rct;
     CMS_ReceiptRequest *rr = NULL;
     ASN1_OBJECT *ctype;
     ASN1_OCTET_STRING *os = NULL;
 
     /* Get original receipt request */
 
     /* Get original receipt request details */
 
     if (CMS_get1_ReceiptRequest(si, &rr) <= 0) {
         CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST);
         goto err;
     }
 
     /* Get original content type */
 
     ctype = CMS_signed_get0_data_by_OBJ(si,
                                         OBJ_nid2obj(NID_pkcs9_contentType),
                                         -3, V_ASN1_OBJECT);
     if (!ctype) {
         CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE);
         goto err;
     }
 
     rct.version = 1;
     rct.contentType = ctype;
     rct.signedContentIdentifier = rr->signedContentIdentifier;
     rct.originatorSignatureValue = si->signature;
 
     os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL);
 
  err:
     if (rr)
         CMS_ReceiptRequest_free(rr);
 
     return os;
 
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_pwri.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_pwri.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/cms/cms_pwri.c	(revision 306191)
@@ -1,435 +1,435 @@
 /* crypto/cms/cms_pwri.c */
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
  * Copyright (c) 2009 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 "cryptlib.h"
 #include <openssl/asn1t.h>
 #include <openssl/pem.h>
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 #include <openssl/cms.h>
 #include <openssl/rand.h>
 #include <openssl/aes.h>
 #include "cms_lcl.h"
 #include "asn1_locl.h"
 
 int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
                                     unsigned char *pass, ossl_ssize_t passlen)
 {
     CMS_PasswordRecipientInfo *pwri;
     if (ri->type != CMS_RECIPINFO_PASS) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI);
         return 0;
     }
 
     pwri = ri->d.pwri;
     pwri->pass = pass;
     if (pass && passlen < 0)
         passlen = strlen((char *)pass);
     pwri->passlen = passlen;
     return 1;
 }
 
 CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
                                                int iter, int wrap_nid,
                                                int pbe_nid,
                                                unsigned char *pass,
                                                ossl_ssize_t passlen,
                                                const EVP_CIPHER *kekciph)
 {
     CMS_RecipientInfo *ri = NULL;
     CMS_EnvelopedData *env;
     CMS_PasswordRecipientInfo *pwri;
     EVP_CIPHER_CTX ctx;
     X509_ALGOR *encalg = NULL;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     int ivlen;
 
     env = cms_get0_enveloped(cms);
     if (!env)
         return NULL;
 
     if (wrap_nid <= 0)
         wrap_nid = NID_id_alg_PWRI_KEK;
 
     if (pbe_nid <= 0)
         pbe_nid = NID_id_pbkdf2;
 
     /* Get from enveloped data */
     if (kekciph == NULL)
         kekciph = env->encryptedContentInfo->cipher;
 
     if (kekciph == NULL) {
         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER);
         return NULL;
     }
     if (wrap_nid != NID_id_alg_PWRI_KEK) {
         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
                CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
         return NULL;
     }
 
     /* Setup algorithm identifier for cipher */
     encalg = X509_ALGOR_new();
     if (encalg == NULL) {
         goto merr;
     }
     EVP_CIPHER_CTX_init(&ctx);
 
     if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) {
         CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
         goto err;
     }
 
     ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
 
     if (ivlen > 0) {
-        if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+        if (RAND_bytes(iv, ivlen) <= 0)
             goto err;
         if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) {
             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
             goto err;
         }
         encalg->parameter = ASN1_TYPE_new();
         if (!encalg->parameter) {
             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) {
             CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD,
                    CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
             goto err;
         }
     }
 
     encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx));
 
     EVP_CIPHER_CTX_cleanup(&ctx);
 
     /* Initialize recipient info */
     ri = M_ASN1_new_of(CMS_RecipientInfo);
     if (!ri)
         goto merr;
 
     ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo);
     if (!ri->d.pwri)
         goto merr;
     ri->type = CMS_RECIPINFO_PASS;
 
     pwri = ri->d.pwri;
     /* Since this is overwritten, free up empty structure already there */
     X509_ALGOR_free(pwri->keyEncryptionAlgorithm);
     pwri->keyEncryptionAlgorithm = X509_ALGOR_new();
     if (!pwri->keyEncryptionAlgorithm)
         goto merr;
     pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid);
     pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new();
     if (!pwri->keyEncryptionAlgorithm->parameter)
         goto merr;
 
     if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR),
                         &pwri->keyEncryptionAlgorithm->parameter->
                         value.sequence))
          goto merr;
     pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE;
 
     X509_ALGOR_free(encalg);
     encalg = NULL;
 
     /* Setup PBE algorithm */
 
     pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1);
 
     if (!pwri->keyDerivationAlgorithm)
         goto err;
 
     CMS_RecipientInfo_set0_password(ri, pass, passlen);
     pwri->version = 0;
 
     if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
         goto merr;
 
     return ri;
 
  merr:
     CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE);
  err:
     EVP_CIPHER_CTX_cleanup(&ctx);
     if (ri)
         M_ASN1_free_of(ri, CMS_RecipientInfo);
     if (encalg)
         X509_ALGOR_free(encalg);
     return NULL;
 
 }
 
 /*
  * This is an implementation of the key wrapping mechanism in RFC3211, at
  * some point this should go into EVP.
  */
 
 static int kek_unwrap_key(unsigned char *out, size_t *outlen,
                           const unsigned char *in, size_t inlen,
                           EVP_CIPHER_CTX *ctx)
 {
     size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
     unsigned char *tmp;
     int outl, rv = 0;
     if (inlen < 2 * blocklen) {
         /* too small */
         return 0;
     }
     if (inlen % blocklen) {
         /* Invalid size */
         return 0;
     }
     tmp = OPENSSL_malloc(inlen);
     if (!tmp)
         return 0;
     /* setup IV by decrypting last two blocks */
     EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl,
                       in + inlen - 2 * blocklen, blocklen * 2);
     /*
      * Do a decrypt of last decrypted block to set IV to correct value output
      * it to start of buffer so we don't corrupt decrypted block this works
      * because buffer is at least two block lengths long.
      */
     EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen);
     /* Can now decrypt first n - 1 blocks */
     EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen);
 
     /* Reset IV to original value */
     EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL);
     /* Decrypt again */
     EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen);
     /* Check check bytes */
     if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) {
         /* Check byte failure */
         goto err;
     }
     if (inlen < (size_t)(tmp[0] - 4)) {
         /* Invalid length value */
         goto err;
     }
     *outlen = (size_t)tmp[0];
     memcpy(out, tmp + 4, *outlen);
     rv = 1;
  err:
     OPENSSL_cleanse(tmp, inlen);
     OPENSSL_free(tmp);
     return rv;
 
 }
 
 static int kek_wrap_key(unsigned char *out, size_t *outlen,
                         const unsigned char *in, size_t inlen,
                         EVP_CIPHER_CTX *ctx)
 {
     size_t blocklen = EVP_CIPHER_CTX_block_size(ctx);
     size_t olen;
     int dummy;
     /*
      * First decide length of output buffer: need header and round up to
      * multiple of block length.
      */
     olen = (inlen + 4 + blocklen - 1) / blocklen;
     olen *= blocklen;
     if (olen < 2 * blocklen) {
         /* Key too small */
         return 0;
     }
     if (inlen > 0xFF) {
         /* Key too large */
         return 0;
     }
     if (out) {
         /* Set header */
         out[0] = (unsigned char)inlen;
         out[1] = in[0] ^ 0xFF;
         out[2] = in[1] ^ 0xFF;
         out[3] = in[2] ^ 0xFF;
         memcpy(out + 4, in, inlen);
         /* Add random padding to end */
         if (olen > inlen + 4
-            && RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen) < 0)
+            && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
             return 0;
         /* Encrypt twice */
         EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
         EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
     }
 
     *outlen = olen;
 
     return 1;
 }
 
 /* Encrypt/Decrypt content key in PWRI recipient info */
 
 int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
                                  int en_de)
 {
     CMS_EncryptedContentInfo *ec;
     CMS_PasswordRecipientInfo *pwri;
     const unsigned char *p = NULL;
     int plen;
     int r = 0;
     X509_ALGOR *algtmp, *kekalg = NULL;
     EVP_CIPHER_CTX kekctx;
     const EVP_CIPHER *kekcipher;
     unsigned char *key = NULL;
     size_t keylen;
 
     ec = cms->d.envelopedData->encryptedContentInfo;
 
     pwri = ri->d.pwri;
     EVP_CIPHER_CTX_init(&kekctx);
 
     if (!pwri->pass) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD);
         return 0;
     }
     algtmp = pwri->keyEncryptionAlgorithm;
 
     if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
                CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM);
         return 0;
     }
 
     if (algtmp->parameter->type == V_ASN1_SEQUENCE) {
         p = algtmp->parameter->value.sequence->data;
         plen = algtmp->parameter->value.sequence->length;
         kekalg = d2i_X509_ALGOR(NULL, &p, plen);
     }
     if (kekalg == NULL) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
                CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER);
         return 0;
     }
 
     kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
 
     if (!kekcipher) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER);
         goto err;
     }
 
     /* Fixup cipher based on AlgorithmIdentifier to set IV etc */
     if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de))
         goto err;
     EVP_CIPHER_CTX_set_padding(&kekctx, 0);
     if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT,
                CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
         goto err;
     }
 
     algtmp = pwri->keyDerivationAlgorithm;
 
     /* Finish password based key derivation to setup key in "ctx" */
 
     if (EVP_PBE_CipherInit(algtmp->algorithm,
                            (char *)pwri->pass, pwri->passlen,
                            algtmp->parameter, &kekctx, en_de) < 0) {
         CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB);
         goto err;
     }
 
     /* Finally wrap/unwrap the key */
 
     if (en_de) {
 
         if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx))
             goto err;
 
         key = OPENSSL_malloc(keylen);
 
         if (!key)
             goto err;
 
         if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx))
             goto err;
         pwri->encryptedKey->data = key;
         pwri->encryptedKey->length = keylen;
     } else {
         key = OPENSSL_malloc(pwri->encryptedKey->length);
 
         if (!key) {
             CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (!kek_unwrap_key(key, &keylen,
                             pwri->encryptedKey->data,
                             pwri->encryptedKey->length, &kekctx)) {
             CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE);
             goto err;
         }
 
         ec->key = key;
         ec->keylen = keylen;
 
     }
 
     r = 1;
 
  err:
 
     EVP_CIPHER_CTX_cleanup(&kekctx);
 
     if (!r && key)
         OPENSSL_free(key);
     X509_ALGOR_free(kekalg);
 
     return r;
 
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/des/des.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/des/des.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/des/des.c	(revision 306191)
@@ -1,868 +1,868 @@
 /* crypto/des/des.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.]
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/opensslconf.h>
 #ifndef OPENSSL_SYS_MSDOS
 # ifndef OPENSSL_SYS_VMS
 #  include OPENSSL_UNISTD
 # else                          /* OPENSSL_SYS_VMS */
 #  ifdef __DECC
 #   include <unistd.h>
 #  else                         /* not __DECC */
 #   include <math.h>
 #  endif                        /* __DECC */
 # endif                         /* OPENSSL_SYS_VMS */
 #else                           /* OPENSSL_SYS_MSDOS */
 # include <io.h>
 #endif
 
 #include <time.h>
 #include "des_ver.h"
 
 #ifdef OPENSSL_SYS_VMS
 # include <types.h>
 # include <stat.h>
 #else
 # ifndef _IRIX
 #  include <sys/types.h>
 # endif
 # include <sys/stat.h>
 #endif
 #include <openssl/des.h>
 #include <openssl/rand.h>
 #include <openssl/ui_compat.h>
 
 void usage(void);
 void doencryption(void);
 int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp);
 void uufwriteEnd(FILE *fp);
 int uufread(unsigned char *out, int size, unsigned int num, FILE *fp);
 int uuencode(unsigned char *in, int num, unsigned char *out);
 int uudecode(unsigned char *in, int num, unsigned char *out);
 void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length,
                       DES_key_schedule sk1, DES_key_schedule sk2,
                       DES_cblock *ivec1, DES_cblock *ivec2, int enc);
 #ifdef OPENSSL_SYS_VMS
 # define EXIT(a) exit(a&0x10000000L)
 #else
 # define EXIT(a) exit(a)
 #endif
 
 #define BUFSIZE (8*1024)
 #define VERIFY  1
 #define KEYSIZ  8
 #define KEYSIZB 1024            /* should hit tty line limit first :-) */
 char key[KEYSIZB + 1];
 int do_encrypt, longk = 0;
 FILE *DES_IN, *DES_OUT, *CKSUM_OUT;
 char uuname[200];
 unsigned char uubuf[50];
 int uubufnum = 0;
 #define INUUBUFN        (45*100)
 #define OUTUUBUF        (65*100)
 unsigned char b[OUTUUBUF];
 unsigned char bb[300];
 DES_cblock cksum = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
 char cksumname[200] = "";
 
 int vflag, cflag, eflag, dflag, kflag, bflag, fflag, sflag, uflag, flag3,
     hflag, error;
 
 int main(int argc, char **argv)
 {
     int i;
     struct stat ins, outs;
     char *p;
     char *in = NULL, *out = NULL;
 
     vflag = cflag = eflag = dflag = kflag = hflag = bflag = fflag = sflag =
         uflag = flag3 = 0;
     error = 0;
     memset(key, 0, sizeof(key));
 
     for (i = 1; i < argc; i++) {
         p = argv[i];
         if ((p[0] == '-') && (p[1] != '\0')) {
             p++;
             while (*p) {
                 switch (*(p++)) {
                 case '3':
                     flag3 = 1;
                     longk = 1;
                     break;
                 case 'c':
                     cflag = 1;
                     strncpy(cksumname, p, 200);
                     cksumname[sizeof(cksumname) - 1] = '\0';
                     p += strlen(cksumname);
                     break;
                 case 'C':
                     cflag = 1;
                     longk = 1;
                     strncpy(cksumname, p, 200);
                     cksumname[sizeof(cksumname) - 1] = '\0';
                     p += strlen(cksumname);
                     break;
                 case 'e':
                     eflag = 1;
                     break;
                 case 'v':
                     vflag = 1;
                     break;
                 case 'E':
                     eflag = 1;
                     longk = 1;
                     break;
                 case 'd':
                     dflag = 1;
                     break;
                 case 'D':
                     dflag = 1;
                     longk = 1;
                     break;
                 case 'b':
                     bflag = 1;
                     break;
                 case 'f':
                     fflag = 1;
                     break;
                 case 's':
                     sflag = 1;
                     break;
                 case 'u':
                     uflag = 1;
                     strncpy(uuname, p, 200);
                     uuname[sizeof(uuname) - 1] = '\0';
                     p += strlen(uuname);
                     break;
                 case 'h':
                     hflag = 1;
                     break;
                 case 'k':
                     kflag = 1;
                     if ((i + 1) == argc) {
                         fputs("must have a key with the -k option\n", stderr);
                         error = 1;
                     } else {
                         int j;
 
                         i++;
                         strncpy(key, argv[i], KEYSIZB);
                         for (j = strlen(argv[i]) - 1; j >= 0; j--)
                             argv[i][j] = '\0';
                     }
                     break;
                 default:
                     fprintf(stderr, "'%c' unknown flag\n", p[-1]);
                     error = 1;
                     break;
                 }
             }
         } else {
             if (in == NULL)
                 in = argv[i];
             else if (out == NULL)
                 out = argv[i];
             else
                 error = 1;
         }
     }
     if (error)
         usage();
     /*-
      * We either
      * do checksum or
      * do encrypt or
      * do decrypt or
      * do decrypt then ckecksum or
      * do checksum then encrypt
      */
     if (((eflag + dflag) == 1) || cflag) {
         if (eflag)
             do_encrypt = DES_ENCRYPT;
         if (dflag)
             do_encrypt = DES_DECRYPT;
     } else {
         if (vflag) {
 #ifndef _Windows
             fprintf(stderr, "des(1) built with %s\n", libdes_version);
 #endif
             EXIT(1);
         } else
             usage();
     }
 
 #ifndef _Windows
     if (vflag)
         fprintf(stderr, "des(1) built with %s\n", libdes_version);
 #endif
     if ((in != NULL) && (out != NULL) &&
 #ifndef OPENSSL_SYS_MSDOS
         (stat(in, &ins) != -1) &&
         (stat(out, &outs) != -1) &&
         (ins.st_dev == outs.st_dev) && (ins.st_ino == outs.st_ino))
 #else                           /* OPENSSL_SYS_MSDOS */
         (strcmp(in, out) == 0))
 #endif
     {
         fputs("input and output file are the same\n", stderr);
         EXIT(3);
     }
 
     if (!kflag)
         if (des_read_pw_string
             (key, KEYSIZB + 1, "Enter key:", eflag ? VERIFY : 0)) {
             fputs("password error\n", stderr);
             EXIT(2);
         }
 
     if (in == NULL)
         DES_IN = stdin;
     else if ((DES_IN = fopen(in, "r")) == NULL) {
         perror("opening input file");
         EXIT(4);
     }
 
     CKSUM_OUT = stdout;
     if (out == NULL) {
         DES_OUT = stdout;
         CKSUM_OUT = stderr;
     } else if ((DES_OUT = fopen(out, "w")) == NULL) {
         perror("opening output file");
         EXIT(5);
     }
 #ifdef OPENSSL_SYS_MSDOS
     /* This should set the file to binary mode. */
     {
 # include <fcntl.h>
         if (!(uflag && dflag))
             setmode(fileno(DES_IN), O_BINARY);
         if (!(uflag && eflag))
             setmode(fileno(DES_OUT), O_BINARY);
     }
 #endif
 
     doencryption();
     fclose(DES_IN);
     fclose(DES_OUT);
     EXIT(0);
 }
 
 void usage(void)
 {
     char **u;
     static const char *Usage[] = {
         "des <options> [input-file [output-file]]",
         "options:",
         "-v         : des(1) version number",
         "-e         : encrypt using SunOS compatible user key to DES key conversion.",
         "-E         : encrypt ",
         "-d         : decrypt using SunOS compatible user key to DES key conversion.",
         "-D         : decrypt ",
         "-c[ckname] : generate a cbc_cksum using SunOS compatible user key to",
         "             DES key conversion and output to ckname (stdout default,",
         "             stderr if data being output on stdout).  The checksum is",
         "             generated before encryption and after decryption if used",
         "             in conjunction with -[eEdD].",
         "-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].",
         "-k key     : use key 'key'",
         "-h         : the key that is entered will be a hexadecimal number",
         "             that is used directly as the des key",
         "-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]",
         "             (uuname is the filename to put in the uuencode header).",
         "-b         : encrypt using DES in ecb encryption mode, the default is cbc mode.",
         "-3         : encrypt using triple DES encryption.  This uses 2 keys",
         "             generated from the input key.  If the input key is less",
         "             than 8 characters long, this is equivalent to normal",
         "             encryption.  Default is triple cbc, -b makes it triple ecb.",
         NULL
     };
     for (u = (char **)Usage; *u; u++) {
         fputs(*u, stderr);
         fputc('\n', stderr);
     }
 
     EXIT(1);
 }
 
 void doencryption(void)
 {
 #ifdef _LIBC
     extern unsigned long time();
 #endif
 
     register int i;
     DES_key_schedule ks, ks2;
     DES_cblock iv, iv2;
     char *p;
     int num = 0, j, k, l, rem, ll, len, last, ex = 0;
     DES_cblock kk, k2;
     FILE *O;
     int Exit = 0;
 #ifndef OPENSSL_SYS_MSDOS
     static unsigned char buf[BUFSIZE + 8], obuf[BUFSIZE + 8];
 #else
     static unsigned char *buf = NULL, *obuf = NULL;
 
     if (buf == NULL) {
         if (((buf = OPENSSL_malloc(BUFSIZE + 8)) == NULL) ||
             ((obuf = OPENSSL_malloc(BUFSIZE + 8)) == NULL)) {
             fputs("Not enough memory\n", stderr);
             Exit = 10;
             goto problems;
         }
     }
 #endif
 
     if (hflag) {
         j = (flag3 ? 16 : 8);
         p = key;
         for (i = 0; i < j; i++) {
             k = 0;
             if ((*p <= '9') && (*p >= '0'))
                 k = (*p - '0') << 4;
             else if ((*p <= 'f') && (*p >= 'a'))
                 k = (*p - 'a' + 10) << 4;
             else if ((*p <= 'F') && (*p >= 'A'))
                 k = (*p - 'A' + 10) << 4;
             else {
                 fputs("Bad hex key\n", stderr);
                 Exit = 9;
                 goto problems;
             }
             p++;
             if ((*p <= '9') && (*p >= '0'))
                 k |= (*p - '0');
             else if ((*p <= 'f') && (*p >= 'a'))
                 k |= (*p - 'a' + 10);
             else if ((*p <= 'F') && (*p >= 'A'))
                 k |= (*p - 'A' + 10);
             else {
                 fputs("Bad hex key\n", stderr);
                 Exit = 9;
                 goto problems;
             }
             p++;
             if (i < 8)
                 kk[i] = k;
             else
                 k2[i - 8] = k;
         }
         DES_set_key_unchecked(&k2, &ks2);
         OPENSSL_cleanse(k2, sizeof(k2));
     } else if (longk || flag3) {
         if (flag3) {
             DES_string_to_2keys(key, &kk, &k2);
             DES_set_key_unchecked(&k2, &ks2);
             OPENSSL_cleanse(k2, sizeof(k2));
         } else
             DES_string_to_key(key, &kk);
     } else
         for (i = 0; i < KEYSIZ; i++) {
             l = 0;
             k = key[i];
             for (j = 0; j < 8; j++) {
                 if (k & 1)
                     l++;
                 k >>= 1;
             }
             if (l & 1)
                 kk[i] = key[i] & 0x7f;
             else
                 kk[i] = key[i] | 0x80;
         }
 
     DES_set_key_unchecked(&kk, &ks);
     OPENSSL_cleanse(key, sizeof(key));
     OPENSSL_cleanse(kk, sizeof(kk));
     /* woops - A bug that does not showup under unix :-( */
     memset(iv, 0, sizeof(iv));
     memset(iv2, 0, sizeof(iv2));
 
     l = 1;
     rem = 0;
     /* first read */
     if (eflag || (!dflag && cflag)) {
         for (;;) {
             num = l = fread(&(buf[rem]), 1, BUFSIZE, DES_IN);
             l += rem;
             num += rem;
             if (l < 0) {
                 perror("read error");
                 Exit = 6;
                 goto problems;
             }
 
             rem = l % 8;
             len = l - rem;
             if (feof(DES_IN)) {
                 for (i = 7 - rem; i > 0; i--) {
-                    if (RAND_pseudo_bytes(buf + l++, 1) < 0)
+                    if (RAND_bytes(buf + l++, 1) <= 0)
                         goto problems;
                 }
                 buf[l++] = rem;
                 ex = 1;
                 len += rem;
             } else
                 l -= rem;
 
             if (cflag) {
                 DES_cbc_cksum(buf, &cksum, (long)len, &ks, &cksum);
                 if (!eflag) {
                     if (feof(DES_IN))
                         break;
                     else
                         continue;
                 }
             }
 
             if (bflag && !flag3)
                 for (i = 0; i < l; i += 8)
                     DES_ecb_encrypt((DES_cblock *)&(buf[i]),
                                     (DES_cblock *)&(obuf[i]),
                                     &ks, do_encrypt);
             else if (flag3 && bflag)
                 for (i = 0; i < l; i += 8)
                     DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
                                      (DES_cblock *)&(obuf[i]),
                                      &ks, &ks2, do_encrypt);
             else if (flag3 && !bflag) {
                 char tmpbuf[8];
 
                 if (rem)
                     memcpy(tmpbuf, &(buf[l]), (unsigned int)rem);
                 DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
                                  (long)l, ks, ks2, &iv, &iv2, do_encrypt);
                 if (rem)
                     memcpy(&(buf[l]), tmpbuf, (unsigned int)rem);
             } else {
                 DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
                 if (l >= 8)
                     memcpy(iv, &(obuf[l - 8]), 8);
             }
             if (rem)
                 memcpy(buf, &(buf[l]), (unsigned int)rem);
 
             i = 0;
             while (i < l) {
                 if (uflag)
                     j = uufwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
                 else
                     j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
                 if (j == -1) {
                     perror("Write error");
                     Exit = 7;
                     goto problems;
                 }
                 i += j;
             }
             if (feof(DES_IN)) {
                 if (uflag)
                     uufwriteEnd(DES_OUT);
                 break;
             }
         }
     } else {                    /* decrypt */
 
         ex = 1;
         for (;;) {
             if (ex) {
                 if (uflag)
                     l = uufread(buf, 1, BUFSIZE, DES_IN);
                 else
                     l = fread(buf, 1, BUFSIZE, DES_IN);
                 ex = 0;
                 rem = l % 8;
                 l -= rem;
             }
             if (l < 0) {
                 perror("read error");
                 Exit = 6;
                 goto problems;
             }
 
             if (bflag && !flag3)
                 for (i = 0; i < l; i += 8)
                     DES_ecb_encrypt((DES_cblock *)&(buf[i]),
                                     (DES_cblock *)&(obuf[i]),
                                     &ks, do_encrypt);
             else if (flag3 && bflag)
                 for (i = 0; i < l; i += 8)
                     DES_ecb2_encrypt((DES_cblock *)&(buf[i]),
                                      (DES_cblock *)&(obuf[i]),
                                      &ks, &ks2, do_encrypt);
             else if (flag3 && !bflag) {
                 DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf,
                                  (long)l, ks, ks2, &iv, &iv2, do_encrypt);
             } else {
                 DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt);
                 if (l >= 8)
                     memcpy(iv, &(buf[l - 8]), 8);
             }
 
             if (uflag)
                 ll = uufread(&(buf[rem]), 1, BUFSIZE, DES_IN);
             else
                 ll = fread(&(buf[rem]), 1, BUFSIZE, DES_IN);
             ll += rem;
             rem = ll % 8;
             ll -= rem;
             if (feof(DES_IN) && (ll == 0)) {
                 last = obuf[l - 1];
 
                 if ((last > 7) || (last < 0)) {
                     fputs("The file was not decrypted correctly.\n", stderr);
                     Exit = 8;
                     last = 0;
                 }
                 l = l - 8 + last;
             }
             i = 0;
             if (cflag)
                 DES_cbc_cksum(obuf,
                               (DES_cblock *)cksum, (long)l / 8 * 8, &ks,
                               (DES_cblock *)cksum);
             while (i != l) {
                 j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT);
                 if (j == -1) {
                     perror("Write error");
                     Exit = 7;
                     goto problems;
                 }
                 i += j;
             }
             l = ll;
             if ((l == 0) && feof(DES_IN))
                 break;
         }
     }
     if (cflag) {
         l = 0;
         if (cksumname[0] != '\0') {
             if ((O = fopen(cksumname, "w")) != NULL) {
                 CKSUM_OUT = O;
                 l = 1;
             }
         }
         for (i = 0; i < 8; i++)
             fprintf(CKSUM_OUT, "%02X", cksum[i]);
         fprintf(CKSUM_OUT, "\n");
         if (l)
             fclose(CKSUM_OUT);
     }
  problems:
     OPENSSL_cleanse(buf, sizeof(buf));
     OPENSSL_cleanse(obuf, sizeof(obuf));
     OPENSSL_cleanse(&ks, sizeof(ks));
     OPENSSL_cleanse(&ks2, sizeof(ks2));
     OPENSSL_cleanse(iv, sizeof(iv));
     OPENSSL_cleanse(iv2, sizeof(iv2));
     OPENSSL_cleanse(kk, sizeof(kk));
     OPENSSL_cleanse(k2, sizeof(k2));
     OPENSSL_cleanse(uubuf, sizeof(uubuf));
     OPENSSL_cleanse(b, sizeof(b));
     OPENSSL_cleanse(bb, sizeof(bb));
     OPENSSL_cleanse(cksum, sizeof(cksum));
     if (Exit)
         EXIT(Exit);
 }
 
 /*    We ignore this parameter but it should be > ~50 I believe    */
 int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp)
 {
     int i, j, left, rem, ret = num;
     static int start = 1;
 
     if (start) {
         fprintf(fp, "begin 600 %s\n",
                 (uuname[0] == '\0') ? "text.d" : uuname);
         start = 0;
     }
 
     if (uubufnum) {
         if (uubufnum + num < 45) {
             memcpy(&(uubuf[uubufnum]), data, (unsigned int)num);
             uubufnum += num;
             return (num);
         } else {
             i = 45 - uubufnum;
             memcpy(&(uubuf[uubufnum]), data, (unsigned int)i);
             j = uuencode((unsigned char *)uubuf, 45, b);
             fwrite(b, 1, (unsigned int)j, fp);
             uubufnum = 0;
             data += i;
             num -= i;
         }
     }
 
     for (i = 0; i < (((int)num) - INUUBUFN); i += INUUBUFN) {
         j = uuencode(&(data[i]), INUUBUFN, b);
         fwrite(b, 1, (unsigned int)j, fp);
     }
     rem = (num - i) % 45;
     left = (num - i - rem);
     if (left) {
         j = uuencode(&(data[i]), left, b);
         fwrite(b, 1, (unsigned int)j, fp);
         i += left;
     }
     if (i != num) {
         memcpy(uubuf, &(data[i]), (unsigned int)rem);
         uubufnum = rem;
     }
     return (ret);
 }
 
 void uufwriteEnd(FILE *fp)
 {
     int j;
     static const char *end = " \nend\n";
 
     if (uubufnum != 0) {
         uubuf[uubufnum] = '\0';
         uubuf[uubufnum + 1] = '\0';
         uubuf[uubufnum + 2] = '\0';
         j = uuencode(uubuf, uubufnum, b);
         fwrite(b, 1, (unsigned int)j, fp);
     }
     fwrite(end, 1, strlen(end), fp);
 }
 
 /*
  * int size: should always be > ~ 60; I actually ignore this parameter :-)
  */
 int uufread(unsigned char *out, int size, unsigned int num, FILE *fp)
 {
     int i, j, tot;
     static int done = 0;
     static int valid = 0;
     static int start = 1;
 
     if (start) {
         for (;;) {
             b[0] = '\0';
             fgets((char *)b, 300, fp);
             if (b[0] == '\0') {
                 fprintf(stderr, "no 'begin' found in uuencoded input\n");
                 return (-1);
             }
             if (strncmp((char *)b, "begin ", 6) == 0)
                 break;
         }
         start = 0;
     }
     if (done)
         return (0);
     tot = 0;
     if (valid) {
         memcpy(out, bb, (unsigned int)valid);
         tot = valid;
         valid = 0;
     }
     for (;;) {
         b[0] = '\0';
         fgets((char *)b, 300, fp);
         if (b[0] == '\0')
             break;
         i = strlen((char *)b);
         if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd')) {
             done = 1;
             while (!feof(fp)) {
                 fgets((char *)b, 300, fp);
             }
             break;
         }
         i = uudecode(b, i, bb);
         if (i < 0)
             break;
         if ((i + tot + 8) > num) {
             /* num to copy to make it a multiple of 8 */
             j = (num / 8 * 8) - tot - 8;
             memcpy(&(out[tot]), bb, (unsigned int)j);
             tot += j;
             memcpy(bb, &(bb[j]), (unsigned int)i - j);
             valid = i - j;
             break;
         }
         memcpy(&(out[tot]), bb, (unsigned int)i);
         tot += i;
     }
     return (tot);
 }
 
 #define ccc2l(c,l)      (l =((DES_LONG)(*((c)++)))<<16, \
                          l|=((DES_LONG)(*((c)++)))<< 8, \
                          l|=((DES_LONG)(*((c)++))))
 
 #define l2ccc(l,c)      (*((c)++)=(unsigned char)(((l)>>16)&0xff), \
                     *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                     *((c)++)=(unsigned char)(((l)    )&0xff))
 
 int uuencode(unsigned char *in, int num, unsigned char *out)
 {
     int j, i, n, tot = 0;
     DES_LONG l;
     register unsigned char *p;
     p = out;
 
     for (j = 0; j < num; j += 45) {
         if (j + 45 > num)
             i = (num - j);
         else
             i = 45;
         *(p++) = i + ' ';
         for (n = 0; n < i; n += 3) {
             ccc2l(in, l);
             *(p++) = ((l >> 18) & 0x3f) + ' ';
             *(p++) = ((l >> 12) & 0x3f) + ' ';
             *(p++) = ((l >> 6) & 0x3f) + ' ';
             *(p++) = ((l) & 0x3f) + ' ';
             tot += 4;
         }
         *(p++) = '\n';
         tot += 2;
     }
     *p = '\0';
     l = 0;
     return (tot);
 }
 
 int uudecode(unsigned char *in, int num, unsigned char *out)
 {
     int j, i, k;
     unsigned int n = 0, space = 0;
     DES_LONG l;
     DES_LONG w, x, y, z;
     unsigned int blank = (unsigned int)'\n' - ' ';
 
     for (j = 0; j < num;) {
         n = *(in++) - ' ';
         if (n == blank) {
             n = 0;
             in--;
         }
         if (n > 60) {
             fprintf(stderr, "uuencoded line length too long\n");
             return (-1);
         }
         j++;
 
         for (i = 0; i < n; j += 4, i += 3) {
             /*
              * the following is for cases where spaces are removed from
              * lines.
              */
             if (space) {
                 w = x = y = z = 0;
             } else {
                 w = *(in++) - ' ';
                 x = *(in++) - ' ';
                 y = *(in++) - ' ';
                 z = *(in++) - ' ';
             }
             if ((w > 63) || (x > 63) || (y > 63) || (z > 63)) {
                 k = 0;
                 if (w == blank)
                     k = 1;
                 if (x == blank)
                     k = 2;
                 if (y == blank)
                     k = 3;
                 if (z == blank)
                     k = 4;
                 space = 1;
                 switch (k) {
                 case 1:
                     w = 0;
                     in--;
                 case 2:
                     x = 0;
                     in--;
                 case 3:
                     y = 0;
                     in--;
                 case 4:
                     z = 0;
                     in--;
                     break;
                 case 0:
                     space = 0;
                     fprintf(stderr, "bad uuencoded data values\n");
                     w = x = y = z = 0;
                     return (-1);
                     break;
                 }
             }
             l = (w << 18) | (x << 12) | (y << 6) | (z);
             l2ccc(l, out);
         }
         if (*(in++) != '\n') {
             fprintf(stderr, "missing nl in uuencoded line\n");
             w = x = y = z = 0;
             return (-1);
         }
         j++;
     }
     *out = '\0';
     w = x = y = z = 0;
     return (n);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/des/enc_writ.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/des/enc_writ.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/des/enc_writ.c	(revision 306191)
@@ -1,182 +1,182 @@
 /* crypto/des/enc_writ.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.]
  */
 
 #include <errno.h>
 #include <time.h>
 #include <stdio.h>
 #include "cryptlib.h"
 #include "des_locl.h"
 #include <openssl/rand.h>
 
 /*-
  * WARNINGS:
  *
  *  -  The data format used by DES_enc_write() and DES_enc_read()
  *     has a cryptographic weakness: When asked to write more
  *     than MAXWRITE bytes, DES_enc_write will split the data
  *     into several chunks that are all encrypted
  *     using the same IV.  So don't use these functions unless you
  *     are sure you know what you do (in which case you might
  *     not want to use them anyway).
  *
  *  -  This code cannot handle non-blocking sockets.
  */
 
 int DES_enc_write(int fd, const void *_buf, int len,
                   DES_key_schedule *sched, DES_cblock *iv)
 {
 #if defined(OPENSSL_NO_POSIX_IO)
     return (-1);
 #else
 # ifdef _LIBC
     extern unsigned long time();
     extern int write();
 # endif
     const unsigned char *buf = _buf;
     long rnum;
     int i, j, k, outnum;
     static unsigned char *outbuf = NULL;
     unsigned char shortbuf[8];
     unsigned char *p;
     const unsigned char *cp;
     static int start = 1;
 
     if (len < 0)
         return -1;
 
     if (outbuf == NULL) {
         outbuf = OPENSSL_malloc(BSIZE + HDRSIZE);
         if (outbuf == NULL)
             return (-1);
     }
     /*
      * If we are sending less than 8 bytes, the same char will look the same
      * if we don't pad it out with random bytes
      */
     if (start) {
         start = 0;
     }
 
     /* lets recurse if we want to send the data in small chunks */
     if (len > MAXWRITE) {
         j = 0;
         for (i = 0; i < len; i += k) {
             k = DES_enc_write(fd, &(buf[i]),
                               ((len - i) > MAXWRITE) ? MAXWRITE : (len - i),
                               sched, iv);
             if (k < 0)
                 return (k);
             else
                 j += k;
         }
         return (j);
     }
 
     /* write length first */
     p = outbuf;
     l2n(len, p);
 
     /* pad short strings */
     if (len < 8) {
         cp = shortbuf;
         memcpy(shortbuf, buf, len);
-        if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) {
+        if (RAND_bytes(shortbuf + len, 8 - len) <= 0) {
             return -1;
         }
         rnum = 8;
     } else {
         cp = buf;
         rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */
     }
 
     if (DES_rw_mode & DES_PCBC_MODE)
         DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
                          iv, DES_ENCRYPT);
     else
         DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched,
                         iv, DES_ENCRYPT);
 
     /* output */
     outnum = rnum + HDRSIZE;
 
     for (j = 0; j < outnum; j += i) {
         /*
          * eay 26/08/92 I was not doing writing from where we got up to.
          */
 # ifndef _WIN32
         i = write(fd, (void *)&(outbuf[j]), outnum - j);
 # else
         i = _write(fd, (void *)&(outbuf[j]), outnum - j);
 # endif
         if (i == -1) {
 # ifdef EINTR
             if (errno == EINTR)
                 i = 0;
             else
 # endif
                 /*
                  * This is really a bad error - very bad It will stuff-up
                  * both ends.
                  */
                 return (-1);
         }
     }
 
     return (len);
 #endif                          /* OPENSSL_NO_POSIX_IO */
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_gen.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_gen.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_gen.c	(revision 306191)
@@ -1,379 +1,379 @@
 /* crypto/dsa/dsa_gen.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.]
  */
 
 #undef GENUINE_DSA
 
 #ifdef GENUINE_DSA
 /*
  * Parameter generation follows the original release of FIPS PUB 186,
  * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180)
  */
 # define HASH    EVP_sha()
 #else
 /*
  * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186,
  * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB
  * 180-1)
  */
 # define HASH    EVP_sha1()
 #endif
 
 #include <openssl/opensslconf.h> /* To see if OPENSSL_NO_SHA is defined */
 
 #ifndef OPENSSL_NO_SHA
 
 # include <stdio.h>
 # include "cryptlib.h"
 # include <openssl/evp.h>
 # include <openssl/bn.h>
 # include <openssl/rand.h>
 # include <openssl/sha.h>
 # include "dsa_locl.h"
 
 # ifdef OPENSSL_FIPS
 #  include <openssl/fips.h>
 # endif
 
 int DSA_generate_parameters_ex(DSA *ret, int bits,
                                const unsigned char *seed_in, int seed_len,
                                int *counter_ret, unsigned long *h_ret,
                                BN_GENCB *cb)
 {
 # ifdef OPENSSL_FIPS
     if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD)
         && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) {
         DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD);
         return 0;
     }
 # endif
     if (ret->meth->dsa_paramgen)
         return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len,
                                        counter_ret, h_ret, cb);
 # ifdef OPENSSL_FIPS
     else if (FIPS_mode()) {
         return FIPS_dsa_generate_parameters_ex(ret, bits,
                                                seed_in, seed_len,
                                                counter_ret, h_ret, cb);
     }
 # endif
     else {
         const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1();
         size_t qbits = EVP_MD_size(evpmd) * 8;
 
         return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
                                     seed_in, seed_len, NULL, counter_ret,
                                     h_ret, cb);
     }
 }
 
 int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
                          const EVP_MD *evpmd, const unsigned char *seed_in,
                          size_t seed_len, unsigned char *seed_out,
                          int *counter_ret, unsigned long *h_ret, BN_GENCB *cb)
 {
     int ok = 0;
     unsigned char seed[SHA256_DIGEST_LENGTH];
     unsigned char md[SHA256_DIGEST_LENGTH];
     unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH];
     BIGNUM *r0, *W, *X, *c, *test;
     BIGNUM *g = NULL, *q = NULL, *p = NULL;
     BN_MONT_CTX *mont = NULL;
     int i, k, n = 0, m = 0, qsize = qbits >> 3;
     int counter = 0;
     int r = 0;
     BN_CTX *ctx = NULL;
     unsigned int h = 2;
 
     if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH &&
         qsize != SHA256_DIGEST_LENGTH)
         /* invalid q size */
         return 0;
 
     if (evpmd == NULL)
         /* use SHA1 as default */
         evpmd = EVP_sha1();
 
     if (bits < 512)
         bits = 512;
 
     bits = (bits + 63) / 64 * 64;
 
     /*
      * NB: seed_len == 0 is special case: copy generated seed to seed_in if
      * it is not NULL.
      */
     if (seed_len && (seed_len < (size_t)qsize))
         seed_in = NULL;         /* seed buffer too small -- ignore */
     if (seed_len > (size_t)qsize)
         seed_len = qsize;       /* App. 2.2 of FIPS PUB 186 allows larger
                                  * SEED, but our internal buffers are
                                  * restricted to 160 bits */
     if (seed_in != NULL)
         memcpy(seed, seed_in, seed_len);
 
     if ((mont = BN_MONT_CTX_new()) == NULL)
         goto err;
 
     if ((ctx = BN_CTX_new()) == NULL)
         goto err;
 
     BN_CTX_start(ctx);
 
     r0 = BN_CTX_get(ctx);
     g = BN_CTX_get(ctx);
     W = BN_CTX_get(ctx);
     q = BN_CTX_get(ctx);
     X = BN_CTX_get(ctx);
     c = BN_CTX_get(ctx);
     p = BN_CTX_get(ctx);
     test = BN_CTX_get(ctx);
 
     if (!BN_lshift(test, BN_value_one(), bits - 1))
         goto err;
 
     for (;;) {
         for (;;) {              /* find q */
             int seed_is_random;
 
             /* step 1 */
             if (!BN_GENCB_call(cb, 0, m++))
                 goto err;
 
             if (!seed_len || !seed_in) {
-                if (RAND_pseudo_bytes(seed, qsize) < 0)
+                if (RAND_bytes(seed, qsize) <= 0)
                     goto err;
                 seed_is_random = 1;
             } else {
                 seed_is_random = 0;
                 seed_len = 0;   /* use random seed if 'seed_in' turns out to
                                  * be bad */
             }
             memcpy(buf, seed, qsize);
             memcpy(buf2, seed, qsize);
             /* precompute "SEED + 1" for step 7: */
             for (i = qsize - 1; i >= 0; i--) {
                 buf[i]++;
                 if (buf[i] != 0)
                     break;
             }
 
             /* step 2 */
             if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL))
                 goto err;
             if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL))
                 goto err;
             for (i = 0; i < qsize; i++)
                 md[i] ^= buf2[i];
 
             /* step 3 */
             md[0] |= 0x80;
             md[qsize - 1] |= 0x01;
             if (!BN_bin2bn(md, qsize, q))
                 goto err;
 
             /* step 4 */
             r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx,
                                         seed_is_random, cb);
             if (r > 0)
                 break;
             if (r != 0)
                 goto err;
 
             /* do a callback call */
             /* step 5 */
         }
 
         if (!BN_GENCB_call(cb, 2, 0))
             goto err;
         if (!BN_GENCB_call(cb, 3, 0))
             goto err;
 
         /* step 6 */
         counter = 0;
         /* "offset = 2" */
 
         n = (bits - 1) / 160;
 
         for (;;) {
             if ((counter != 0) && !BN_GENCB_call(cb, 0, counter))
                 goto err;
 
             /* step 7 */
             BN_zero(W);
             /* now 'buf' contains "SEED + offset - 1" */
             for (k = 0; k <= n; k++) {
                 /*
                  * obtain "SEED + offset + k" by incrementing:
                  */
                 for (i = qsize - 1; i >= 0; i--) {
                     buf[i]++;
                     if (buf[i] != 0)
                         break;
                 }
 
                 if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL))
                     goto err;
 
                 /* step 8 */
                 if (!BN_bin2bn(md, qsize, r0))
                     goto err;
                 if (!BN_lshift(r0, r0, (qsize << 3) * k))
                     goto err;
                 if (!BN_add(W, W, r0))
                     goto err;
             }
 
             /* more of step 8 */
             if (!BN_mask_bits(W, bits - 1))
                 goto err;
             if (!BN_copy(X, W))
                 goto err;
             if (!BN_add(X, X, test))
                 goto err;
 
             /* step 9 */
             if (!BN_lshift1(r0, q))
                 goto err;
             if (!BN_mod(c, X, r0, ctx))
                 goto err;
             if (!BN_sub(r0, c, BN_value_one()))
                 goto err;
             if (!BN_sub(p, X, r0))
                 goto err;
 
             /* step 10 */
             if (BN_cmp(p, test) >= 0) {
                 /* step 11 */
                 r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb);
                 if (r > 0)
                     goto end;   /* found it */
                 if (r != 0)
                     goto err;
             }
 
             /* step 13 */
             counter++;
             /* "offset = offset + n + 1" */
 
             /* step 14 */
             if (counter >= 4096)
                 break;
         }
     }
  end:
     if (!BN_GENCB_call(cb, 2, 1))
         goto err;
 
     /* We now need to generate g */
     /* Set r0=(p-1)/q */
     if (!BN_sub(test, p, BN_value_one()))
         goto err;
     if (!BN_div(r0, NULL, test, q, ctx))
         goto err;
 
     if (!BN_set_word(test, h))
         goto err;
     if (!BN_MONT_CTX_set(mont, p, ctx))
         goto err;
 
     for (;;) {
         /* g=test^r0%p */
         if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont))
             goto err;
         if (!BN_is_one(g))
             break;
         if (!BN_add(test, test, BN_value_one()))
             goto err;
         h++;
     }
 
     if (!BN_GENCB_call(cb, 3, 1))
         goto err;
 
     ok = 1;
  err:
     if (ok) {
         if (ret->p)
             BN_free(ret->p);
         if (ret->q)
             BN_free(ret->q);
         if (ret->g)
             BN_free(ret->g);
         ret->p = BN_dup(p);
         ret->q = BN_dup(q);
         ret->g = BN_dup(g);
         if (ret->p == NULL || ret->q == NULL || ret->g == NULL) {
             ok = 0;
             goto err;
         }
         if (counter_ret != NULL)
             *counter_ret = counter;
         if (h_ret != NULL)
             *h_ret = h;
         if (seed_out)
             memcpy(seed_out, seed, qsize);
     }
     if (ctx) {
         BN_CTX_end(ctx);
         BN_CTX_free(ctx);
     }
     if (mont != NULL)
         BN_MONT_CTX_free(mont);
     return ok;
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_ossl.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_ossl.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/dsa/dsa_ossl.c	(revision 306191)
@@ -1,426 +1,431 @@
 /* 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;
     int noredo = 0;
 
     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;
  redo:
     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;
         noredo = 1;
     }
 
     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;
 
     /*
      * Redo if r or s is zero as required by FIPS 186-3: this is very
      * unlikely.
      */
     if (BN_is_zero(r) || BN_is_zero(s)) {
         if (noredo) {
             reason = DSA_R_NEED_NEW_SETUP_VALUES;
             goto err;
         }
         goto redo;
     }
     ret = DSA_SIG_new();
     if (ret == NULL)
         goto err;
     ret->r = r;
     ret->s = s;
 
  err:
     if (ret == NULL) {
         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)) ;
+    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;
 
+        BN_set_flags(&kq, BN_FLG_CONSTTIME);
+
         /*
          * 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);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/evp/bio_ok.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/evp/bio_ok.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/evp/bio_ok.c	(revision 306191)
@@ -1,624 +1,624 @@
 /* crypto/evp/bio_ok.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.]
  */
 
 /*-
         From: Arne Ansper <arne@cyber.ee>
 
         Why BIO_f_reliable?
 
         I wrote function which took BIO* as argument, read data from it
         and processed it. Then I wanted to store the input file in
         encrypted form. OK I pushed BIO_f_cipher to the BIO stack
         and everything was OK. BUT if user types wrong password
         BIO_f_cipher outputs only garbage and my function crashes. Yes
         I can and I should fix my function, but BIO_f_cipher is
         easy way to add encryption support to many existing applications
         and it's hard to debug and fix them all.
 
         So I wanted another BIO which would catch the incorrect passwords and
         file damages which cause garbage on BIO_f_cipher's output.
 
         The easy way is to push the BIO_f_md and save the checksum at
         the end of the file. However there are several problems with this
         approach:
 
         1) you must somehow separate checksum from actual data.
         2) you need lot's of memory when reading the file, because you
         must read to the end of the file and verify the checksum before
         letting the application to read the data.
 
         BIO_f_reliable tries to solve both problems, so that you can
         read and write arbitrary long streams using only fixed amount
         of memory.
 
         BIO_f_reliable splits data stream into blocks. Each block is prefixed
         with it's length and suffixed with it's digest. So you need only
         several Kbytes of memory to buffer single block before verifying
         it's digest.
 
         BIO_f_reliable goes further and adds several important capabilities:
 
         1) the digest of the block is computed over the whole stream
         -- so nobody can rearrange the blocks or remove or replace them.
 
         2) to detect invalid passwords right at the start BIO_f_reliable
         adds special prefix to the stream. In order to avoid known plain-text
         attacks this prefix is generated as follows:
 
                 *) digest is initialized with random seed instead of
                 standardized one.
                 *) same seed is written to output
                 *) well-known text is then hashed and the output
                 of the digest is also written to output.
 
         reader can now read the seed from stream, hash the same string
         and then compare the digest output.
 
         Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I
         initially wrote and tested this code on x86 machine and wrote the
         digests out in machine-dependent order :( There are people using
         this code and I cannot change this easily without making existing
         data files unreadable.
 
 */
 
 #include <stdio.h>
 #include <errno.h>
 #include <assert.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 
 static int ok_write(BIO *h, const char *buf, int num);
 static int ok_read(BIO *h, char *buf, int size);
 static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2);
 static int ok_new(BIO *h);
 static int ok_free(BIO *data);
 static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
 
 static int sig_out(BIO *b);
 static int sig_in(BIO *b);
 static int block_out(BIO *b);
 static int block_in(BIO *b);
 #define OK_BLOCK_SIZE   (1024*4)
 #define OK_BLOCK_BLOCK  4
 #define IOBS            (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE)
 #define WELLKNOWN "The quick brown fox jumped over the lazy dog's back."
 
 typedef struct ok_struct {
     size_t buf_len;
     size_t buf_off;
     size_t buf_len_save;
     size_t buf_off_save;
     int cont;                   /* <= 0 when finished */
     int finished;
     EVP_MD_CTX md;
     int blockout;               /* output block is ready */
     int sigio;                  /* must process signature */
     unsigned char buf[IOBS];
 } BIO_OK_CTX;
 
 static BIO_METHOD methods_ok = {
     BIO_TYPE_CIPHER, "reliable",
     ok_write,
     ok_read,
     NULL,                       /* ok_puts, */
     NULL,                       /* ok_gets, */
     ok_ctrl,
     ok_new,
     ok_free,
     ok_callback_ctrl,
 };
 
 BIO_METHOD *BIO_f_reliable(void)
 {
     return (&methods_ok);
 }
 
 static int ok_new(BIO *bi)
 {
     BIO_OK_CTX *ctx;
 
     ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX));
     if (ctx == NULL)
         return (0);
 
     ctx->buf_len = 0;
     ctx->buf_off = 0;
     ctx->buf_len_save = 0;
     ctx->buf_off_save = 0;
     ctx->cont = 1;
     ctx->finished = 0;
     ctx->blockout = 0;
     ctx->sigio = 1;
 
     EVP_MD_CTX_init(&ctx->md);
 
     bi->init = 0;
     bi->ptr = (char *)ctx;
     bi->flags = 0;
     return (1);
 }
 
 static int ok_free(BIO *a)
 {
     if (a == NULL)
         return (0);
     EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md);
     OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX));
     OPENSSL_free(a->ptr);
     a->ptr = NULL;
     a->init = 0;
     a->flags = 0;
     return (1);
 }
 
 static int ok_read(BIO *b, char *out, int outl)
 {
     int ret = 0, i, n;
     BIO_OK_CTX *ctx;
 
     if (out == NULL)
         return (0);
     ctx = (BIO_OK_CTX *)b->ptr;
 
     if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
         return (0);
 
     while (outl > 0) {
 
         /* copy clean bytes to output buffer */
         if (ctx->blockout) {
             i = ctx->buf_len - ctx->buf_off;
             if (i > outl)
                 i = outl;
             memcpy(out, &(ctx->buf[ctx->buf_off]), i);
             ret += i;
             out += i;
             outl -= i;
             ctx->buf_off += i;
 
             /* all clean bytes are out */
             if (ctx->buf_len == ctx->buf_off) {
                 ctx->buf_off = 0;
 
                 /*
                  * copy start of the next block into proper place
                  */
                 if (ctx->buf_len_save - ctx->buf_off_save > 0) {
                     ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save;
                     memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]),
                             ctx->buf_len);
                 } else {
                     ctx->buf_len = 0;
                 }
                 ctx->blockout = 0;
             }
         }
 
         /* output buffer full -- cancel */
         if (outl == 0)
             break;
 
         /* no clean bytes in buffer -- fill it */
         n = IOBS - ctx->buf_len;
         i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n);
 
         if (i <= 0)
             break;              /* nothing new */
 
         ctx->buf_len += i;
 
         /* no signature yet -- check if we got one */
         if (ctx->sigio == 1) {
             if (!sig_in(b)) {
                 BIO_clear_retry_flags(b);
                 return 0;
             }
         }
 
         /* signature ok -- check if we got block */
         if (ctx->sigio == 0) {
             if (!block_in(b)) {
                 BIO_clear_retry_flags(b);
                 return 0;
             }
         }
 
         /* invalid block -- cancel */
         if (ctx->cont <= 0)
             break;
 
     }
 
     BIO_clear_retry_flags(b);
     BIO_copy_next_retry(b);
     return (ret);
 }
 
 static int ok_write(BIO *b, const char *in, int inl)
 {
     int ret = 0, n, i;
     BIO_OK_CTX *ctx;
 
     if (inl <= 0)
         return inl;
 
     ctx = (BIO_OK_CTX *)b->ptr;
     ret = inl;
 
     if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0))
         return (0);
 
     if (ctx->sigio && !sig_out(b))
         return 0;
 
     do {
         BIO_clear_retry_flags(b);
         n = ctx->buf_len - ctx->buf_off;
         while (ctx->blockout && n > 0) {
             i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
             if (i <= 0) {
                 BIO_copy_next_retry(b);
                 if (!BIO_should_retry(b))
                     ctx->cont = 0;
                 return (i);
             }
             ctx->buf_off += i;
             n -= i;
         }
 
         /* at this point all pending data has been written */
         ctx->blockout = 0;
         if (ctx->buf_len == ctx->buf_off) {
             ctx->buf_len = OK_BLOCK_BLOCK;
             ctx->buf_off = 0;
         }
 
         if ((in == NULL) || (inl <= 0))
             return (0);
 
         n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ?
             (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl;
 
         memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])),
                (unsigned char *)in, n);
         ctx->buf_len += n;
         inl -= n;
         in += n;
 
         if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) {
             if (!block_out(b)) {
                 BIO_clear_retry_flags(b);
                 return 0;
             }
         }
     } while (inl > 0);
 
     BIO_clear_retry_flags(b);
     BIO_copy_next_retry(b);
     return (ret);
 }
 
 static long ok_ctrl(BIO *b, int cmd, long num, void *ptr)
 {
     BIO_OK_CTX *ctx;
     EVP_MD *md;
     const EVP_MD **ppmd;
     long ret = 1;
     int i;
 
     ctx = b->ptr;
 
     switch (cmd) {
     case BIO_CTRL_RESET:
         ctx->buf_len = 0;
         ctx->buf_off = 0;
         ctx->buf_len_save = 0;
         ctx->buf_off_save = 0;
         ctx->cont = 1;
         ctx->finished = 0;
         ctx->blockout = 0;
         ctx->sigio = 1;
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     case BIO_CTRL_EOF:         /* More to read */
         if (ctx->cont <= 0)
             ret = 1;
         else
             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     case BIO_CTRL_PENDING:     /* More to read in buffer */
     case BIO_CTRL_WPENDING:    /* More to read in buffer */
         ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0;
         if (ret <= 0)
             ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     case BIO_CTRL_FLUSH:
         /* do a final write */
         if (ctx->blockout == 0)
             if (!block_out(b))
                 return 0;
 
         while (ctx->blockout) {
             i = ok_write(b, NULL, 0);
             if (i < 0) {
                 ret = i;
                 break;
             }
         }
 
         ctx->finished = 1;
         ctx->buf_off = ctx->buf_len = 0;
         ctx->cont = (int)ret;
 
         /* Finally flush the underlying BIO */
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     case BIO_C_DO_STATE_MACHINE:
         BIO_clear_retry_flags(b);
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         BIO_copy_next_retry(b);
         break;
     case BIO_CTRL_INFO:
         ret = (long)ctx->cont;
         break;
     case BIO_C_SET_MD:
         md = ptr;
         if (!EVP_DigestInit_ex(&ctx->md, md, NULL))
             return 0;
         b->init = 1;
         break;
     case BIO_C_GET_MD:
         if (b->init) {
             ppmd = ptr;
             *ppmd = ctx->md.digest;
         } else
             ret = 0;
         break;
     default:
         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
         break;
     }
     return (ret);
 }
 
 static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
 {
     long ret = 1;
 
     if (b->next_bio == NULL)
         return (0);
     switch (cmd) {
     default:
         ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
         break;
     }
     return (ret);
 }
 
 static void longswap(void *_ptr, size_t len)
 {
     const union {
         long one;
         char little;
     } is_endian = {
         1
     };
 
     if (is_endian.little) {
         size_t i;
         unsigned char *p = _ptr, c;
 
         for (i = 0; i < len; i += 4) {
             c = p[0], p[0] = p[3], p[3] = c;
             c = p[1], p[1] = p[2], p[2] = c;
         }
     }
 }
 
 static int sig_out(BIO *b)
 {
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
 
     ctx = b->ptr;
     md = &ctx->md;
 
     if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE)
         return 1;
 
     if (!EVP_DigestInit_ex(md, md->digest, NULL))
         goto berr;
     /*
      * FIXME: there's absolutely no guarantee this makes any sense at all,
      * particularly now EVP_MD_CTX has been restructured.
      */
-    if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0)
+    if (RAND_bytes(md->md_data, md->digest->md_size) <= 0)
         goto berr;
     memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
     longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
     ctx->buf_len += md->digest->md_size;
 
     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
         goto berr;
     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
         goto berr;
     ctx->buf_len += md->digest->md_size;
     ctx->blockout = 1;
     ctx->sigio = 0;
     return 1;
  berr:
     BIO_clear_retry_flags(b);
     return 0;
 }
 
 static int sig_in(BIO *b)
 {
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
     unsigned char tmp[EVP_MAX_MD_SIZE];
     int ret = 0;
 
     ctx = b->ptr;
     md = &ctx->md;
 
     if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size)
         return 1;
 
     if (!EVP_DigestInit_ex(md, md->digest, NULL))
         goto berr;
     memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size);
     longswap(md->md_data, md->digest->md_size);
     ctx->buf_off += md->digest->md_size;
 
     if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN)))
         goto berr;
     if (!EVP_DigestFinal_ex(md, tmp, NULL))
         goto berr;
     ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0;
     ctx->buf_off += md->digest->md_size;
     if (ret == 1) {
         ctx->sigio = 0;
         if (ctx->buf_len != ctx->buf_off) {
             memmove(ctx->buf, &(ctx->buf[ctx->buf_off]),
                     ctx->buf_len - ctx->buf_off);
         }
         ctx->buf_len -= ctx->buf_off;
         ctx->buf_off = 0;
     } else {
         ctx->cont = 0;
     }
     return 1;
  berr:
     BIO_clear_retry_flags(b);
     return 0;
 }
 
 static int block_out(BIO *b)
 {
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
     unsigned long tl;
 
     ctx = b->ptr;
     md = &ctx->md;
 
     tl = ctx->buf_len - OK_BLOCK_BLOCK;
     ctx->buf[0] = (unsigned char)(tl >> 24);
     ctx->buf[1] = (unsigned char)(tl >> 16);
     ctx->buf[2] = (unsigned char)(tl >> 8);
     ctx->buf[3] = (unsigned char)(tl);
     if (!EVP_DigestUpdate(md,
                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
         goto berr;
     if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL))
         goto berr;
     ctx->buf_len += md->digest->md_size;
     ctx->blockout = 1;
     return 1;
  berr:
     BIO_clear_retry_flags(b);
     return 0;
 }
 
 static int block_in(BIO *b)
 {
     BIO_OK_CTX *ctx;
     EVP_MD_CTX *md;
     unsigned long tl = 0;
     unsigned char tmp[EVP_MAX_MD_SIZE];
 
     ctx = b->ptr;
     md = &ctx->md;
 
     assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */
     tl = ctx->buf[0];
     tl <<= 8;
     tl |= ctx->buf[1];
     tl <<= 8;
     tl |= ctx->buf[2];
     tl <<= 8;
     tl |= ctx->buf[3];
 
     if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size)
         return 1;
 
     if (!EVP_DigestUpdate(md,
                           (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl))
         goto berr;
     if (!EVP_DigestFinal_ex(md, tmp, NULL))
         goto berr;
     if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) ==
         0) {
         /* there might be parts from next block lurking around ! */
         ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size;
         ctx->buf_len_save = ctx->buf_len;
         ctx->buf_off = OK_BLOCK_BLOCK;
         ctx->buf_len = tl + OK_BLOCK_BLOCK;
         ctx->blockout = 1;
     } else {
         ctx->cont = 0;
     }
     return 1;
  berr:
     BIO_clear_retry_flags(b);
     return 0;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/evp/digest.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/evp/digest.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/evp/digest.c	(revision 306191)
@@ -1,396 +1,396 @@
 /* crypto/evp/digest.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 <stdio.h>
 #include "cryptlib.h"
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 #endif
 
 void EVP_MD_CTX_init(EVP_MD_CTX *ctx)
 {
     memset(ctx, '\0', sizeof *ctx);
 }
 
 EVP_MD_CTX *EVP_MD_CTX_create(void)
 {
     EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
 
     if (ctx)
         EVP_MD_CTX_init(ctx);
 
     return ctx;
 }
 
 int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type)
 {
     EVP_MD_CTX_init(ctx);
     return EVP_DigestInit_ex(ctx, type, NULL);
 }
 
 int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
 {
     EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
 #ifndef OPENSSL_NO_ENGINE
     /*
      * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so
      * this context may already have an ENGINE! Try to avoid releasing the
      * previous handle, re-querying for an ENGINE, and having a
      * reinitialisation, when it may all be unecessary.
      */
     if (ctx->engine && ctx->digest && (!type ||
                                        (type
                                         && (type->type ==
                                             ctx->digest->type))))
         goto skip_to_init;
     if (type) {
         /*
          * Ensure an ENGINE left lying around from last time is cleared (the
          * previous check attempted to avoid this if the same ENGINE and
          * EVP_MD could be used).
          */
         if (ctx->engine)
             ENGINE_finish(ctx->engine);
         if (impl) {
             if (!ENGINE_init(impl)) {
                 EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
                 return 0;
             }
         } else
             /* Ask if an ENGINE is reserved for this job */
             impl = ENGINE_get_digest_engine(type->type);
         if (impl) {
             /* There's an ENGINE for this job ... (apparently) */
             const EVP_MD *d = ENGINE_get_digest(impl, type->type);
             if (!d) {
                 /* Same comment from evp_enc.c */
                 EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR);
                 ENGINE_finish(impl);
                 return 0;
             }
             /* We'll use the ENGINE's private digest definition */
             type = d;
             /*
              * Store the ENGINE functional reference so we know 'type' came
              * from an ENGINE and we need to release it when done.
              */
             ctx->engine = impl;
         } else
             ctx->engine = NULL;
     } else {
         if (!ctx->digest) {
             EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET);
             return 0;
         }
         type = ctx->digest;
     }
 #endif
     if (ctx->digest != type) {
         if (ctx->digest && ctx->digest->ctx_size) {
             OPENSSL_free(ctx->md_data);
             ctx->md_data = NULL;
         }
         ctx->digest = type;
         if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
             ctx->update = type->update;
             ctx->md_data = OPENSSL_malloc(type->ctx_size);
             if (ctx->md_data == NULL) {
                 EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE);
                 return 0;
             }
         }
     }
 #ifndef OPENSSL_NO_ENGINE
  skip_to_init:
 #endif
     if (ctx->pctx) {
         int r;
         r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
                               EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
         if (r <= 0 && (r != -2))
             return 0;
     }
     if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT)
         return 1;
 #ifdef OPENSSL_FIPS
     if (FIPS_mode()) {
         if (FIPS_digestinit(ctx, type))
             return 1;
         OPENSSL_free(ctx->md_data);
         ctx->md_data = NULL;
         return 0;
     }
 #endif
     return ctx->digest->init(ctx);
 }
 
 int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
 {
 #ifdef OPENSSL_FIPS
-    return FIPS_digestupdate(ctx, data, count);
-#else
-    return ctx->update(ctx, data, count);
+    if (FIPS_mode())
+        return FIPS_digestupdate(ctx, data, count);
 #endif
+    return ctx->update(ctx, data, count);
 }
 
 /* The caller can assume that this removes any secret data from the context */
 int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 {
     int ret;
     ret = EVP_DigestFinal_ex(ctx, md, size);
     EVP_MD_CTX_cleanup(ctx);
     return ret;
 }
 
 /* The caller can assume that this removes any secret data from the context */
 int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
 {
-#ifdef OPENSSL_FIPS
-    return FIPS_digestfinal(ctx, md, size);
-#else
     int ret;
+#ifdef OPENSSL_FIPS
+    if (FIPS_mode())
+        return FIPS_digestfinal(ctx, md, size);
+#endif
 
     OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
     ret = ctx->digest->final(ctx, md);
     if (size != NULL)
         *size = ctx->digest->md_size;
     if (ctx->digest->cleanup) {
         ctx->digest->cleanup(ctx);
         EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
     }
-    memset(ctx->md_data, 0, ctx->digest->ctx_size);
+    OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
     return ret;
-#endif
 }
 
 int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
 {
     EVP_MD_CTX_init(out);
     return EVP_MD_CTX_copy_ex(out, in);
 }
 
 int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
 {
     unsigned char *tmp_buf;
     if ((in == NULL) || (in->digest == NULL)) {
         EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED);
         return 0;
     }
 #ifndef OPENSSL_NO_ENGINE
     /* Make sure it's safe to copy a digest context using an ENGINE */
     if (in->engine && !ENGINE_init(in->engine)) {
         EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB);
         return 0;
     }
 #endif
 
     if (out->digest == in->digest) {
         tmp_buf = out->md_data;
         EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE);
     } else
         tmp_buf = NULL;
     EVP_MD_CTX_cleanup(out);
     memcpy(out, in, sizeof *out);
 
     if (in->md_data && out->digest->ctx_size) {
         if (tmp_buf)
             out->md_data = tmp_buf;
         else {
             out->md_data = OPENSSL_malloc(out->digest->ctx_size);
             if (!out->md_data) {
                 EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE);
                 return 0;
             }
         }
         memcpy(out->md_data, in->md_data, out->digest->ctx_size);
     }
 
     out->update = in->update;
 
     if (in->pctx) {
         out->pctx = EVP_PKEY_CTX_dup(in->pctx);
         if (!out->pctx) {
             EVP_MD_CTX_cleanup(out);
             return 0;
         }
     }
 
     if (out->digest->copy)
         return out->digest->copy(out, in);
 
     return 1;
 }
 
 int EVP_Digest(const void *data, size_t count,
                unsigned char *md, unsigned int *size, const EVP_MD *type,
                ENGINE *impl)
 {
     EVP_MD_CTX ctx;
     int ret;
 
     EVP_MD_CTX_init(&ctx);
     EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT);
     ret = EVP_DigestInit_ex(&ctx, type, impl)
         && EVP_DigestUpdate(&ctx, data, count)
         && EVP_DigestFinal_ex(&ctx, md, size);
     EVP_MD_CTX_cleanup(&ctx);
 
     return ret;
 }
 
 void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx)
 {
     if (ctx) {
         EVP_MD_CTX_cleanup(ctx);
         OPENSSL_free(ctx);
     }
 }
 
 /* This call frees resources associated with the context */
 int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx)
 {
 #ifndef OPENSSL_FIPS
     /*
      * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because
      * sometimes only copies of the context are ever finalised.
      */
     if (ctx->digest && ctx->digest->cleanup
         && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED))
         ctx->digest->cleanup(ctx);
     if (ctx->digest && ctx->digest->ctx_size && ctx->md_data
         && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) {
         OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
         OPENSSL_free(ctx->md_data);
     }
 #endif
     if (ctx->pctx)
         EVP_PKEY_CTX_free(ctx->pctx);
 #ifndef OPENSSL_NO_ENGINE
     if (ctx->engine)
         /*
          * The EVP_MD we used belongs to an ENGINE, release the functional
          * reference we held for this reason.
          */
         ENGINE_finish(ctx->engine);
 #endif
 #ifdef OPENSSL_FIPS
     FIPS_md_ctx_cleanup(ctx);
 #endif
     memset(ctx, '\0', sizeof *ctx);
 
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/evp/e_seed.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/evp/e_seed.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/evp/e_seed.c	(revision 306191)
@@ -1,82 +1,83 @@
 /* crypto/evp/e_seed.c */
 /* ====================================================================
  * Copyright (c) 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 <openssl/opensslconf.h>
 #ifndef OPENSSL_NO_SEED
 # include <openssl/evp.h>
 # include <openssl/err.h>
 # include <string.h>
 # include <assert.h>
 # include <openssl/seed.h>
 # include "evp_locl.h"
 
 static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                          const unsigned char *iv, int enc);
 
 typedef struct {
     SEED_KEY_SCHEDULE ks;
 } EVP_SEED_KEY;
 
 IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
-                       16, 16, 16, 128, 0, seed_init_key, 0, 0, 0, 0)
+                       16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
+                       seed_init_key, 0, 0, 0, 0)
 
 static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
                          const unsigned char *iv, int enc)
 {
     SEED_set_key(key, ctx->cipher_data);
     return 1;
 }
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/md2/md2_dgst.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/md2/md2_dgst.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/md2/md2_dgst.c	(revision 306191)
@@ -1,224 +1,224 @@
 /* crypto/md2/md2_dgst.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.]
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/md2.h>
 #include <openssl/opensslv.h>
 #include <openssl/crypto.h>
 
 const char MD2_version[] = "MD2" OPENSSL_VERSION_PTEXT;
 
 /*
  * Implemented from RFC1319 The MD2 Message-Digest Algorithm
  */
 
 #define UCHAR   unsigned char
 
 static void md2_block(MD2_CTX *c, const unsigned char *d);
 /*
  * The magic S table - I have converted it to hex since it is basically just
  * a random byte string.
  */
 static const MD2_INT S[256] = {
     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
     0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
     0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
     0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
     0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
     0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
     0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
     0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
     0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
     0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
     0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
     0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
     0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
     0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
     0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
     0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
     0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
     0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
     0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
     0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
     0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
     0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
     0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
     0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
     0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
     0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
     0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
     0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
     0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
 };
 
 const char *MD2_options(void)
 {
     if (sizeof(MD2_INT) == 1)
         return ("md2(char)");
     else
         return ("md2(int)");
 }
 
 fips_md_init(MD2)
 {
     c->num = 0;
     memset(c->state, 0, sizeof c->state);
     memset(c->cksm, 0, sizeof c->cksm);
     memset(c->data, 0, sizeof c->data);
     return 1;
 }
 
 int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len)
 {
     register UCHAR *p;
 
     if (len == 0)
         return 1;
 
     p = c->data;
     if (c->num != 0) {
         if ((c->num + len) >= MD2_BLOCK) {
             memcpy(&(p[c->num]), data, MD2_BLOCK - c->num);
             md2_block(c, c->data);
             data += (MD2_BLOCK - c->num);
             len -= (MD2_BLOCK - c->num);
             c->num = 0;
             /* drop through and do the rest */
         } else {
             memcpy(&(p[c->num]), data, len);
             /* data+=len; */
             c->num += (int)len;
             return 1;
         }
     }
     /*
      * we now can process the input data in blocks of MD2_BLOCK chars and
      * save the leftovers to c->data.
      */
     while (len >= MD2_BLOCK) {
         md2_block(c, data);
         data += MD2_BLOCK;
         len -= MD2_BLOCK;
     }
     memcpy(p, data, len);
     c->num = (int)len;
     return 1;
 }
 
 static void md2_block(MD2_CTX *c, const unsigned char *d)
 {
     register MD2_INT t, *sp1, *sp2;
     register int i, j;
     MD2_INT state[48];
 
     sp1 = c->state;
     sp2 = c->cksm;
     j = sp2[MD2_BLOCK - 1];
     for (i = 0; i < 16; i++) {
         state[i] = sp1[i];
         state[i + 16] = t = d[i];
         state[i + 32] = (t ^ sp1[i]);
         j = sp2[i] ^= S[t ^ j];
     }
     t = 0;
     for (i = 0; i < 18; i++) {
         for (j = 0; j < 48; j += 8) {
             t = state[j + 0] ^= S[t];
             t = state[j + 1] ^= S[t];
             t = state[j + 2] ^= S[t];
             t = state[j + 3] ^= S[t];
             t = state[j + 4] ^= S[t];
             t = state[j + 5] ^= S[t];
             t = state[j + 6] ^= S[t];
             t = state[j + 7] ^= S[t];
         }
         t = (t + i) & 0xff;
     }
     memcpy(sp1, state, 16 * sizeof(MD2_INT));
     OPENSSL_cleanse(state, 48 * sizeof(MD2_INT));
 }
 
 int MD2_Final(unsigned char *md, MD2_CTX *c)
 {
     int i, v;
     register UCHAR *cp;
     register MD2_INT *p1, *p2;
 
     cp = c->data;
     p1 = c->state;
     p2 = c->cksm;
     v = MD2_BLOCK - c->num;
     for (i = c->num; i < MD2_BLOCK; i++)
         cp[i] = (UCHAR) v;
 
     md2_block(c, cp);
 
     for (i = 0; i < MD2_BLOCK; i++)
         cp[i] = (UCHAR) p2[i];
     md2_block(c, cp);
 
     for (i = 0; i < 16; i++)
         md[i] = (UCHAR) (p1[i] & 0xff);
-    memset((char *)&c, 0, sizeof(c));
+    OPENSSL_cleanse(c, sizeof(*c));
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/md32_common.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/md32_common.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/md32_common.h	(revision 306191)
@@ -1,410 +1,418 @@
 /* crypto/md32_common.h */
 /* ====================================================================
  * Copyright (c) 1999-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
  *    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 is a generic 32 bit "collector" for message digest algorithms.
  * Whenever needed it collects input character stream into chunks of
  * 32 bit values and invokes a block function that performs actual hash
  * calculations.
  *
  * Porting guide.
  *
  * Obligatory macros:
  *
  * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN
  *      this macro defines byte order of input stream.
  * HASH_CBLOCK
  *      size of a unit chunk HASH_BLOCK operates on.
  * HASH_LONG
  *      has to be at lest 32 bit wide, if it's wider, then
  *      HASH_LONG_LOG2 *has to* be defined along
  * HASH_CTX
  *      context structure that at least contains following
  *      members:
  *              typedef struct {
  *                      ...
  *                      HASH_LONG       Nl,Nh;
  *                      either {
  *                      HASH_LONG       data[HASH_LBLOCK];
  *                      unsigned char   data[HASH_CBLOCK];
  *                      };
  *                      unsigned int    num;
  *                      ...
  *                      } HASH_CTX;
  *      data[] vector is expected to be zeroed upon first call to
  *      HASH_UPDATE.
  * HASH_UPDATE
  *      name of "Update" function, implemented here.
  * HASH_TRANSFORM
  *      name of "Transform" function, implemented here.
  * HASH_FINAL
  *      name of "Final" function, implemented here.
  * HASH_BLOCK_DATA_ORDER
  *      name of "block" function capable of treating *unaligned* input
  *      message in original (data) byte order, implemented externally.
  * HASH_MAKE_STRING
  *      macro convering context variables to an ASCII hash string.
  *
  * MD5 example:
  *
  *      #define DATA_ORDER_IS_LITTLE_ENDIAN
  *
  *      #define HASH_LONG               MD5_LONG
  *      #define HASH_LONG_LOG2          MD5_LONG_LOG2
  *      #define HASH_CTX                MD5_CTX
  *      #define HASH_CBLOCK             MD5_CBLOCK
  *      #define HASH_UPDATE             MD5_Update
  *      #define HASH_TRANSFORM          MD5_Transform
  *      #define HASH_FINAL              MD5_Final
  *      #define HASH_BLOCK_DATA_ORDER   md5_block_data_order
  *
  *                                      <appro@fy.chalmers.se>
  */
 
+#include <openssl/crypto.h>
+
 #if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
 # error "DATA_ORDER must be defined!"
 #endif
 
 #ifndef HASH_CBLOCK
 # error "HASH_CBLOCK must be defined!"
 #endif
 #ifndef HASH_LONG
 # error "HASH_LONG must be defined!"
 #endif
 #ifndef HASH_CTX
 # error "HASH_CTX must be defined!"
 #endif
 
 #ifndef HASH_UPDATE
 # error "HASH_UPDATE must be defined!"
 #endif
 #ifndef HASH_TRANSFORM
 # error "HASH_TRANSFORM must be defined!"
 #endif
 #ifndef HASH_FINAL
 # error "HASH_FINAL must be defined!"
 #endif
 
 #ifndef HASH_BLOCK_DATA_ORDER
 # error "HASH_BLOCK_DATA_ORDER must be defined!"
 #endif
 
 /*
  * Engage compiler specific rotate intrinsic function if available.
  */
 #undef ROTATE
 #ifndef PEDANTIC
 # if defined(_MSC_VER)
 #  define ROTATE(a,n)   _lrotl(a,n)
 # elif defined(__ICC)
 #  define ROTATE(a,n)   _rotl(a,n)
 # elif defined(__MWERKS__)
 #  if defined(__POWERPC__)
 #   define ROTATE(a,n)  __rlwinm(a,n,0,31)
 #  elif defined(__MC68K__)
     /* Motorola specific tweak. <appro@fy.chalmers.se> */
 #   define ROTATE(a,n)  ( n<24 ? __rol(a,n) : __ror(a,32-n) )
 #  else
 #   define ROTATE(a,n)  __rol(a,n)
 #  endif
 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
   /*
    * Some GNU C inline assembler templates. Note that these are
    * rotates by *constant* number of bits! But that's exactly
    * what we need here...
    *                                    <appro@fy.chalmers.se>
    */
 #  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
 #   define ROTATE(a,n)  ({ register unsigned int ret;   \
                                 asm (                   \
                                 "roll %1,%0"            \
                                 : "=r"(ret)             \
                                 : "I"(n), "0"((unsigned int)(a))        \
                                 : "cc");                \
                            ret;                         \
                         })
 #  elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \
         defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__)
 #   define ROTATE(a,n)  ({ register unsigned int ret;   \
                                 asm (                   \
                                 "rlwinm %0,%1,%2,0,31"  \
                                 : "=r"(ret)             \
                                 : "r"(a), "I"(n));      \
                            ret;                         \
                         })
 #  elif defined(__s390x__)
 #   define ROTATE(a,n) ({ register unsigned int ret;    \
                                 asm ("rll %0,%1,%2"     \
                                 : "=r"(ret)             \
                                 : "r"(a), "I"(n));      \
                           ret;                          \
                         })
 #  endif
 # endif
 #endif                          /* PEDANTIC */
 
 #ifndef ROTATE
 # define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
 #endif
 
 #if defined(DATA_ORDER_IS_BIG_ENDIAN)
 
 # ifndef PEDANTIC
 #  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
 #   if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \
       (defined(__x86_64) || defined(__x86_64__))
 #    if !defined(B_ENDIAN)
     /*
      * This gives ~30-40% performance improvement in SHA-256 compiled
      * with gcc [on P4]. Well, first macro to be frank. We can pull
      * this trick on x86* platforms only, because these CPUs can fetch
      * unaligned data without raising an exception.
      */
 #     define HOST_c2l(c,l)        ({ unsigned int r=*((const unsigned int *)(c)); \
                                    asm ("bswapl %0":"=r"(r):"0"(r));    \
                                    (c)+=4; (l)=r;                       })
 #     define HOST_l2c(l,c)        ({ unsigned int r=(l);                  \
                                    asm ("bswapl %0":"=r"(r):"0"(r));    \
                                    *((unsigned int *)(c))=r; (c)+=4; r; })
 #    endif
 #   endif
 #  endif
 # endif
 # if defined(__s390__) || defined(__s390x__)
 #  define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l))
 #  define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l))
 # endif
 
 # ifndef HOST_c2l
 #  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))<<24),          \
                          l|=(((unsigned long)(*((c)++)))<<16),          \
                          l|=(((unsigned long)(*((c)++)))<< 8),          \
                          l|=(((unsigned long)(*((c)++)))    )           )
 # endif
 # ifndef HOST_l2c
 #  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)>>24)&0xff),      \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
                          *((c)++)=(unsigned char)(((l)    )&0xff),      \
                          l)
 # endif
 
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
 
 # ifndef PEDANTIC
 #  if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
 #   if defined(__s390x__)
 #    define HOST_c2l(c,l)        ({ asm ("lrv    %0,%1"                  \
                                    :"=d"(l) :"m"(*(const unsigned int *)(c)));\
                                    (c)+=4; (l);                         })
 #    define HOST_l2c(l,c)        ({ asm ("strv   %1,%0"                  \
                                    :"=m"(*(unsigned int *)(c)) :"d"(l));\
                                    (c)+=4; (l);                         })
 #   endif
 #  endif
 # endif
 # if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
 #  ifndef B_ENDIAN
    /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */
 #   define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l)
 #   define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l)
 #  endif
 # endif
 
 # ifndef HOST_c2l
 #  define HOST_c2l(c,l)   (l =(((unsigned long)(*((c)++)))    ),          \
                          l|=(((unsigned long)(*((c)++)))<< 8),          \
                          l|=(((unsigned long)(*((c)++)))<<16),          \
                          l|=(((unsigned long)(*((c)++)))<<24)           )
 # endif
 # ifndef HOST_l2c
 #  define HOST_l2c(l,c)   (*((c)++)=(unsigned char)(((l)    )&0xff),      \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff),      \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff),      \
                          *((c)++)=(unsigned char)(((l)>>24)&0xff),      \
                          l)
 # endif
 
 #endif
 
 /*
  * Time for some action:-)
  */
 
 int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
 {
     const unsigned char *data = data_;
     unsigned char *p;
     HASH_LONG l;
     size_t n;
 
     if (len == 0)
         return 1;
 
     l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL;
     /*
      * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai
      * <weidai@eskimo.com> for pointing it out.
      */
     if (l < c->Nl)              /* overflow */
         c->Nh++;
     c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on
                                        * 16-bit */
     c->Nl = l;
 
     n = c->num;
     if (n != 0) {
         p = (unsigned char *)c->data;
 
         if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) {
             memcpy(p + n, data, HASH_CBLOCK - n);
             HASH_BLOCK_DATA_ORDER(c, p, 1);
             n = HASH_CBLOCK - n;
             data += n;
             len -= n;
             c->num = 0;
+            /*
+             * We use memset rather than OPENSSL_cleanse() here deliberately.
+             * Using OPENSSL_cleanse() here could be a performance issue. It
+             * will get properly cleansed on finalisation so this isn't a
+             * security problem.
+             */
             memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
         } else {
             memcpy(p + n, data, len);
             c->num += (unsigned int)len;
             return 1;
         }
     }
 
     n = len / HASH_CBLOCK;
     if (n > 0) {
         HASH_BLOCK_DATA_ORDER(c, data, n);
         n *= HASH_CBLOCK;
         data += n;
         len -= n;
     }
 
     if (len != 0) {
         p = (unsigned char *)c->data;
         c->num = (unsigned int)len;
         memcpy(p, data, len);
     }
     return 1;
 }
 
 void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data)
 {
     HASH_BLOCK_DATA_ORDER(c, data, 1);
 }
 
 int HASH_FINAL(unsigned char *md, HASH_CTX *c)
 {
     unsigned char *p = (unsigned char *)c->data;
     size_t n = c->num;
 
     p[n] = 0x80;                /* there is always room for one */
     n++;
 
     if (n > (HASH_CBLOCK - 8)) {
         memset(p + n, 0, HASH_CBLOCK - n);
         n = 0;
         HASH_BLOCK_DATA_ORDER(c, p, 1);
     }
     memset(p + n, 0, HASH_CBLOCK - 8 - n);
 
     p += HASH_CBLOCK - 8;
 #if   defined(DATA_ORDER_IS_BIG_ENDIAN)
     (void)HOST_l2c(c->Nh, p);
     (void)HOST_l2c(c->Nl, p);
 #elif defined(DATA_ORDER_IS_LITTLE_ENDIAN)
     (void)HOST_l2c(c->Nl, p);
     (void)HOST_l2c(c->Nh, p);
 #endif
     p -= HASH_CBLOCK;
     HASH_BLOCK_DATA_ORDER(c, p, 1);
     c->num = 0;
-    memset(p, 0, HASH_CBLOCK);
+    OPENSSL_cleanse(p, HASH_CBLOCK);
 
 #ifndef HASH_MAKE_STRING
 # error "HASH_MAKE_STRING must be defined!"
 #else
     HASH_MAKE_STRING(c, md);
 #endif
 
     return 1;
 }
 
 #ifndef MD32_REG_T
 # if defined(__alpha) || defined(__sparcv9) || defined(__mips)
 #  define MD32_REG_T long
 /*
  * This comment was originaly written for MD5, which is why it
  * discusses A-D. But it basically applies to all 32-bit digests,
  * which is why it was moved to common header file.
  *
  * In case you wonder why A-D are declared as long and not
  * as MD5_LONG. Doing so results in slight performance
  * boost on LP64 architectures. The catch is we don't
  * really care if 32 MSBs of a 64-bit register get polluted
  * with eventual overflows as we *save* only 32 LSBs in
  * *either* case. Now declaring 'em long excuses the compiler
  * from keeping 32 MSBs zeroed resulting in 13% performance
  * improvement under SPARC Solaris7/64 and 5% under AlphaLinux.
  * Well, to be honest it should say that this *prevents*
  * performance degradation.
  *                              <appro@fy.chalmers.se>
  */
 # else
 /*
  * Above is not absolute and there are LP64 compilers that
  * generate better code if MD32_REG_T is defined int. The above
  * pre-processor condition reflects the circumstances under which
  * the conclusion was made and is subject to further extension.
  *                              <appro@fy.chalmers.se>
  */
 #  define MD32_REG_T int
 # endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/mdc2/mdc2dgst.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/mdc2/mdc2dgst.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/mdc2/mdc2dgst.c	(revision 306191)
@@ -1,196 +1,196 @@
 /* crypto/mdc2/mdc2dgst.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.]
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <openssl/crypto.h>
 #include <openssl/des.h>
 #include <openssl/mdc2.h>
 
 #undef c2l
 #define c2l(c,l)        (l =((DES_LONG)(*((c)++)))    , \
                          l|=((DES_LONG)(*((c)++)))<< 8L, \
                          l|=((DES_LONG)(*((c)++)))<<16L, \
                          l|=((DES_LONG)(*((c)++)))<<24L)
 
 #undef l2c
 #define l2c(l,c)        (*((c)++)=(unsigned char)(((l)     )&0xff), \
                         *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \
                         *((c)++)=(unsigned char)(((l)>>16L)&0xff), \
                         *((c)++)=(unsigned char)(((l)>>24L)&0xff))
 
 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len);
 fips_md_init(MDC2)
 {
     c->num = 0;
     c->pad_type = 1;
     memset(&(c->h[0]), 0x52, MDC2_BLOCK);
     memset(&(c->hh[0]), 0x25, MDC2_BLOCK);
     return 1;
 }
 
 int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
 {
     size_t i, j;
 
     i = c->num;
     if (i != 0) {
-        if (i + len < MDC2_BLOCK) {
+        if (len < MDC2_BLOCK - i) {
             /* partial block */
             memcpy(&(c->data[i]), in, len);
             c->num += (int)len;
             return 1;
         } else {
             /* filled one */
             j = MDC2_BLOCK - i;
             memcpy(&(c->data[i]), in, j);
             len -= j;
             in += j;
             c->num = 0;
             mdc2_body(c, &(c->data[0]), MDC2_BLOCK);
         }
     }
     i = len & ~((size_t)MDC2_BLOCK - 1);
     if (i > 0)
         mdc2_body(c, in, i);
     j = len - i;
     if (j > 0) {
         memcpy(&(c->data[0]), &(in[i]), j);
         c->num = (int)j;
     }
     return 1;
 }
 
 static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len)
 {
     register DES_LONG tin0, tin1;
     register DES_LONG ttin0, ttin1;
     DES_LONG d[2], dd[2];
     DES_key_schedule k;
     unsigned char *p;
     size_t i;
 
     for (i = 0; i < len; i += 8) {
         c2l(in, tin0);
         d[0] = dd[0] = tin0;
         c2l(in, tin1);
         d[1] = dd[1] = tin1;
         c->h[0] = (c->h[0] & 0x9f) | 0x40;
         c->hh[0] = (c->hh[0] & 0x9f) | 0x20;
 
         DES_set_odd_parity(&c->h);
         DES_set_key_unchecked(&c->h, &k);
         DES_encrypt1(d, &k, 1);
 
         DES_set_odd_parity(&c->hh);
         DES_set_key_unchecked(&c->hh, &k);
         DES_encrypt1(dd, &k, 1);
 
         ttin0 = tin0 ^ dd[0];
         ttin1 = tin1 ^ dd[1];
         tin0 ^= d[0];
         tin1 ^= d[1];
 
         p = c->h;
         l2c(tin0, p);
         l2c(ttin1, p);
         p = c->hh;
         l2c(ttin0, p);
         l2c(tin1, p);
     }
 }
 
 int MDC2_Final(unsigned char *md, MDC2_CTX *c)
 {
     unsigned int i;
     int j;
 
     i = c->num;
     j = c->pad_type;
     if ((i > 0) || (j == 2)) {
         if (j == 2)
             c->data[i++] = 0x80;
         memset(&(c->data[i]), 0, MDC2_BLOCK - i);
         mdc2_body(c, c->data, MDC2_BLOCK);
     }
     memcpy(md, (char *)c->h, MDC2_BLOCK);
     memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK);
     return 1;
 }
 
 #undef TEST
 
 #ifdef TEST
 main()
 {
     unsigned char md[MDC2_DIGEST_LENGTH];
     int i;
     MDC2_CTX c;
     static char *text = "Now is the time for all ";
 
     MDC2_Init(&c);
     MDC2_Update(&c, text, strlen(text));
     MDC2_Final(&(md[0]), &c);
 
     for (i = 0; i < MDC2_DIGEST_LENGTH; i++)
         printf("%02X", md[i]);
     printf("\n");
 }
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/ocsp/ocsp_ext.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/ocsp/ocsp_ext.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/ocsp/ocsp_ext.c	(revision 306191)
@@ -1,566 +1,566 @@
 /* ocsp_ext.c */
 /*
  * Written by Tom Titchener <Tom_Titchener@groove.net> for the OpenSSL
  * project.
  */
 
 /*
  * History: This file was transfered to Richard Levitte from CertCo by Kathy
  * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a
  * patch kit.
  */
 
 /* ====================================================================
  * Copyright (c) 1998-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
  *    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 <cryptlib.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/ocsp.h>
 #include <openssl/rand.h>
 #include <openssl/x509v3.h>
 
 /* Standard wrapper functions for extensions */
 
 /* OCSP request extensions */
 
 int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x)
 {
     return (X509v3_get_ext_count(x->tbsRequest->requestExtensions));
 }
 
 int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos)
 {
     return (X509v3_get_ext_by_NID
             (x->tbsRequest->requestExtensions, nid, lastpos));
 }
 
 int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj,
                                 int lastpos)
 {
     return (X509v3_get_ext_by_OBJ
             (x->tbsRequest->requestExtensions, obj, lastpos));
 }
 
 int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos)
 {
     return (X509v3_get_ext_by_critical
             (x->tbsRequest->requestExtensions, crit, lastpos));
 }
 
 X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc)
 {
     return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc));
 }
 
 X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc)
 {
     return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc));
 }
 
 void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx)
 {
     return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx);
 }
 
 int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit,
                               unsigned long flags)
 {
     return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value,
                            crit, flags);
 }
 
 int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc)
 {
     return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) !=
             NULL);
 }
 
 /* Single extensions */
 
 int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x)
 {
     return (X509v3_get_ext_count(x->singleRequestExtensions));
 }
 
 int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos)
 {
     return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos));
 }
 
 int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos)
 {
     return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos));
 }
 
 int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos)
 {
     return (X509v3_get_ext_by_critical
             (x->singleRequestExtensions, crit, lastpos));
 }
 
 X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc)
 {
     return (X509v3_get_ext(x->singleRequestExtensions, loc));
 }
 
 X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc)
 {
     return (X509v3_delete_ext(x->singleRequestExtensions, loc));
 }
 
 void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx)
 {
     return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx);
 }
 
 int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit,
                              unsigned long flags)
 {
     return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit,
                            flags);
 }
 
 int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc)
 {
     return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL);
 }
 
 /* OCSP Basic response */
 
 int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x)
 {
     return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions));
 }
 
 int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos)
 {
     return (X509v3_get_ext_by_NID
             (x->tbsResponseData->responseExtensions, nid, lastpos));
 }
 
 int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj,
                                   int lastpos)
 {
     return (X509v3_get_ext_by_OBJ
             (x->tbsResponseData->responseExtensions, obj, lastpos));
 }
 
 int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit,
                                        int lastpos)
 {
     return (X509v3_get_ext_by_critical
             (x->tbsResponseData->responseExtensions, crit, lastpos));
 }
 
 X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc)
 {
     return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc));
 }
 
 X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc)
 {
     return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc));
 }
 
 void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit,
                                   int *idx)
 {
     return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit,
                           idx);
 }
 
 int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value,
                                 int crit, unsigned long flags)
 {
     return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid,
                            value, crit, flags);
 }
 
 int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc)
 {
     return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc)
             != NULL);
 }
 
 /* OCSP single response extensions */
 
 int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x)
 {
     return (X509v3_get_ext_count(x->singleExtensions));
 }
 
 int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos)
 {
     return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos));
 }
 
 int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj,
                                    int lastpos)
 {
     return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos));
 }
 
 int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit,
                                         int lastpos)
 {
     return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos));
 }
 
 X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc)
 {
     return (X509v3_get_ext(x->singleExtensions, loc));
 }
 
 X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc)
 {
     return (X509v3_delete_ext(x->singleExtensions, loc));
 }
 
 void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit,
                                    int *idx)
 {
     return X509V3_get_d2i(x->singleExtensions, nid, crit, idx);
 }
 
 int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value,
                                  int crit, unsigned long flags)
 {
     return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags);
 }
 
 int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc)
 {
     return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL);
 }
 
 /* also CRL Entry Extensions */
 #if 0
 ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d,
                                 void *data, STACK_OF(ASN1_OBJECT) *sk)
 {
     int i;
     unsigned char *p, *b = NULL;
 
     if (data) {
         if ((i = i2d(data, NULL)) <= 0)
             goto err;
         if (!(b = p = OPENSSL_malloc((unsigned int)i)))
             goto err;
         if (i2d(data, &p) <= 0)
             goto err;
     } else if (sk) {
         if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL,
                                              (I2D_OF(ASN1_OBJECT)) i2d,
                                              V_ASN1_SEQUENCE,
                                              V_ASN1_UNIVERSAL,
                                              IS_SEQUENCE)) <= 0)
              goto err;
         if (!(b = p = OPENSSL_malloc((unsigned int)i)))
             goto err;
         if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d,
                                         V_ASN1_SEQUENCE,
                                         V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0)
              goto err;
     } else {
         OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA);
         goto err;
     }
     if (!s && !(s = ASN1_STRING_new()))
         goto err;
     if (!(ASN1_STRING_set(s, b, i)))
         goto err;
     OPENSSL_free(b);
     return s;
  err:
     if (b)
         OPENSSL_free(b);
     return NULL;
 }
 #endif
 
 /* Nonce handling functions */
 
 /*
  * Add a nonce to an extension stack. A nonce can be specificed or if NULL a
  * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an
  * OCTET STRING containing the nonce, previous versions used the raw nonce.
  */
 
 static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
                            unsigned char *val, int len)
 {
     unsigned char *tmpval;
     ASN1_OCTET_STRING os;
     int ret = 0;
     if (len <= 0)
         len = OCSP_DEFAULT_NONCE_LENGTH;
     /*
      * Create the OCTET STRING manually by writing out the header and
      * appending the content octets. This avoids an extra memory allocation
      * operation in some cases. Applications should *NOT* do this because it
      * relies on library internals.
      */
     os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING);
     os.data = OPENSSL_malloc(os.length);
     if (os.data == NULL)
         goto err;
     tmpval = os.data;
     ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
     if (val)
         memcpy(tmpval, val, len);
-    else if (RAND_pseudo_bytes(tmpval, len) < 0)
+    else if (RAND_bytes(tmpval, len) <= 0)
         goto err;
     if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
                          &os, 0, X509V3_ADD_REPLACE))
         goto err;
     ret = 1;
  err:
     if (os.data)
         OPENSSL_free(os.data);
     return ret;
 }
 
 /* Add nonce to an OCSP request */
 
 int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len)
 {
     return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len);
 }
 
 /* Same as above but for a response */
 
 int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len)
 {
     return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val,
                            len);
 }
 
 /*-
  * Check nonce validity in a request and response.
  * Return value reflects result:
  *  1: nonces present and equal.
  *  2: nonces both absent.
  *  3: nonce present in response only.
  *  0: nonces both present and not equal.
  * -1: nonce in request only.
  *
  *  For most responders clients can check return > 0.
  *  If responder doesn't handle nonces return != 0 may be
  *  necessary. return == 0 is always an error.
  */
 
 int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs)
 {
     /*
      * Since we are only interested in the presence or absence of
      * the nonce and comparing its value there is no need to use
      * the X509V3 routines: this way we can avoid them allocating an
      * ASN1_OCTET_STRING structure for the value which would be
      * freed immediately anyway.
      */
 
     int req_idx, resp_idx;
     X509_EXTENSION *req_ext, *resp_ext;
     req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
     resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1);
     /* Check both absent */
     if ((req_idx < 0) && (resp_idx < 0))
         return 2;
     /* Check in request only */
     if ((req_idx >= 0) && (resp_idx < 0))
         return -1;
     /* Check in response but not request */
     if ((req_idx < 0) && (resp_idx >= 0))
         return 3;
     /*
      * Otherwise nonce in request and response so retrieve the extensions
      */
     req_ext = OCSP_REQUEST_get_ext(req, req_idx);
     resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx);
     if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value))
         return 0;
     return 1;
 }
 
 /*
  * Copy the nonce value (if any) from an OCSP request to a response.
  */
 
 int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req)
 {
     X509_EXTENSION *req_ext;
     int req_idx;
     /* Check for nonce in request */
     req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1);
     /* If no nonce that's OK */
     if (req_idx < 0)
         return 2;
     req_ext = OCSP_REQUEST_get_ext(req, req_idx);
     return OCSP_BASICRESP_add_ext(resp, req_ext, -1);
 }
 
 X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim)
 {
     X509_EXTENSION *x = NULL;
     OCSP_CRLID *cid = NULL;
 
     if (!(cid = OCSP_CRLID_new()))
         goto err;
     if (url) {
         if (!(cid->crlUrl = ASN1_IA5STRING_new()))
             goto err;
         if (!(ASN1_STRING_set(cid->crlUrl, url, -1)))
             goto err;
     }
     if (n) {
         if (!(cid->crlNum = ASN1_INTEGER_new()))
             goto err;
         if (!(ASN1_INTEGER_set(cid->crlNum, *n)))
             goto err;
     }
     if (tim) {
         if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new()))
             goto err;
         if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim)))
             goto err;
     }
     x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid);
  err:
     if (cid)
         OCSP_CRLID_free(cid);
     return x;
 }
 
 /*   AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */
 X509_EXTENSION *OCSP_accept_responses_new(char **oids)
 {
     int nid;
     STACK_OF(ASN1_OBJECT) *sk = NULL;
     ASN1_OBJECT *o = NULL;
     X509_EXTENSION *x = NULL;
 
     if (!(sk = sk_ASN1_OBJECT_new_null()))
         goto err;
     while (oids && *oids) {
         if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid)))
             sk_ASN1_OBJECT_push(sk, o);
         oids++;
     }
     x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk);
  err:
     if (sk)
         sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free);
     return x;
 }
 
 /*  ArchiveCutoff ::= GeneralizedTime */
 X509_EXTENSION *OCSP_archive_cutoff_new(char *tim)
 {
     X509_EXTENSION *x = NULL;
     ASN1_GENERALIZEDTIME *gt = NULL;
 
     if (!(gt = ASN1_GENERALIZEDTIME_new()))
         goto err;
     if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim)))
         goto err;
     x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt);
  err:
     if (gt)
         ASN1_GENERALIZEDTIME_free(gt);
     return x;
 }
 
 /*
  * per ACCESS_DESCRIPTION parameter are oids, of which there are currently
  * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value.  This method
  * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String.
  */
 X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls)
 {
     X509_EXTENSION *x = NULL;
     ASN1_IA5STRING *ia5 = NULL;
     OCSP_SERVICELOC *sloc = NULL;
     ACCESS_DESCRIPTION *ad = NULL;
 
     if (!(sloc = OCSP_SERVICELOC_new()))
         goto err;
     if (!(sloc->issuer = X509_NAME_dup(issuer)))
         goto err;
     if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null()))
         goto err;
     while (urls && *urls) {
         if (!(ad = ACCESS_DESCRIPTION_new()))
             goto err;
         if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP)))
             goto err;
         if (!(ad->location = GENERAL_NAME_new()))
             goto err;
         if (!(ia5 = ASN1_IA5STRING_new()))
             goto err;
         if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1))
             goto err;
         ad->location->type = GEN_URI;
         ad->location->d.ia5 = ia5;
         if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad))
             goto err;
         urls++;
     }
     x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc);
  err:
     if (sloc)
         OCSP_SERVICELOC_free(sloc);
     return x;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/opensslv.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/opensslv.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/opensslv.h	(revision 306191)
@@ -1,97 +1,97 @@
 #ifndef HEADER_OPENSSLV_H
 # define HEADER_OPENSSLV_H
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 /*-
  * 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  0x1000114fL
+# define OPENSSL_VERSION_NUMBER  0x1000115fL
 # ifdef OPENSSL_FIPS
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1t-fips  3 May 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1u-fips  22 Sep 2016"
 # else
-#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1t  3 May 2016"
+#  define OPENSSL_VERSION_TEXT    "OpenSSL 1.0.1u  22 Sep 2016"
 # 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"
 
 
 #ifdef  __cplusplus
 }
 #endif
 #endif                          /* HEADER_OPENSSLV_H */
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem.h	(revision 306191)
@@ -1,611 +1,612 @@
 /* crypto/pem/pem.h */
 /* Copyright (C) 1995-1997 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_PEM_H
 # define HEADER_PEM_H
 
 # include <openssl/e_os2.h>
 # ifndef OPENSSL_NO_BIO
 #  include <openssl/bio.h>
 # endif
 # ifndef OPENSSL_NO_STACK
 #  include <openssl/stack.h>
 # endif
 # include <openssl/evp.h>
 # include <openssl/x509.h>
 # include <openssl/pem2.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 # define PEM_BUFSIZE             1024
 
 # define PEM_OBJ_UNDEF           0
 # define PEM_OBJ_X509            1
 # define PEM_OBJ_X509_REQ        2
 # define PEM_OBJ_CRL             3
 # define PEM_OBJ_SSL_SESSION     4
 # define PEM_OBJ_PRIV_KEY        10
 # define PEM_OBJ_PRIV_RSA        11
 # define PEM_OBJ_PRIV_DSA        12
 # define PEM_OBJ_PRIV_DH         13
 # define PEM_OBJ_PUB_RSA         14
 # define PEM_OBJ_PUB_DSA         15
 # define PEM_OBJ_PUB_DH          16
 # define PEM_OBJ_DHPARAMS        17
 # define PEM_OBJ_DSAPARAMS       18
 # define PEM_OBJ_PRIV_RSA_PUBLIC 19
 # define PEM_OBJ_PRIV_ECDSA      20
 # define PEM_OBJ_PUB_ECDSA       21
 # define PEM_OBJ_ECPARAMETERS    22
 
 # define PEM_ERROR               30
 # define PEM_DEK_DES_CBC         40
 # define PEM_DEK_IDEA_CBC        45
 # define PEM_DEK_DES_EDE         50
 # define PEM_DEK_DES_ECB         60
 # define PEM_DEK_RSA             70
 # define PEM_DEK_RSA_MD2         80
 # define PEM_DEK_RSA_MD5         90
 
 # define PEM_MD_MD2              NID_md2
 # define PEM_MD_MD5              NID_md5
 # define PEM_MD_SHA              NID_sha
 # define PEM_MD_MD2_RSA          NID_md2WithRSAEncryption
 # define PEM_MD_MD5_RSA          NID_md5WithRSAEncryption
 # define PEM_MD_SHA_RSA          NID_sha1WithRSAEncryption
 
 # define PEM_STRING_X509_OLD     "X509 CERTIFICATE"
 # define PEM_STRING_X509         "CERTIFICATE"
 # define PEM_STRING_X509_PAIR    "CERTIFICATE PAIR"
 # define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE"
 # define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST"
 # define PEM_STRING_X509_REQ     "CERTIFICATE REQUEST"
 # define PEM_STRING_X509_CRL     "X509 CRL"
 # define PEM_STRING_EVP_PKEY     "ANY PRIVATE KEY"
 # define PEM_STRING_PUBLIC       "PUBLIC KEY"
 # define PEM_STRING_RSA          "RSA PRIVATE KEY"
 # define PEM_STRING_RSA_PUBLIC   "RSA PUBLIC KEY"
 # define PEM_STRING_DSA          "DSA PRIVATE KEY"
 # define PEM_STRING_DSA_PUBLIC   "DSA PUBLIC KEY"
 # define PEM_STRING_PKCS7        "PKCS7"
 # define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA"
 # define PEM_STRING_PKCS8        "ENCRYPTED PRIVATE KEY"
 # define PEM_STRING_PKCS8INF     "PRIVATE KEY"
 # define PEM_STRING_DHPARAMS     "DH PARAMETERS"
 # define PEM_STRING_SSL_SESSION  "SSL SESSION PARAMETERS"
 # define PEM_STRING_DSAPARAMS    "DSA PARAMETERS"
 # define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY"
 # define PEM_STRING_ECPARAMETERS "EC PARAMETERS"
 # define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY"
 # define PEM_STRING_PARAMETERS   "PARAMETERS"
 # define PEM_STRING_CMS          "CMS"
 
   /*
    * Note that this structure is initialised by PEM_SealInit and cleaned up
    * by PEM_SealFinal (at least for now)
    */
 typedef struct PEM_Encode_Seal_st {
     EVP_ENCODE_CTX encode;
     EVP_MD_CTX md;
     EVP_CIPHER_CTX cipher;
 } PEM_ENCODE_SEAL_CTX;
 
 /* enc_type is one off */
 # define PEM_TYPE_ENCRYPTED      10
 # define PEM_TYPE_MIC_ONLY       20
 # define PEM_TYPE_MIC_CLEAR      30
 # define PEM_TYPE_CLEAR          40
 
 typedef struct pem_recip_st {
     char *name;
     X509_NAME *dn;
     int cipher;
     int key_enc;
     /*      char iv[8]; unused and wrong size */
 } PEM_USER;
 
 typedef struct pem_ctx_st {
     int type;                   /* what type of object */
     struct {
         int version;
         int mode;
     } proc_type;
 
     char *domain;
 
     struct {
         int cipher;
         /*-
         unused, and wrong size
         unsigned char iv[8]; */
     } DEK_info;
 
     PEM_USER *originator;
 
     int num_recipient;
     PEM_USER **recipient;
 
 /*-
     XXX(ben): don#t think this is used!
         STACK *x509_chain;      / * certificate chain */
     EVP_MD *md;                 /* signature type */
 
     int md_enc;                 /* is the md encrypted or not? */
     int md_len;                 /* length of md_data */
     char *md_data;              /* message digest, could be pkey encrypted */
 
     EVP_CIPHER *dec;            /* date encryption cipher */
     int key_len;                /* key length */
     unsigned char *key;         /* key */
   /*-
     unused, and wrong size
     unsigned char iv[8]; */
 
     int data_enc;               /* is the data encrypted */
     int data_len;
     unsigned char *data;
 } PEM_CTX;
 
 /*
  * These macros make the PEM_read/PEM_write functions easier to maintain and
  * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or
  * IMPLEMENT_PEM_rw_cb(...)
  */
 
 # ifdef OPENSSL_NO_FP_API
 
 #  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/
 #  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/
 #  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/
 #  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/
 #  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/
 # else
 
 #  define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \
 type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\
 { \
 return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \
 }
 
 #  define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x) \
 { \
 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 #  define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, const type *x) \
 { \
 return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 #  define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, \
                   void *u) \
         { \
         return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
         }
 
 #  define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \
 int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, \
                   void *u) \
         { \
         return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \
         }
 
 # endif
 
 # define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
 type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\
 { \
 return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \
 }
 
 # define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x) \
 { \
 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \
 }
 
 # define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, const type *x) \
 { \
 return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \
 }
 
 # define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
         { \
         return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \
         }
 
 # define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
 int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \
         { \
         return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \
         }
 
 # define IMPLEMENT_PEM_write(name, type, str, asn1) \
         IMPLEMENT_PEM_write_bio(name, type, str, asn1) \
         IMPLEMENT_PEM_write_fp(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_write_const(name, type, str, asn1) \
         IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \
         IMPLEMENT_PEM_write_fp_const(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \
         IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \
         IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \
         IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \
         IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_read(name, type, str, asn1) \
         IMPLEMENT_PEM_read_bio(name, type, str, asn1) \
         IMPLEMENT_PEM_read_fp(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_rw(name, type, str, asn1) \
         IMPLEMENT_PEM_read(name, type, str, asn1) \
         IMPLEMENT_PEM_write(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \
         IMPLEMENT_PEM_read(name, type, str, asn1) \
         IMPLEMENT_PEM_write_const(name, type, str, asn1)
 
 # define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \
         IMPLEMENT_PEM_read(name, type, str, asn1) \
         IMPLEMENT_PEM_write_cb(name, type, str, asn1)
 
 /* These are the same except they are for the declarations */
 
 # if defined(OPENSSL_NO_FP_API)
 
 #  define DECLARE_PEM_read_fp(name, type) /**/
 #  define DECLARE_PEM_write_fp(name, type) /**/
 #  define DECLARE_PEM_write_cb_fp(name, type) /**/
 # else
 
 #  define DECLARE_PEM_read_fp(name, type) \
         type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u);
 
 #  define DECLARE_PEM_write_fp(name, type) \
         int PEM_write_##name(FILE *fp, type *x);
 
 #  define DECLARE_PEM_write_fp_const(name, type) \
         int PEM_write_##name(FILE *fp, const type *x);
 
 #  define DECLARE_PEM_write_cb_fp(name, type) \
         int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
 
 # endif
 
 # ifndef OPENSSL_NO_BIO
 #  define DECLARE_PEM_read_bio(name, type) \
         type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u);
 
 #  define DECLARE_PEM_write_bio(name, type) \
         int PEM_write_bio_##name(BIO *bp, type *x);
 
 #  define DECLARE_PEM_write_bio_const(name, type) \
         int PEM_write_bio_##name(BIO *bp, const type *x);
 
 #  define DECLARE_PEM_write_cb_bio(name, type) \
         int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \
              unsigned char *kstr, int klen, pem_password_cb *cb, void *u);
 
 # else
 
 #  define DECLARE_PEM_read_bio(name, type) /**/
 #  define DECLARE_PEM_write_bio(name, type) /**/
 #  define DECLARE_PEM_write_bio_const(name, type) /**/
 #  define DECLARE_PEM_write_cb_bio(name, type) /**/
 # endif
 # define DECLARE_PEM_write(name, type) \
         DECLARE_PEM_write_bio(name, type) \
         DECLARE_PEM_write_fp(name, type)
 # define DECLARE_PEM_write_const(name, type) \
         DECLARE_PEM_write_bio_const(name, type) \
         DECLARE_PEM_write_fp_const(name, type)
 # define DECLARE_PEM_write_cb(name, type) \
         DECLARE_PEM_write_cb_bio(name, type) \
         DECLARE_PEM_write_cb_fp(name, type)
 # define DECLARE_PEM_read(name, type) \
         DECLARE_PEM_read_bio(name, type) \
         DECLARE_PEM_read_fp(name, type)
 # define DECLARE_PEM_rw(name, type) \
         DECLARE_PEM_read(name, type) \
         DECLARE_PEM_write(name, type)
 # define DECLARE_PEM_rw_const(name, type) \
         DECLARE_PEM_read(name, type) \
         DECLARE_PEM_write_const(name, type)
 # define DECLARE_PEM_rw_cb(name, type) \
         DECLARE_PEM_read(name, type) \
         DECLARE_PEM_write_cb(name, type)
 # if 1
 /* "userdata": new with OpenSSL 0.9.4 */
 typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
 # else
 /* OpenSSL 0.9.3, 0.9.3a */
 typedef int pem_password_cb (char *buf, int size, int rwflag);
 # endif
 
 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher);
 int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len,
                   pem_password_cb *callback, void *u);
 
 # ifndef OPENSSL_NO_BIO
 int PEM_read_bio(BIO *bp, char **name, char **header,
                  unsigned char **data, long *len);
 int PEM_write_bio(BIO *bp, const char *name, char *hdr, unsigned char *data,
                   long len);
 int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
                        const char *name, BIO *bp, pem_password_cb *cb,
                        void *u);
 void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
                         pem_password_cb *cb, void *u);
 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x,
                        const EVP_CIPHER *enc, unsigned char *kstr, int klen,
                        pem_password_cb *cb, void *u);
 
 STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk,
                                             pem_password_cb *cb, void *u);
 int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
                             unsigned char *kstr, int klen,
                             pem_password_cb *cd, void *u);
 # endif
 
 int PEM_read(FILE *fp, char **name, char **header,
              unsigned char **data, long *len);
 int PEM_write(FILE *fp, char *name, char *hdr, unsigned char *data, long len);
 void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
                     pem_password_cb *cb, void *u);
 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
                    void *x, const EVP_CIPHER *enc, unsigned char *kstr,
                    int klen, pem_password_cb *callback, void *u);
 STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk,
                                         pem_password_cb *cb, void *u);
 
 int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type,
                  EVP_MD *md_type, unsigned char **ek, int *ekl,
                  unsigned char *iv, EVP_PKEY **pubk, int npubk);
 void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl,
                     unsigned char *in, int inl);
 int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
                   unsigned char *out, int *outl, EVP_PKEY *priv);
 
 void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
 void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt);
 int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
                   unsigned int *siglen, EVP_PKEY *pkey);
 
 int PEM_def_callback(char *buf, int num, int w, void *key);
 void PEM_proc_type(char *buf, int type);
 void PEM_dek_info(char *buf, const char *type, int len, char *str);
 
 # include <openssl/symhacks.h>
 
 DECLARE_PEM_rw(X509, X509)
 DECLARE_PEM_rw(X509_AUX, X509)
 DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR)
 DECLARE_PEM_rw(X509_REQ, X509_REQ)
 DECLARE_PEM_write(X509_REQ_NEW, X509_REQ)
 DECLARE_PEM_rw(X509_CRL, X509_CRL)
 DECLARE_PEM_rw(PKCS7, PKCS7)
 DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
 DECLARE_PEM_rw(PKCS8, X509_SIG)
 DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
 # ifndef OPENSSL_NO_RSA
 DECLARE_PEM_rw_cb(RSAPrivateKey, RSA)
 DECLARE_PEM_rw_const(RSAPublicKey, RSA)
 DECLARE_PEM_rw(RSA_PUBKEY, RSA)
 # endif
 # ifndef OPENSSL_NO_DSA
 DECLARE_PEM_rw_cb(DSAPrivateKey, DSA)
 DECLARE_PEM_rw(DSA_PUBKEY, DSA)
 DECLARE_PEM_rw_const(DSAparams, DSA)
 # endif
 # ifndef OPENSSL_NO_EC
 DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP)
 DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY)
 DECLARE_PEM_rw(EC_PUBKEY, EC_KEY)
 # endif
 # ifndef OPENSSL_NO_DH
 DECLARE_PEM_rw_const(DHparams, DH)
 # endif
 DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY)
 DECLARE_PEM_rw(PUBKEY, EVP_PKEY)
 
 int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid,
                                       char *kstr, int klen,
                                       pem_password_cb *cb, void *u);
 int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *,
                                   char *, int, pem_password_cb *, void *);
 int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc,
                             char *kstr, int klen,
                             pem_password_cb *cb, void *u);
 int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid,
                                 char *kstr, int klen,
                                 pem_password_cb *cb, void *u);
 EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb,
                                   void *u);
 
 int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                            char *kstr, int klen,
                            pem_password_cb *cb, void *u);
 int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid,
                                char *kstr, int klen,
                                pem_password_cb *cb, void *u);
 int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid,
                                   char *kstr, int klen,
                                   pem_password_cb *cb, void *u);
 
 EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb,
                                  void *u);
 
 int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
                               char *kstr, int klen, pem_password_cb *cd,
                               void *u);
 
 EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x);
 int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x);
 
 EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length);
 EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length);
 EVP_PKEY *b2i_PrivateKey_bio(BIO *in);
 EVP_PKEY *b2i_PublicKey_bio(BIO *in);
 int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk);
 int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk);
 # ifndef OPENSSL_NO_RC4
 EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u);
 int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
                 pem_password_cb *cb, void *u);
 # 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_PEM_strings(void);
 
 /* Error codes for the PEM functions. */
 
 /* Function codes. */
 # define PEM_F_B2I_DSS                                    127
 # define PEM_F_B2I_PVK_BIO                                128
 # define PEM_F_B2I_RSA                                    129
 # define PEM_F_CHECK_BITLEN_DSA                           130
 # define PEM_F_CHECK_BITLEN_RSA                           131
 # define PEM_F_D2I_PKCS8PRIVATEKEY_BIO                    120
 # define PEM_F_D2I_PKCS8PRIVATEKEY_FP                     121
 # define PEM_F_DO_B2I                                     132
 # define PEM_F_DO_B2I_BIO                                 133
 # define PEM_F_DO_BLOB_HEADER                             134
 # define PEM_F_DO_PK8PKEY                                 126
 # define PEM_F_DO_PK8PKEY_FP                              125
 # define PEM_F_DO_PVK_BODY                                135
 # define PEM_F_DO_PVK_HEADER                              136
 # define PEM_F_I2B_PVK                                    137
 # define PEM_F_I2B_PVK_BIO                                138
 # define PEM_F_LOAD_IV                                    101
 # define PEM_F_PEM_ASN1_READ                              102
 # define PEM_F_PEM_ASN1_READ_BIO                          103
 # define PEM_F_PEM_ASN1_WRITE                             104
 # define PEM_F_PEM_ASN1_WRITE_BIO                         105
 # define PEM_F_PEM_DEF_CALLBACK                           100
 # define PEM_F_PEM_DO_HEADER                              106
 # define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY            118
 # define PEM_F_PEM_GET_EVP_CIPHER_INFO                    107
 # define PEM_F_PEM_PK8PKEY                                119
 # define PEM_F_PEM_READ                                   108
 # define PEM_F_PEM_READ_BIO                               109
 # define PEM_F_PEM_READ_BIO_PARAMETERS                    140
 # define PEM_F_PEM_READ_BIO_PRIVATEKEY                    123
 # define PEM_F_PEM_READ_PRIVATEKEY                        124
 # define PEM_F_PEM_SEALFINAL                              110
 # define PEM_F_PEM_SEALINIT                               111
 # define PEM_F_PEM_SIGNFINAL                              112
 # define PEM_F_PEM_WRITE                                  113
 # define PEM_F_PEM_WRITE_BIO                              114
 # define PEM_F_PEM_WRITE_PRIVATEKEY                       139
 # define PEM_F_PEM_X509_INFO_READ                         115
 # define PEM_F_PEM_X509_INFO_READ_BIO                     116
 # define PEM_F_PEM_X509_INFO_WRITE_BIO                    117
 
 /* Reason codes. */
 # define PEM_R_BAD_BASE64_DECODE                          100
 # define PEM_R_BAD_DECRYPT                                101
 # define PEM_R_BAD_END_LINE                               102
 # define PEM_R_BAD_IV_CHARS                               103
 # define PEM_R_BAD_MAGIC_NUMBER                           116
 # define PEM_R_BAD_PASSWORD_READ                          104
 # define PEM_R_BAD_VERSION_NUMBER                         117
 # define PEM_R_BIO_WRITE_FAILURE                          118
 # define PEM_R_CIPHER_IS_NULL                             127
 # define PEM_R_ERROR_CONVERTING_PRIVATE_KEY               115
 # define PEM_R_EXPECTING_PRIVATE_KEY_BLOB                 119
 # define PEM_R_EXPECTING_PUBLIC_KEY_BLOB                  120
+# define PEM_R_HEADER_TOO_LONG                            128
 # define PEM_R_INCONSISTENT_HEADER                        121
 # define PEM_R_KEYBLOB_HEADER_PARSE_ERROR                 122
 # define PEM_R_KEYBLOB_TOO_SHORT                          123
 # define PEM_R_NOT_DEK_INFO                               105
 # define PEM_R_NOT_ENCRYPTED                              106
 # define PEM_R_NOT_PROC_TYPE                              107
 # define PEM_R_NO_START_LINE                              108
 # define PEM_R_PROBLEMS_GETTING_PASSWORD                  109
 # define PEM_R_PUBLIC_KEY_NO_RSA                          110
 # define PEM_R_PVK_DATA_TOO_SHORT                         124
 # define PEM_R_PVK_TOO_SHORT                              125
 # define PEM_R_READ_KEY                                   111
 # define PEM_R_SHORT_HEADER                               112
 # define PEM_R_UNSUPPORTED_CIPHER                         113
 # define PEM_R_UNSUPPORTED_ENCRYPTION                     114
 # define PEM_R_UNSUPPORTED_KEY_COMPONENTS                 126
 
 #ifdef  __cplusplus
 }
 #endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_err.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_err.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_err.c	(revision 306191)
@@ -1,166 +1,167 @@
 /* crypto/pem/pem_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2007 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2016 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 <openssl/pem.h>
 
 /* BEGIN ERROR CODES */
 #ifndef OPENSSL_NO_ERR
 
 # define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0)
 # define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason)
 
 static ERR_STRING_DATA PEM_str_functs[] = {
     {ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"},
     {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"},
     {ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"},
     {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"},
     {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"},
     {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"},
     {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"},
     {ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"},
     {ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"},
     {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"},
     {ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"},
     {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"},
     {ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"},
     {ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"},
     {ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"},
     {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"},
     {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"},
     {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"},
     {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"},
     {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"},
     {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"},
     {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"},
     {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"},
     {ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY),
      "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"},
     {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"},
     {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"},
     {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"},
     {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"},
     {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"},
     {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"},
     {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"},
     {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"},
     {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"},
     {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"},
     {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"},
     {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"},
     {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"},
     {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"},
     {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"},
     {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"},
     {0, NULL}
 };
 
 static ERR_STRING_DATA PEM_str_reasons[] = {
     {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"},
     {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"},
     {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"},
     {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"},
     {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"},
     {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"},
     {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"},
     {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"},
     {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"},
     {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY),
      "error converting private key"},
     {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB),
      "expecting private key blob"},
     {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),
      "expecting public key blob"},
+    {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"},
     {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"},
     {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),
      "keyblob header parse error"},
     {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"},
     {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"},
     {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"},
     {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"},
     {ERR_REASON(PEM_R_NO_START_LINE), "no start line"},
     {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD),
      "problems getting password"},
     {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA), "public key no rsa"},
     {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"},
     {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"},
     {ERR_REASON(PEM_R_READ_KEY), "read key"},
     {ERR_REASON(PEM_R_SHORT_HEADER), "short header"},
     {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
     {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"},
     {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS),
      "unsupported key components"},
     {0, NULL}
 };
 
 #endif
 
 void ERR_load_PEM_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
 
     if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) {
         ERR_load_strings(0, PEM_str_functs);
         ERR_load_strings(0, PEM_str_reasons);
     }
 #endif
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pem/pem_lib.c	(revision 306191)
@@ -1,860 +1,860 @@
 /* crypto/pem/pem_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.]
  */
 
 #include <stdio.h>
 #include <ctype.h>
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/x509.h>
 #include <openssl/pem.h>
 #include <openssl/pkcs12.h>
 #include "asn1_locl.h"
 #ifndef OPENSSL_NO_DES
 # include <openssl/des.h>
 #endif
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 
 const char PEM_version[] = "PEM" OPENSSL_VERSION_PTEXT;
 
 #define MIN_LENGTH      4
 
 static int load_iv(char **fromp, unsigned char *to, int num);
 static int check_pem(const char *nm, const char *name);
 int pem_check_suffix(const char *pem_str, const char *suffix);
 
 int PEM_def_callback(char *buf, int num, int w, void *key)
 {
 #ifdef OPENSSL_NO_FP_API
     /*
      * We should not ever call the default callback routine from windows.
      */
     PEMerr(PEM_F_PEM_DEF_CALLBACK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return (-1);
 #else
     int i, j;
     const char *prompt;
     if (key) {
         i = strlen(key);
         i = (i > num) ? num : i;
         memcpy(buf, key, i);
         return (i);
     }
 
     prompt = EVP_get_pw_prompt();
     if (prompt == NULL)
         prompt = "Enter PEM pass phrase:";
 
     for (;;) {
         i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w);
         if (i != 0) {
             PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
             memset(buf, 0, (unsigned int)num);
             return (-1);
         }
         j = strlen(buf);
         if (j < MIN_LENGTH) {
             fprintf(stderr,
                     "phrase is too short, needs to be at least %d chars\n",
                     MIN_LENGTH);
         } else
             break;
     }
     return (j);
 #endif
 }
 
 void PEM_proc_type(char *buf, int type)
 {
     const char *str;
 
     if (type == PEM_TYPE_ENCRYPTED)
         str = "ENCRYPTED";
     else if (type == PEM_TYPE_MIC_CLEAR)
         str = "MIC-CLEAR";
     else if (type == PEM_TYPE_MIC_ONLY)
         str = "MIC-ONLY";
     else
         str = "BAD-TYPE";
 
     BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE);
     BUF_strlcat(buf, str, PEM_BUFSIZE);
     BUF_strlcat(buf, "\n", PEM_BUFSIZE);
 }
 
 void PEM_dek_info(char *buf, const char *type, int len, char *str)
 {
     static const unsigned char map[17] = "0123456789ABCDEF";
     long i;
     int j;
 
     BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE);
     BUF_strlcat(buf, type, PEM_BUFSIZE);
     BUF_strlcat(buf, ",", PEM_BUFSIZE);
     j = strlen(buf);
     if (j + (len * 2) + 1 > PEM_BUFSIZE)
         return;
     for (i = 0; i < len; i++) {
         buf[j + i * 2] = map[(str[i] >> 4) & 0x0f];
         buf[j + i * 2 + 1] = map[(str[i]) & 0x0f];
     }
     buf[j + i * 2] = '\n';
     buf[j + i * 2 + 1] = '\0';
 }
 
 #ifndef OPENSSL_NO_FP_API
 void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
                     pem_password_cb *cb, void *u)
 {
     BIO *b;
     void *ret;
 
     if ((b = BIO_new(BIO_s_file())) == NULL) {
         PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB);
         return (0);
     }
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u);
     BIO_free(b);
     return (ret);
 }
 #endif
 
 static int check_pem(const char *nm, const char *name)
 {
     /* Normal matching nm and name */
     if (!strcmp(nm, name))
         return 1;
 
     /* Make PEM_STRING_EVP_PKEY match any private key */
 
     if (!strcmp(name, PEM_STRING_EVP_PKEY)) {
         int slen;
         const EVP_PKEY_ASN1_METHOD *ameth;
         if (!strcmp(nm, PEM_STRING_PKCS8))
             return 1;
         if (!strcmp(nm, PEM_STRING_PKCS8INF))
             return 1;
         slen = pem_check_suffix(nm, "PRIVATE KEY");
         if (slen > 0) {
             /*
              * NB: ENGINE implementations wont contain a deprecated old
              * private key decode function so don't look for them.
              */
             ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen);
             if (ameth && ameth->old_priv_decode)
                 return 1;
         }
         return 0;
     }
 
     if (!strcmp(name, PEM_STRING_PARAMETERS)) {
         int slen;
         const EVP_PKEY_ASN1_METHOD *ameth;
         slen = pem_check_suffix(nm, "PARAMETERS");
         if (slen > 0) {
             ENGINE *e;
             ameth = EVP_PKEY_asn1_find_str(&e, nm, slen);
             if (ameth) {
                 int r;
                 if (ameth->param_decode)
                     r = 1;
                 else
                     r = 0;
 #ifndef OPENSSL_NO_ENGINE
                 if (e)
                     ENGINE_finish(e);
 #endif
                 return r;
             }
         }
         return 0;
     }
 
     /* Permit older strings */
 
     if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509))
         return 1;
 
     if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) &&
         !strcmp(name, PEM_STRING_X509_REQ))
         return 1;
 
     /* Allow normal certs to be read as trusted certs */
     if (!strcmp(nm, PEM_STRING_X509) &&
         !strcmp(name, PEM_STRING_X509_TRUSTED))
         return 1;
 
     if (!strcmp(nm, PEM_STRING_X509_OLD) &&
         !strcmp(name, PEM_STRING_X509_TRUSTED))
         return 1;
 
     /* Some CAs use PKCS#7 with CERTIFICATE headers */
     if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7))
         return 1;
 
     if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) &&
         !strcmp(name, PEM_STRING_PKCS7))
         return 1;
 
 #ifndef OPENSSL_NO_CMS
     if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS))
         return 1;
     /* Allow CMS to be read from PKCS#7 headers */
     if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS))
         return 1;
 #endif
 
     return 0;
 }
 
 int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm,
                        const char *name, BIO *bp, pem_password_cb *cb,
                        void *u)
 {
     EVP_CIPHER_INFO cipher;
     char *nm = NULL, *header = NULL;
     unsigned char *data = NULL;
     long len;
     int ret = 0;
 
     for (;;) {
         if (!PEM_read_bio(bp, &nm, &header, &data, &len)) {
             if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE)
                 ERR_add_error_data(2, "Expecting: ", name);
             return 0;
         }
         if (check_pem(nm, name))
             break;
         OPENSSL_free(nm);
         OPENSSL_free(header);
         OPENSSL_free(data);
     }
     if (!PEM_get_EVP_CIPHER_INFO(header, &cipher))
         goto err;
     if (!PEM_do_header(&cipher, data, &len, cb, u))
         goto err;
 
     *pdata = data;
     *plen = len;
 
     if (pnm)
         *pnm = nm;
 
     ret = 1;
 
  err:
     if (!ret || !pnm)
         OPENSSL_free(nm);
     OPENSSL_free(header);
     if (!ret)
         OPENSSL_free(data);
     return ret;
 }
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
                    void *x, const EVP_CIPHER *enc, unsigned char *kstr,
                    int klen, pem_password_cb *callback, void *u)
 {
     BIO *b;
     int ret;
 
     if ((b = BIO_new(BIO_s_file())) == NULL) {
         PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB);
         return (0);
     }
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u);
     BIO_free(b);
     return (ret);
 }
 #endif
 
 int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
                        void *x, const EVP_CIPHER *enc, unsigned char *kstr,
                        int klen, pem_password_cb *callback, void *u)
 {
     EVP_CIPHER_CTX ctx;
     int dsize = 0, i, j, ret = 0;
     unsigned char *p, *data = NULL;
     const char *objstr = NULL;
     char buf[PEM_BUFSIZE];
     unsigned char key[EVP_MAX_KEY_LENGTH];
     unsigned char iv[EVP_MAX_IV_LENGTH];
 
     if (enc != NULL) {
         objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc));
         if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) {
             PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER);
             goto err;
         }
     }
 
     if ((dsize = i2d(x, NULL)) < 0) {
         PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB);
         dsize = 0;
         goto err;
     }
     /* dzise + 8 bytes are needed */
     /* actually it needs the cipher block size extra... */
     data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20);
     if (data == NULL) {
         PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     p = data;
     i = i2d(x, &p);
 
     if (enc != NULL) {
         if (kstr == NULL) {
             if (callback == NULL)
                 klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u);
             else
                 klen = (*callback) (buf, PEM_BUFSIZE, 1, u);
             if (klen <= 0) {
                 PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY);
                 goto err;
             }
 #ifdef CHARSET_EBCDIC
             /* Convert the pass phrase from EBCDIC */
             ebcdic2ascii(buf, buf, klen);
 #endif
             kstr = (unsigned char *)buf;
         }
         RAND_add(data, i, 0);   /* put in the RSA key. */
         OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
-        if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) /* Generate a salt */
+        if (RAND_bytes(iv, enc->iv_len) <= 0) /* Generate a salt */
             goto err;
         /*
          * The 'iv' is used as the iv and as a salt.  It is NOT taken from
          * the BytesToKey function
          */
         if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL))
             goto err;
 
         if (kstr == (unsigned char *)buf)
             OPENSSL_cleanse(buf, PEM_BUFSIZE);
 
         OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <=
                        sizeof buf);
 
         buf[0] = '\0';
         PEM_proc_type(buf, PEM_TYPE_ENCRYPTED);
         PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv);
         /* k=strlen(buf); */
 
         EVP_CIPHER_CTX_init(&ctx);
         ret = 1;
         if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv)
             || !EVP_EncryptUpdate(&ctx, data, &j, data, i)
             || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i))
             ret = 0;
         EVP_CIPHER_CTX_cleanup(&ctx);
         if (ret == 0)
             goto err;
         i += j;
     } else {
         ret = 1;
         buf[0] = '\0';
     }
     i = PEM_write_bio(bp, name, buf, data, i);
     if (i <= 0)
         ret = 0;
  err:
     OPENSSL_cleanse(key, sizeof(key));
     OPENSSL_cleanse(iv, sizeof(iv));
     OPENSSL_cleanse((char *)&ctx, sizeof(ctx));
     OPENSSL_cleanse(buf, PEM_BUFSIZE);
     if (data != NULL) {
         OPENSSL_cleanse(data, (unsigned int)dsize);
         OPENSSL_free(data);
     }
     return (ret);
 }
 
 int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
                   pem_password_cb *callback, void *u)
 {
     int i = 0, j, o, klen;
     long len;
     EVP_CIPHER_CTX ctx;
     unsigned char key[EVP_MAX_KEY_LENGTH];
     char buf[PEM_BUFSIZE];
 
     len = *plen;
 
     if (cipher->cipher == NULL)
         return (1);
     if (callback == NULL)
         klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u);
     else
         klen = callback(buf, PEM_BUFSIZE, 0, u);
     if (klen <= 0) {
         PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ);
         return (0);
     }
 #ifdef CHARSET_EBCDIC
     /* Convert the pass phrase from EBCDIC */
     ebcdic2ascii(buf, buf, klen);
 #endif
 
     if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]),
                         (unsigned char *)buf, klen, 1, key, NULL))
         return 0;
 
     j = (int)len;
     EVP_CIPHER_CTX_init(&ctx);
     o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0]));
     if (o)
         o = EVP_DecryptUpdate(&ctx, data, &i, data, j);
     if (o)
         o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j);
     EVP_CIPHER_CTX_cleanup(&ctx);
     OPENSSL_cleanse((char *)buf, sizeof(buf));
     OPENSSL_cleanse((char *)key, sizeof(key));
     j += i;
     if (!o) {
         PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT);
         return (0);
     }
     *plen = j;
     return (1);
 }
 
 int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
 {
     const EVP_CIPHER *enc = NULL;
     char *p, c;
     char **header_pp = &header;
 
     cipher->cipher = NULL;
     if ((header == NULL) || (*header == '\0') || (*header == '\n'))
         return (1);
     if (strncmp(header, "Proc-Type: ", 11) != 0) {
         PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE);
         return (0);
     }
     header += 11;
     if (*header != '4')
         return (0);
     header++;
     if (*header != ',')
         return (0);
     header++;
     if (strncmp(header, "ENCRYPTED", 9) != 0) {
         PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED);
         return (0);
     }
     for (; (*header != '\n') && (*header != '\0'); header++) ;
     if (*header == '\0') {
         PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER);
         return (0);
     }
     header++;
     if (strncmp(header, "DEK-Info: ", 10) != 0) {
         PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO);
         return (0);
     }
     header += 10;
 
     p = header;
     for (;;) {
         c = *header;
 #ifndef CHARSET_EBCDIC
         if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') ||
               ((c >= '0') && (c <= '9'))))
             break;
 #else
         if (!(isupper(c) || (c == '-') || isdigit(c)))
             break;
 #endif
         header++;
     }
     *header = '\0';
     cipher->cipher = enc = EVP_get_cipherbyname(p);
     *header = c;
     header++;
 
     if (enc == NULL) {
         PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
         return (0);
     }
     if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len))
         return (0);
 
     return (1);
 }
 
 static int load_iv(char **fromp, unsigned char *to, int num)
 {
     int v, i;
     char *from;
 
     from = *fromp;
     for (i = 0; i < num; i++)
         to[i] = 0;
     num *= 2;
     for (i = 0; i < num; i++) {
         if ((*from >= '0') && (*from <= '9'))
             v = *from - '0';
         else if ((*from >= 'A') && (*from <= 'F'))
             v = *from - 'A' + 10;
         else if ((*from >= 'a') && (*from <= 'f'))
             v = *from - 'a' + 10;
         else {
             PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS);
             return (0);
         }
         from++;
         to[i / 2] |= v << (long)((!(i & 1)) * 4);
     }
 
     *fromp = from;
     return (1);
 }
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_write(FILE *fp, char *name, char *header, unsigned char *data,
               long len)
 {
     BIO *b;
     int ret;
 
     if ((b = BIO_new(BIO_s_file())) == NULL) {
         PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB);
         return (0);
     }
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     ret = PEM_write_bio(b, name, header, data, len);
     BIO_free(b);
     return (ret);
 }
 #endif
 
 int PEM_write_bio(BIO *bp, const char *name, char *header,
                   unsigned char *data, long len)
 {
     int nlen, n, i, j, outl;
     unsigned char *buf = NULL;
     EVP_ENCODE_CTX ctx;
     int reason = ERR_R_BUF_LIB;
 
     EVP_EncodeInit(&ctx);
     nlen = strlen(name);
 
     if ((BIO_write(bp, "-----BEGIN ", 11) != 11) ||
         (BIO_write(bp, name, nlen) != nlen) ||
         (BIO_write(bp, "-----\n", 6) != 6))
         goto err;
 
     i = strlen(header);
     if (i > 0) {
         if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1))
             goto err;
     }
 
     buf = OPENSSL_malloc(PEM_BUFSIZE * 8);
     if (buf == NULL) {
         reason = ERR_R_MALLOC_FAILURE;
         goto err;
     }
 
     i = j = 0;
     while (len > 0) {
         n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len);
         EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n);
         if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl))
             goto err;
         i += outl;
         len -= n;
         j += n;
     }
     EVP_EncodeFinal(&ctx, buf, &outl);
     if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl))
         goto err;
     OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
     OPENSSL_free(buf);
     buf = NULL;
     if ((BIO_write(bp, "-----END ", 9) != 9) ||
         (BIO_write(bp, name, nlen) != nlen) ||
         (BIO_write(bp, "-----\n", 6) != 6))
         goto err;
     return (i + outl);
  err:
     if (buf) {
         OPENSSL_cleanse(buf, PEM_BUFSIZE * 8);
         OPENSSL_free(buf);
     }
     PEMerr(PEM_F_PEM_WRITE_BIO, reason);
     return (0);
 }
 
 #ifndef OPENSSL_NO_FP_API
 int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
              long *len)
 {
     BIO *b;
     int ret;
 
     if ((b = BIO_new(BIO_s_file())) == NULL) {
         PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB);
         return (0);
     }
     BIO_set_fp(b, fp, BIO_NOCLOSE);
     ret = PEM_read_bio(b, name, header, data, len);
     BIO_free(b);
     return (ret);
 }
 #endif
 
 int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
                  long *len)
 {
     EVP_ENCODE_CTX ctx;
     int end = 0, i, k, bl = 0, hl = 0, nohead = 0;
     char buf[256];
     BUF_MEM *nameB;
     BUF_MEM *headerB;
     BUF_MEM *dataB, *tmpB;
 
     nameB = BUF_MEM_new();
     headerB = BUF_MEM_new();
     dataB = BUF_MEM_new();
     if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) {
         BUF_MEM_free(nameB);
         BUF_MEM_free(headerB);
         BUF_MEM_free(dataB);
         PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
         return (0);
     }
 
     buf[254] = '\0';
     for (;;) {
         i = BIO_gets(bp, buf, 254);
 
         if (i <= 0) {
             PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE);
             goto err;
         }
 
         while ((i >= 0) && (buf[i] <= ' '))
             i--;
         buf[++i] = '\n';
         buf[++i] = '\0';
 
         if (strncmp(buf, "-----BEGIN ", 11) == 0) {
             i = strlen(&(buf[11]));
 
             if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0)
                 continue;
             if (!BUF_MEM_grow(nameB, i + 9)) {
                 PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             memcpy(nameB->data, &(buf[11]), i - 6);
             nameB->data[i - 6] = '\0';
             break;
         }
     }
     hl = 0;
     if (!BUF_MEM_grow(headerB, 256)) {
         PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     headerB->data[0] = '\0';
     for (;;) {
         i = BIO_gets(bp, buf, 254);
         if (i <= 0)
             break;
 
         while ((i >= 0) && (buf[i] <= ' '))
             i--;
         buf[++i] = '\n';
         buf[++i] = '\0';
 
         if (buf[0] == '\n')
             break;
         if (!BUF_MEM_grow(headerB, hl + i + 9)) {
             PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (strncmp(buf, "-----END ", 9) == 0) {
             nohead = 1;
             break;
         }
         memcpy(&(headerB->data[hl]), buf, i);
         headerB->data[hl + i] = '\0';
         hl += i;
     }
 
     bl = 0;
     if (!BUF_MEM_grow(dataB, 1024)) {
         PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     dataB->data[0] = '\0';
     if (!nohead) {
         for (;;) {
             i = BIO_gets(bp, buf, 254);
             if (i <= 0)
                 break;
 
             while ((i >= 0) && (buf[i] <= ' '))
                 i--;
             buf[++i] = '\n';
             buf[++i] = '\0';
 
             if (i != 65)
                 end = 1;
             if (strncmp(buf, "-----END ", 9) == 0)
                 break;
             if (i > 65)
                 break;
             if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) {
                 PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             memcpy(&(dataB->data[bl]), buf, i);
             dataB->data[bl + i] = '\0';
             bl += i;
             if (end) {
                 buf[0] = '\0';
                 i = BIO_gets(bp, buf, 254);
                 if (i <= 0)
                     break;
 
                 while ((i >= 0) && (buf[i] <= ' '))
                     i--;
                 buf[++i] = '\n';
                 buf[++i] = '\0';
 
                 break;
             }
         }
     } else {
         tmpB = headerB;
         headerB = dataB;
         dataB = tmpB;
         bl = hl;
     }
     i = strlen(nameB->data);
     if ((strncmp(buf, "-----END ", 9) != 0) ||
         (strncmp(nameB->data, &(buf[9]), i) != 0) ||
         (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) {
         PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE);
         goto err;
     }
 
     EVP_DecodeInit(&ctx);
     i = EVP_DecodeUpdate(&ctx,
                          (unsigned char *)dataB->data, &bl,
                          (unsigned char *)dataB->data, bl);
     if (i < 0) {
         PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
         goto err;
     }
     i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k);
     if (i < 0) {
         PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE);
         goto err;
     }
     bl += k;
 
     if (bl == 0)
         goto err;
     *name = nameB->data;
     *header = headerB->data;
     *data = (unsigned char *)dataB->data;
     *len = bl;
     OPENSSL_free(nameB);
     OPENSSL_free(headerB);
     OPENSSL_free(dataB);
     return (1);
  err:
     BUF_MEM_free(nameB);
     BUF_MEM_free(headerB);
     BUF_MEM_free(dataB);
     return (0);
 }
 
 /*
  * Check pem string and return prefix length. If for example the pem_str ==
  * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the
  * string "RSA".
  */
 
 int pem_check_suffix(const char *pem_str, const char *suffix)
 {
     int pem_len = strlen(pem_str);
     int suffix_len = strlen(suffix);
     const char *p;
     if (suffix_len + 1 >= pem_len)
         return 0;
     p = pem_str + pem_len - suffix_len;
     if (strcmp(p, suffix))
         return 0;
     p--;
     if (*p != ' ')
         return 0;
     return p - pem_str;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pem/pvkfmt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pem/pvkfmt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pem/pvkfmt.c	(revision 306191)
@@ -1,888 +1,895 @@
 /*
  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
  * 2005.
  */
 /* ====================================================================
  * Copyright (c) 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
  *    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).
  *
  */
 
 /*
  * Support for PVK format keys and related structures (such a PUBLICKEYBLOB
  * and PRIVATEKEYBLOB).
  */
 
 #include "cryptlib.h"
 #include <openssl/pem.h>
 #include <openssl/rand.h>
 #include <openssl/bn.h>
 #if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA)
 # include <openssl/dsa.h>
 # include <openssl/rsa.h>
 
 /*
  * Utility function: read a DWORD (4 byte unsigned integer) in little endian
  * format
  */
 
 static unsigned int read_ledword(const unsigned char **in)
 {
     const unsigned char *p = *in;
     unsigned int ret;
     ret = *p++;
     ret |= (*p++ << 8);
     ret |= (*p++ << 16);
     ret |= (*p++ << 24);
     *in = p;
     return ret;
 }
 
 /*
  * Read a BIGNUM in little endian format. The docs say that this should take
  * up bitlen/8 bytes.
  */
 
 static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
 {
     const unsigned char *p;
     unsigned char *tmpbuf, *q;
     unsigned int i;
     p = *in + nbyte - 1;
     tmpbuf = OPENSSL_malloc(nbyte);
     if (!tmpbuf)
         return 0;
     q = tmpbuf;
     for (i = 0; i < nbyte; i++)
         *q++ = *p--;
     *r = BN_bin2bn(tmpbuf, nbyte, NULL);
     OPENSSL_free(tmpbuf);
     if (*r) {
         *in += nbyte;
         return 1;
     } else
         return 0;
 }
 
 /* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */
 
 # define MS_PUBLICKEYBLOB        0x6
 # define MS_PRIVATEKEYBLOB       0x7
 # define MS_RSA1MAGIC            0x31415352L
 # define MS_RSA2MAGIC            0x32415352L
 # define MS_DSS1MAGIC            0x31535344L
 # define MS_DSS2MAGIC            0x32535344L
 
 # define MS_KEYALG_RSA_KEYX      0xa400
 # define MS_KEYALG_DSS_SIGN      0x2200
 
 # define MS_KEYTYPE_KEYX         0x1
 # define MS_KEYTYPE_SIGN         0x2
 
+/* Maximum length of a blob after header */
+# define BLOB_MAX_LENGTH          102400
+
 /* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
 # define MS_PVKMAGIC             0xb0b5f11eL
 /* Salt length for PVK files */
 # define PVK_SALTLEN             0x10
 /* Maximum length in PVK header */
 # define PVK_MAX_KEYLEN          102400
 /* Maximum salt length */
 # define PVK_MAX_SALTLEN         10240
 
 static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
                          unsigned int bitlen, int ispub);
 static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
                          unsigned int bitlen, int ispub);
 
 static int do_blob_header(const unsigned char **in, unsigned int length,
                           unsigned int *pmagic, unsigned int *pbitlen,
                           int *pisdss, int *pispub)
 {
     const unsigned char *p = *in;
     if (length < 16)
         return 0;
     /* bType */
     if (*p == MS_PUBLICKEYBLOB) {
         if (*pispub == 0) {
             PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
             return 0;
         }
         *pispub = 1;
     } else if (*p == MS_PRIVATEKEYBLOB) {
         if (*pispub == 1) {
             PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
             return 0;
         }
         *pispub = 0;
     } else
         return 0;
     p++;
     /* Version */
     if (*p++ != 0x2) {
         PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER);
         return 0;
     }
     /* Ignore reserved, aiKeyAlg */
     p += 6;
     *pmagic = read_ledword(&p);
     *pbitlen = read_ledword(&p);
     *pisdss = 0;
     switch (*pmagic) {
 
     case MS_DSS1MAGIC:
         *pisdss = 1;
     case MS_RSA1MAGIC:
         if (*pispub == 0) {
             PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB);
             return 0;
         }
         break;
 
     case MS_DSS2MAGIC:
         *pisdss = 1;
     case MS_RSA2MAGIC:
         if (*pispub == 1) {
             PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB);
             return 0;
         }
         break;
 
     default:
         PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER);
         return -1;
     }
     *in = p;
     return 1;
 }
 
 static unsigned int blob_length(unsigned bitlen, int isdss, int ispub)
 {
     unsigned int nbyte, hnbyte;
     nbyte = (bitlen + 7) >> 3;
     hnbyte = (bitlen + 15) >> 4;
     if (isdss) {
 
         /*
          * Expected length: 20 for q + 3 components bitlen each + 24 for seed
          * structure.
          */
         if (ispub)
             return 44 + 3 * nbyte;
         /*
          * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed
          * structure.
          */
         else
             return 64 + 2 * nbyte;
     } else {
         /* Expected length: 4 for 'e' + 'n' */
         if (ispub)
             return 4 + nbyte;
         else
             /*
              * Expected length: 4 for 'e' and 7 other components. 2
              * components are bitlen size, 5 are bitlen/2
              */
             return 4 + 2 * nbyte + 5 * hnbyte;
     }
 
 }
 
 static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length,
                         int ispub)
 {
     const unsigned char *p = *in;
     unsigned int bitlen, magic;
     int isdss;
     if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) {
         PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR);
         return NULL;
     }
     length -= 16;
     if (length < blob_length(bitlen, isdss, ispub)) {
         PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT);
         return NULL;
     }
     if (isdss)
         return b2i_dss(&p, length, bitlen, ispub);
     else
         return b2i_rsa(&p, length, bitlen, ispub);
 }
 
 static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
 {
     const unsigned char *p;
     unsigned char hdr_buf[16], *buf = NULL;
     unsigned int bitlen, magic, length;
     int isdss;
     EVP_PKEY *ret = NULL;
     if (BIO_read(in, hdr_buf, 16) != 16) {
         PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
         return NULL;
     }
     p = hdr_buf;
     if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0)
         return NULL;
 
     length = blob_length(bitlen, isdss, ispub);
+    if (length > BLOB_MAX_LENGTH) {
+        PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG);
+        return NULL;
+    }
     buf = OPENSSL_malloc(length);
     if (!buf) {
         PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     p = buf;
     if (BIO_read(in, buf, length) != (int)length) {
         PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT);
         goto err;
     }
 
     if (isdss)
         ret = b2i_dss(&p, length, bitlen, ispub);
     else
         ret = b2i_rsa(&p, length, bitlen, ispub);
 
  err:
     if (buf)
         OPENSSL_free(buf);
     return ret;
 }
 
 static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length,
                          unsigned int bitlen, int ispub)
 {
     const unsigned char *p = *in;
     EVP_PKEY *ret = NULL;
     DSA *dsa = NULL;
     BN_CTX *ctx = NULL;
     unsigned int nbyte;
     nbyte = (bitlen + 7) >> 3;
 
     dsa = DSA_new();
     ret = EVP_PKEY_new();
     if (!dsa || !ret)
         goto memerr;
     if (!read_lebn(&p, nbyte, &dsa->p))
         goto memerr;
     if (!read_lebn(&p, 20, &dsa->q))
         goto memerr;
     if (!read_lebn(&p, nbyte, &dsa->g))
         goto memerr;
     if (ispub) {
         if (!read_lebn(&p, nbyte, &dsa->pub_key))
             goto memerr;
     } else {
         if (!read_lebn(&p, 20, &dsa->priv_key))
             goto memerr;
         /* Calculate public key */
         if (!(dsa->pub_key = BN_new()))
             goto memerr;
         if (!(ctx = BN_CTX_new()))
             goto memerr;
 
         if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
 
             goto memerr;
         BN_CTX_free(ctx);
     }
 
     EVP_PKEY_set1_DSA(ret, dsa);
     DSA_free(dsa);
     *in = p;
     return ret;
 
  memerr:
     PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE);
     if (dsa)
         DSA_free(dsa);
     if (ret)
         EVP_PKEY_free(ret);
     if (ctx)
         BN_CTX_free(ctx);
     return NULL;
 }
 
 static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length,
                          unsigned int bitlen, int ispub)
 {
     const unsigned char *p = *in;
     EVP_PKEY *ret = NULL;
     RSA *rsa = NULL;
     unsigned int nbyte, hnbyte;
     nbyte = (bitlen + 7) >> 3;
     hnbyte = (bitlen + 15) >> 4;
     rsa = RSA_new();
     ret = EVP_PKEY_new();
     if (!rsa || !ret)
         goto memerr;
     rsa->e = BN_new();
     if (!rsa->e)
         goto memerr;
     if (!BN_set_word(rsa->e, read_ledword(&p)))
         goto memerr;
     if (!read_lebn(&p, nbyte, &rsa->n))
         goto memerr;
     if (!ispub) {
         if (!read_lebn(&p, hnbyte, &rsa->p))
             goto memerr;
         if (!read_lebn(&p, hnbyte, &rsa->q))
             goto memerr;
         if (!read_lebn(&p, hnbyte, &rsa->dmp1))
             goto memerr;
         if (!read_lebn(&p, hnbyte, &rsa->dmq1))
             goto memerr;
         if (!read_lebn(&p, hnbyte, &rsa->iqmp))
             goto memerr;
         if (!read_lebn(&p, nbyte, &rsa->d))
             goto memerr;
     }
 
     EVP_PKEY_set1_RSA(ret, rsa);
     RSA_free(rsa);
     *in = p;
     return ret;
  memerr:
     PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE);
     if (rsa)
         RSA_free(rsa);
     if (ret)
         EVP_PKEY_free(ret);
     return NULL;
 }
 
 EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length)
 {
     return do_b2i(in, length, 0);
 }
 
 EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length)
 {
     return do_b2i(in, length, 1);
 }
 
 EVP_PKEY *b2i_PrivateKey_bio(BIO *in)
 {
     return do_b2i_bio(in, 0);
 }
 
 EVP_PKEY *b2i_PublicKey_bio(BIO *in)
 {
     return do_b2i_bio(in, 1);
 }
 
 static void write_ledword(unsigned char **out, unsigned int dw)
 {
     unsigned char *p = *out;
     *p++ = dw & 0xff;
     *p++ = (dw >> 8) & 0xff;
     *p++ = (dw >> 16) & 0xff;
     *p++ = (dw >> 24) & 0xff;
     *out = p;
 }
 
 static void write_lebn(unsigned char **out, const BIGNUM *bn, int len)
 {
     int nb, i;
     unsigned char *p = *out, *q, c;
     nb = BN_num_bytes(bn);
     BN_bn2bin(bn, p);
     q = p + nb - 1;
     /* In place byte order reversal */
     for (i = 0; i < nb / 2; i++) {
         c = *p;
         *p++ = *q;
         *q-- = c;
     }
     *out += nb;
     /* Pad with zeroes if we have to */
     if (len > 0) {
         len -= nb;
         if (len > 0) {
             memset(*out, 0, len);
             *out += len;
         }
     }
 }
 
 static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic);
 static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic);
 
 static void write_rsa(unsigned char **out, RSA *rsa, int ispub);
 static void write_dsa(unsigned char **out, DSA *dsa, int ispub);
 
 static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub)
 {
     unsigned char *p;
     unsigned int bitlen, magic = 0, keyalg;
     int outlen, noinc = 0;
     if (pk->type == EVP_PKEY_DSA) {
         bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic);
         keyalg = MS_KEYALG_DSS_SIGN;
     } else if (pk->type == EVP_PKEY_RSA) {
         bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic);
         keyalg = MS_KEYALG_RSA_KEYX;
     } else
         return -1;
     if (bitlen == 0)
         return -1;
     outlen = 16 + blob_length(bitlen,
                               keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub);
     if (out == NULL)
         return outlen;
     if (*out)
         p = *out;
     else {
         p = OPENSSL_malloc(outlen);
         if (!p)
             return -1;
         *out = p;
         noinc = 1;
     }
     if (ispub)
         *p++ = MS_PUBLICKEYBLOB;
     else
         *p++ = MS_PRIVATEKEYBLOB;
     *p++ = 0x2;
     *p++ = 0;
     *p++ = 0;
     write_ledword(&p, keyalg);
     write_ledword(&p, magic);
     write_ledword(&p, bitlen);
     if (keyalg == MS_KEYALG_DSS_SIGN)
         write_dsa(&p, pk->pkey.dsa, ispub);
     else
         write_rsa(&p, pk->pkey.rsa, ispub);
     if (!noinc)
         *out += outlen;
     return outlen;
 }
 
 static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub)
 {
     unsigned char *tmp = NULL;
     int outlen, wrlen;
     outlen = do_i2b(&tmp, pk, ispub);
     if (outlen < 0)
         return -1;
     wrlen = BIO_write(out, tmp, outlen);
     OPENSSL_free(tmp);
     if (wrlen == outlen)
         return outlen;
     return -1;
 }
 
 static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic)
 {
     int bitlen;
     bitlen = BN_num_bits(dsa->p);
     if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160)
         || (BN_num_bits(dsa->g) > bitlen))
         goto badkey;
     if (ispub) {
         if (BN_num_bits(dsa->pub_key) > bitlen)
             goto badkey;
         *pmagic = MS_DSS1MAGIC;
     } else {
         if (BN_num_bits(dsa->priv_key) > 160)
             goto badkey;
         *pmagic = MS_DSS2MAGIC;
     }
 
     return bitlen;
  badkey:
     PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
     return 0;
 }
 
 static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic)
 {
     int nbyte, hnbyte, bitlen;
     if (BN_num_bits(rsa->e) > 32)
         goto badkey;
     bitlen = BN_num_bits(rsa->n);
     nbyte = BN_num_bytes(rsa->n);
     hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
     if (ispub) {
         *pmagic = MS_RSA1MAGIC;
         return bitlen;
     } else {
         *pmagic = MS_RSA2MAGIC;
         /*
          * For private key each component must fit within nbyte or hnbyte.
          */
         if (BN_num_bytes(rsa->d) > nbyte)
             goto badkey;
         if ((BN_num_bytes(rsa->iqmp) > hnbyte)
             || (BN_num_bytes(rsa->p) > hnbyte)
             || (BN_num_bytes(rsa->q) > hnbyte)
             || (BN_num_bytes(rsa->dmp1) > hnbyte)
             || (BN_num_bytes(rsa->dmq1) > hnbyte))
             goto badkey;
     }
     return bitlen;
  badkey:
     PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS);
     return 0;
 }
 
 static void write_rsa(unsigned char **out, RSA *rsa, int ispub)
 {
     int nbyte, hnbyte;
     nbyte = BN_num_bytes(rsa->n);
     hnbyte = (BN_num_bits(rsa->n) + 15) >> 4;
     write_lebn(out, rsa->e, 4);
     write_lebn(out, rsa->n, -1);
     if (ispub)
         return;
     write_lebn(out, rsa->p, hnbyte);
     write_lebn(out, rsa->q, hnbyte);
     write_lebn(out, rsa->dmp1, hnbyte);
     write_lebn(out, rsa->dmq1, hnbyte);
     write_lebn(out, rsa->iqmp, hnbyte);
     write_lebn(out, rsa->d, nbyte);
 }
 
 static void write_dsa(unsigned char **out, DSA *dsa, int ispub)
 {
     int nbyte;
     nbyte = BN_num_bytes(dsa->p);
     write_lebn(out, dsa->p, nbyte);
     write_lebn(out, dsa->q, 20);
     write_lebn(out, dsa->g, nbyte);
     if (ispub)
         write_lebn(out, dsa->pub_key, nbyte);
     else
         write_lebn(out, dsa->priv_key, 20);
     /* Set "invalid" for seed structure values */
     memset(*out, 0xff, 24);
     *out += 24;
     return;
 }
 
 int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk)
 {
     return do_i2b_bio(out, pk, 0);
 }
 
 int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk)
 {
     return do_i2b_bio(out, pk, 1);
 }
 
 # ifndef OPENSSL_NO_RC4
 
 static int do_PVK_header(const unsigned char **in, unsigned int length,
                          int skip_magic,
                          unsigned int *psaltlen, unsigned int *pkeylen)
 {
     const unsigned char *p = *in;
     unsigned int pvk_magic, is_encrypted;
     if (skip_magic) {
         if (length < 20) {
             PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
             return 0;
         }
     } else {
         if (length < 24) {
             PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT);
             return 0;
         }
         pvk_magic = read_ledword(&p);
         if (pvk_magic != MS_PVKMAGIC) {
             PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER);
             return 0;
         }
     }
     /* Skip reserved */
     p += 4;
     /*
      * keytype =
      */ read_ledword(&p);
     is_encrypted = read_ledword(&p);
     *psaltlen = read_ledword(&p);
     *pkeylen = read_ledword(&p);
 
     if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN)
         return 0;
 
     if (is_encrypted && !*psaltlen) {
         PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER);
         return 0;
     }
 
     *in = p;
     return 1;
 }
 
 static int derive_pvk_key(unsigned char *key,
                           const unsigned char *salt, unsigned int saltlen,
                           const unsigned char *pass, int passlen)
 {
     EVP_MD_CTX mctx;
     int rv = 1;
     EVP_MD_CTX_init(&mctx);
     if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL)
         || !EVP_DigestUpdate(&mctx, salt, saltlen)
         || !EVP_DigestUpdate(&mctx, pass, passlen)
         || !EVP_DigestFinal_ex(&mctx, key, NULL))
         rv = 0;
 
     EVP_MD_CTX_cleanup(&mctx);
     return rv;
 }
 
 static EVP_PKEY *do_PVK_body(const unsigned char **in,
                              unsigned int saltlen, unsigned int keylen,
                              pem_password_cb *cb, void *u)
 {
     EVP_PKEY *ret = NULL;
     const unsigned char *p = *in;
     unsigned int magic;
     unsigned char *enctmp = NULL, *q;
     EVP_CIPHER_CTX cctx;
     EVP_CIPHER_CTX_init(&cctx);
     if (saltlen) {
         char psbuf[PEM_BUFSIZE];
         unsigned char keybuf[20];
         int enctmplen, inlen;
         if (cb)
             inlen = cb(psbuf, PEM_BUFSIZE, 0, u);
         else
             inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u);
         if (inlen <= 0) {
             PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ);
             goto err;
         }
         enctmp = OPENSSL_malloc(keylen + 8);
         if (!enctmp) {
             PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         if (!derive_pvk_key(keybuf, p, saltlen,
                             (unsigned char *)psbuf, inlen))
             goto err;
         p += saltlen;
         /* Copy BLOBHEADER across, decrypt rest */
         memcpy(enctmp, p, 8);
         p += 8;
         if (keylen < 8) {
             PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT);
             goto err;
         }
         inlen = keylen - 8;
         q = enctmp + 8;
         if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
             goto err;
         if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
             goto err;
         if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
             goto err;
         magic = read_ledword((const unsigned char **)&q);
         if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
             q = enctmp + 8;
             memset(keybuf + 5, 0, 11);
             if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
                 goto err;
             OPENSSL_cleanse(keybuf, 20);
             if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen))
                 goto err;
             if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen))
                 goto err;
             magic = read_ledword((const unsigned char **)&q);
             if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) {
                 PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT);
                 goto err;
             }
         } else
             OPENSSL_cleanse(keybuf, 20);
         p = enctmp;
     }
 
     ret = b2i_PrivateKey(&p, keylen);
  err:
     EVP_CIPHER_CTX_cleanup(&cctx);
     if (enctmp && saltlen)
         OPENSSL_free(enctmp);
     return ret;
 }
 
 EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u)
 {
     unsigned char pvk_hdr[24], *buf = NULL;
     const unsigned char *p;
     int buflen;
     EVP_PKEY *ret = NULL;
     unsigned int saltlen, keylen;
     if (BIO_read(in, pvk_hdr, 24) != 24) {
         PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
         return NULL;
     }
     p = pvk_hdr;
 
     if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen))
         return 0;
     buflen = (int)keylen + saltlen;
     buf = OPENSSL_malloc(buflen);
     if (!buf) {
         PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     p = buf;
     if (BIO_read(in, buf, buflen) != buflen) {
         PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT);
         goto err;
     }
     ret = do_PVK_body(&p, saltlen, keylen, cb, u);
 
  err:
     if (buf) {
         OPENSSL_cleanse(buf, buflen);
         OPENSSL_free(buf);
     }
     return ret;
 }
 
 static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel,
                    pem_password_cb *cb, void *u)
 {
     int outlen = 24, pklen;
     unsigned char *p, *salt = NULL;
     EVP_CIPHER_CTX cctx;
     EVP_CIPHER_CTX_init(&cctx);
     if (enclevel)
         outlen += PVK_SALTLEN;
     pklen = do_i2b(NULL, pk, 0);
     if (pklen < 0)
         return -1;
     outlen += pklen;
     if (!out)
         return outlen;
     if (*out)
         p = *out;
     else {
         p = OPENSSL_malloc(outlen);
         if (!p) {
             PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE);
             return -1;
         }
         *out = p;
     }
 
     write_ledword(&p, MS_PVKMAGIC);
     write_ledword(&p, 0);
     if (pk->type == EVP_PKEY_DSA)
         write_ledword(&p, MS_KEYTYPE_SIGN);
     else
         write_ledword(&p, MS_KEYTYPE_KEYX);
     write_ledword(&p, enclevel ? 1 : 0);
     write_ledword(&p, enclevel ? PVK_SALTLEN : 0);
     write_ledword(&p, pklen);
     if (enclevel) {
         if (RAND_bytes(p, PVK_SALTLEN) <= 0)
             goto error;
         salt = p;
         p += PVK_SALTLEN;
     }
     do_i2b(&p, pk, 0);
     if (enclevel == 0)
         return outlen;
     else {
         char psbuf[PEM_BUFSIZE];
         unsigned char keybuf[20];
         int enctmplen, inlen;
         if (cb)
             inlen = cb(psbuf, PEM_BUFSIZE, 1, u);
         else
             inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u);
         if (inlen <= 0) {
             PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ);
             goto error;
         }
         if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN,
                             (unsigned char *)psbuf, inlen))
             goto error;
         if (enclevel == 1)
             memset(keybuf + 5, 0, 11);
         p = salt + PVK_SALTLEN + 8;
         if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL))
             goto error;
         OPENSSL_cleanse(keybuf, 20);
         if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8))
             goto error;
         if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen))
             goto error;
     }
     EVP_CIPHER_CTX_cleanup(&cctx);
     return outlen;
 
  error:
     EVP_CIPHER_CTX_cleanup(&cctx);
     return -1;
 }
 
 int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
                 pem_password_cb *cb, void *u)
 {
     unsigned char *tmp = NULL;
     int outlen, wrlen;
     outlen = i2b_PVK(&tmp, pk, enclevel, cb, u);
     if (outlen < 0)
         return -1;
     wrlen = BIO_write(out, tmp, outlen);
     OPENSSL_free(tmp);
     if (wrlen == outlen) {
         PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE);
         return outlen;
     }
     return -1;
 }
 
 # endif
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_mutl.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_mutl.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_mutl.c	(revision 306191)
@@ -1,195 +1,195 @@
 /* p12_mutl.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).
  *
  */
 
 #ifndef OPENSSL_NO_HMAC
 # include <stdio.h>
 # include "cryptlib.h"
 # include <openssl/crypto.h>
 # include <openssl/hmac.h>
 # include <openssl/rand.h>
 # include <openssl/pkcs12.h>
 
 /* Generate a MAC */
 int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
                    unsigned char *mac, unsigned int *maclen)
 {
     const EVP_MD *md_type;
     HMAC_CTX hmac;
     unsigned char key[EVP_MAX_MD_SIZE], *salt;
     int saltlen, iter;
     int md_size;
 
     if (!PKCS7_type_is_data(p12->authsafes)) {
         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA);
         return 0;
     }
 
     salt = p12->mac->salt->data;
     saltlen = p12->mac->salt->length;
     if (!p12->mac->iter)
         iter = 1;
     else
         iter = ASN1_INTEGER_get(p12->mac->iter);
     if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) {
         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM);
         return 0;
     }
     md_size = EVP_MD_size(md_type);
     if (md_size < 0)
         return 0;
     if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter,
                         md_size, key, md_type)) {
         PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR);
         return 0;
     }
     HMAC_CTX_init(&hmac);
     if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL)
         || !HMAC_Update(&hmac, p12->authsafes->d.data->data,
                         p12->authsafes->d.data->length)
         || !HMAC_Final(&hmac, mac, maclen)) {
         HMAC_CTX_cleanup(&hmac);
         return 0;
     }
     HMAC_CTX_cleanup(&hmac);
     return 1;
 }
 
 /* Verify the mac */
 int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen)
 {
     unsigned char mac[EVP_MAX_MD_SIZE];
     unsigned int maclen;
     if (p12->mac == NULL) {
         PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT);
         return 0;
     }
     if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
         PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR);
         return 0;
     }
     if ((maclen != (unsigned int)p12->mac->dinfo->digest->length)
         || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen))
         return 0;
     return 1;
 }
 
 /* Set a mac */
 
 int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
                    unsigned char *salt, int saltlen, int iter,
                    const EVP_MD *md_type)
 {
     unsigned char mac[EVP_MAX_MD_SIZE];
     unsigned int maclen;
 
     if (!md_type)
         md_type = EVP_sha1();
     if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) {
         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR);
         return 0;
     }
     if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) {
         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR);
         return 0;
     }
     if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) {
         PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR);
         return 0;
     }
     return 1;
 }
 
 /* Set up a mac structure */
 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
                      const EVP_MD *md_type)
 {
     if (!(p12->mac = PKCS12_MAC_DATA_new()))
         return PKCS12_ERROR;
     if (iter > 1) {
         if (!(p12->mac->iter = M_ASN1_INTEGER_new())) {
             PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
             return 0;
         }
         if (!ASN1_INTEGER_set(p12->mac->iter, iter)) {
             PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
             return 0;
         }
     }
     if (!saltlen)
         saltlen = PKCS12_SALT_LEN;
     if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) {
         PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     p12->mac->salt->length = saltlen;
     if (!salt) {
-        if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0)
+        if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
             return 0;
     } else
         memcpy(p12->mac->salt->data, salt, saltlen);
     p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type));
     if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) {
         PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE);
         return 0;
     }
     p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL;
 
     return 1;
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_npas.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_npas.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_npas.c	(revision 306191)
@@ -1,235 +1,230 @@
 /* p12_npas.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 <stdlib.h>
 #include <string.h>
 #include <openssl/pem.h>
 #include <openssl/err.h>
 #include <openssl/pkcs12.h>
 
 /* PKCS#12 password change routine */
 
-static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
-static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
-                        char *newpass);
-static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+                        const char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+                        const char *newpass);
 static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
 
 /*
  * Change the password on a PKCS#12 structure.
  */
 
-int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
 {
     /* Check for NULL PKCS12 structure */
 
     if (!p12) {
         PKCS12err(PKCS12_F_PKCS12_NEWPASS,
                   PKCS12_R_INVALID_NULL_PKCS12_POINTER);
         return 0;
     }
 
     /* Check the mac */
 
     if (!PKCS12_verify_mac(p12, oldpass, -1)) {
         PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE);
         return 0;
     }
 
     if (!newpass_p12(p12, oldpass, newpass)) {
         PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR);
         return 0;
     }
 
     return 1;
 }
 
 /* Parse the outer PKCS#12 structure */
 
-static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
 {
-    STACK_OF(PKCS7) *asafes, *newsafes;
-    STACK_OF(PKCS12_SAFEBAG) *bags;
+    STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL;
+    STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
     int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
     PKCS7 *p7, *p7new;
-    ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
+    ASN1_OCTET_STRING *p12_data_tmp = NULL;
     unsigned char mac[EVP_MAX_MD_SIZE];
     unsigned int maclen;
+    int rv = 0;
 
-    if (!(asafes = PKCS12_unpack_authsafes(p12)))
-        return 0;
-    if (!(newsafes = sk_PKCS7_new_null()))
-        return 0;
+    if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
+        goto err;
+    if ((newsafes = sk_PKCS7_new_null()) == NULL)
+        goto err;
     for (i = 0; i < sk_PKCS7_num(asafes); i++) {
         p7 = sk_PKCS7_value(asafes, i);
         bagnid = OBJ_obj2nid(p7->type);
         if (bagnid == NID_pkcs7_data) {
             bags = PKCS12_unpack_p7data(p7);
         } else if (bagnid == NID_pkcs7_encrypted) {
             bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
             if (!alg_get(p7->d.encrypted->enc_data->algorithm,
-                         &pbe_nid, &pbe_iter, &pbe_saltlen)) {
-                sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-                bags = NULL;
-            }
-        } else
+                         &pbe_nid, &pbe_iter, &pbe_saltlen))
+                goto err;
+        } else {
             continue;
-        if (!bags) {
-            sk_PKCS7_pop_free(asafes, PKCS7_free);
-            return 0;
         }
-        if (!newpass_bags(bags, oldpass, newpass)) {
-            sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-            sk_PKCS7_pop_free(asafes, PKCS7_free);
-            return 0;
-        }
+        if (bags == NULL)
+            goto err;
+        if (!newpass_bags(bags, oldpass, newpass))
+            goto err;
         /* Repack bag in same form with new password */
         if (bagnid == NID_pkcs7_data)
             p7new = PKCS12_pack_p7data(bags);
         else
             p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
                                           pbe_saltlen, pbe_iter, bags);
+        if (!p7new || !sk_PKCS7_push(newsafes, p7new))
+            goto err;
         sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
-        if (!p7new) {
-            sk_PKCS7_pop_free(asafes, PKCS7_free);
-            return 0;
-        }
-        sk_PKCS7_push(newsafes, p7new);
+        bags = NULL;
     }
-    sk_PKCS7_pop_free(asafes, PKCS7_free);
 
     /* Repack safe: save old safe in case of error */
 
     p12_data_tmp = p12->authsafes->d.data;
-    if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new()))
-        goto saferr;
+    if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL)
+        goto err;
     if (!PKCS12_pack_authsafes(p12, newsafes))
-        goto saferr;
-
+        goto err;
     if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
-        goto saferr;
-    if (!(macnew = ASN1_OCTET_STRING_new()))
-        goto saferr;
-    if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
-        goto saferr;
-    ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
-    p12->mac->dinfo->digest = macnew;
-    ASN1_OCTET_STRING_free(p12_data_tmp);
+        goto err;
+    if (!ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))
+        goto err;
 
-    return 1;
+    rv = 1;
 
- saferr:
-    /* Restore old safe */
-    ASN1_OCTET_STRING_free(p12->authsafes->d.data);
-    ASN1_OCTET_STRING_free(macnew);
-    p12->authsafes->d.data = p12_data_tmp;
-    return 0;
-
+err:
+    /* Restore old safe if necessary */
+    if (rv == 1) {
+        ASN1_OCTET_STRING_free(p12_data_tmp);
+    } else if (p12_data_tmp != NULL) {
+        ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+        p12->authsafes->d.data = p12_data_tmp;
+    }
+    sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+    sk_PKCS7_pop_free(asafes, PKCS7_free);
+    sk_PKCS7_pop_free(newsafes, PKCS7_free);
+    return rv;
 }
 
-static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
-                        char *newpass)
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+                        const char *newpass)
 {
     int i;
     for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
         if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass))
             return 0;
     }
     return 1;
 }
 
 /* Change password of safebag: only needs handle shrouded keybags */
 
-static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+                       const char *newpass)
 {
     PKCS8_PRIV_KEY_INFO *p8;
     X509_SIG *p8new;
     int p8_nid, p8_saltlen, p8_iter;
 
     if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag)
         return 1;
 
     if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1)))
         return 0;
     if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen))
         return 0;
-    if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
-                                p8_iter, p8)))
+    p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
+                          p8_iter, p8);
+    PKCS8_PRIV_KEY_INFO_free(p8);
+    if (p8new == NULL)
         return 0;
     X509_SIG_free(bag->value.shkeybag);
     bag->value.shkeybag = p8new;
     return 1;
 }
 
 static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen)
 {
     PBEPARAM *pbe;
     const unsigned char *p;
 
     p = alg->parameter->value.sequence->data;
     pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length);
     if (!pbe)
         return 0;
     *pnid = OBJ_obj2nid(alg->algorithm);
     *piter = ASN1_INTEGER_get(pbe->iter);
     *psaltlen = pbe->salt->length;
     PBEPARAM_free(pbe);
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_utl.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_utl.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/p12_utl.c	(revision 306191)
@@ -1,161 +1,165 @@
 /* p12_utl.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 "cryptlib.h"
 #include <openssl/pkcs12.h>
 
 /* Cheap and nasty Unicode stuff */
 
 unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
                                unsigned char **uni, int *unilen)
 {
     int ulen, i;
     unsigned char *unitmp;
     if (asclen == -1)
         asclen = strlen(asc);
     ulen = asclen * 2 + 2;
     if (!(unitmp = OPENSSL_malloc(ulen)))
         return NULL;
     for (i = 0; i < ulen - 2; i += 2) {
         unitmp[i] = 0;
         unitmp[i + 1] = asc[i >> 1];
     }
     /* Make result double null terminated */
     unitmp[ulen - 2] = 0;
     unitmp[ulen - 1] = 0;
     if (unilen)
         *unilen = ulen;
     if (uni)
         *uni = unitmp;
     return unitmp;
 }
 
 char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
 {
     int asclen, i;
     char *asctmp;
+
+    /* string must contain an even number of bytes */
+    if (unilen & 1)
+        return NULL;
     asclen = unilen / 2;
     /* If no terminating zero allow for one */
     if (!unilen || uni[unilen - 1])
         asclen++;
     uni++;
     if (!(asctmp = OPENSSL_malloc(asclen)))
         return NULL;
     for (i = 0; i < unilen; i += 2)
         asctmp[i >> 1] = uni[i];
     asctmp[asclen - 1] = 0;
     return asctmp;
 }
 
 int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12)
 {
     return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
 }
 
 #ifndef OPENSSL_NO_FP_API
 int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12)
 {
     return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
 }
 #endif
 
 PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12)
 {
     return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12);
 }
 
 #ifndef OPENSSL_NO_FP_API
 PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12)
 {
     return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12);
 }
 #endif
 
 PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509)
 {
     return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509),
                                     NID_x509Certificate, NID_certBag);
 }
 
 PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl)
 {
     return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL),
                                     NID_x509Crl, NID_crlBag);
 }
 
 X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag)
 {
     if (M_PKCS12_bag_type(bag) != NID_certBag)
         return NULL;
     if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
         return NULL;
     return ASN1_item_unpack(bag->value.bag->value.octet,
                             ASN1_ITEM_rptr(X509));
 }
 
 X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag)
 {
     if (M_PKCS12_bag_type(bag) != NID_crlBag)
         return NULL;
     if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl)
         return NULL;
     return ASN1_item_unpack(bag->value.bag->value.octet,
                             ASN1_ITEM_rptr(X509_CRL));
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/pkcs12.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/pkcs12.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pkcs12/pkcs12.h	(revision 306191)
@@ -1,342 +1,342 @@
 /* pkcs12.h */
 /*
  * 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).
  *
  */
 
 #ifndef HEADER_PKCS12_H
 # define HEADER_PKCS12_H
 
 # include <openssl/bio.h>
 # include <openssl/x509.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 # define PKCS12_KEY_ID   1
 # define PKCS12_IV_ID    2
 # define PKCS12_MAC_ID   3
 
 /* Default iteration count */
 # ifndef PKCS12_DEFAULT_ITER
 #  define PKCS12_DEFAULT_ITER     PKCS5_DEFAULT_ITER
 # endif
 
 # define PKCS12_MAC_KEY_LENGTH 20
 
 # define PKCS12_SALT_LEN 8
 
 /* Uncomment out next line for unicode password and names, otherwise ASCII */
 
 /*
  * #define PBE_UNICODE
  */
 
 # ifdef PBE_UNICODE
 #  define PKCS12_key_gen PKCS12_key_gen_uni
 #  define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni
 # else
 #  define PKCS12_key_gen PKCS12_key_gen_asc
 #  define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc
 # endif
 
 /* MS key usage constants */
 
 # define KEY_EX  0x10
 # define KEY_SIG 0x80
 
 typedef struct {
     X509_SIG *dinfo;
     ASN1_OCTET_STRING *salt;
     ASN1_INTEGER *iter;         /* defaults to 1 */
 } PKCS12_MAC_DATA;
 
 typedef struct {
     ASN1_INTEGER *version;
     PKCS12_MAC_DATA *mac;
     PKCS7 *authsafes;
 } PKCS12;
 
 typedef struct {
     ASN1_OBJECT *type;
     union {
         struct pkcs12_bag_st *bag; /* secret, crl and certbag */
         struct pkcs8_priv_key_info_st *keybag; /* keybag */
         X509_SIG *shkeybag;     /* shrouded key bag */
         STACK_OF(PKCS12_SAFEBAG) *safes;
         ASN1_TYPE *other;
     } value;
     STACK_OF(X509_ATTRIBUTE) *attrib;
 } PKCS12_SAFEBAG;
 
 DECLARE_STACK_OF(PKCS12_SAFEBAG)
 DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG)
 DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG)
 
 typedef struct pkcs12_bag_st {
     ASN1_OBJECT *type;
     union {
         ASN1_OCTET_STRING *x509cert;
         ASN1_OCTET_STRING *x509crl;
         ASN1_OCTET_STRING *octet;
         ASN1_IA5STRING *sdsicert;
         ASN1_TYPE *other;       /* Secret or other bag */
     } value;
 } PKCS12_BAGS;
 
 # define PKCS12_ERROR    0
 # define PKCS12_OK       1
 
 /* Compatibility macros */
 
 # define M_PKCS12_x5092certbag PKCS12_x5092certbag
 # define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag
 
 # define M_PKCS12_certbag2x509 PKCS12_certbag2x509
 # define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl
 
 # define M_PKCS12_unpack_p7data PKCS12_unpack_p7data
 # define M_PKCS12_pack_authsafes PKCS12_pack_authsafes
 # define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes
 # define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata
 
 # define M_PKCS12_decrypt_skey PKCS12_decrypt_skey
 # define M_PKCS8_decrypt PKCS8_decrypt
 
 # define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type)
 # define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type)
 # define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type
 
 # define PKCS12_get_attr(bag, attr_nid) \
                          PKCS12_get_attr_gen(bag->attrib, attr_nid)
 
 # define PKCS8_get_attr(p8, attr_nid) \
                 PKCS12_get_attr_gen(p8->attributes, attr_nid)
 
 # define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0)
 
 PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509);
 PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl);
 X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag);
 X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag);
 
 PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it,
                                          int nid1, int nid2);
 PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8);
 PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass,
                                    int passlen);
 PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag,
                                          const char *pass, int passlen);
 X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
                         const char *pass, int passlen, unsigned char *salt,
                         int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8);
 PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass,
                                      int passlen, unsigned char *salt,
                                      int saltlen, int iter,
                                      PKCS8_PRIV_KEY_INFO *p8);
 PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk);
 STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7);
 PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen,
                              unsigned char *salt, int saltlen, int iter,
                              STACK_OF(PKCS12_SAFEBAG) *bags);
 STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
                                                   int passlen);
 
 int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes);
 STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12);
 
 int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name,
                           int namelen);
 int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name,
                                 int namelen);
 int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name,
                            int namelen);
 int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag,
                                 const unsigned char *name, int namelen);
 int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage);
 ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid);
 char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag);
 unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass,
                                 int passlen, unsigned char *in, int inlen,
                                 unsigned char **data, int *datalen,
                                 int en_de);
 void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
                               const char *pass, int passlen,
                               ASN1_OCTET_STRING *oct, int zbuf);
 ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor,
                                            const ASN1_ITEM *it,
                                            const char *pass, int passlen,
                                            void *obj, int zbuf);
 PKCS12 *PKCS12_init(int mode);
 int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt,
                        int saltlen, int id, int iter, int n,
                        unsigned char *out, const EVP_MD *md_type);
 int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt,
                        int saltlen, int id, int iter, int n,
                        unsigned char *out, const EVP_MD *md_type);
 int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen,
                         ASN1_TYPE *param, const EVP_CIPHER *cipher,
                         const EVP_MD *md_type, int en_de);
 int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
                    unsigned char *mac, unsigned int *maclen);
 int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen);
 int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
                    unsigned char *salt, int saltlen, int iter,
                    const EVP_MD *md_type);
 int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt,
                      int saltlen, const EVP_MD *md_type);
 unsigned char *OPENSSL_asc2uni(const char *asc, int asclen,
                                unsigned char **uni, int *unilen);
 char *OPENSSL_uni2asc(unsigned char *uni, int unilen);
 
 DECLARE_ASN1_FUNCTIONS(PKCS12)
 DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA)
 DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG)
 DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS)
 
 DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS)
 DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES)
 
 void PKCS12_PBE_add(void);
 int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert,
                  STACK_OF(X509) **ca);
 PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert,
                       STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter,
                       int mac_iter, int keytype);
 
 PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert);
 PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags,
                                EVP_PKEY *key, int key_usage, int iter,
                                int key_nid, char *pass);
 int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags,
                     int safe_nid, int iter, char *pass);
 PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid);
 
 int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
 int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
 PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
 PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
-int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass);
 
 /* 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_PKCS12_strings(void);
 
 /* Error codes for the PKCS12 functions. */
 
 /* Function codes. */
 # define PKCS12_F_PARSE_BAG                               129
 # define PKCS12_F_PARSE_BAGS                              103
 # define PKCS12_F_PKCS12_ADD_FRIENDLYNAME                 100
 # define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC             127
 # define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI             102
 # define PKCS12_F_PKCS12_ADD_LOCALKEYID                   104
 # define PKCS12_F_PKCS12_CREATE                           105
 # define PKCS12_F_PKCS12_GEN_MAC                          107
 # define PKCS12_F_PKCS12_INIT                             109
 # define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I                 106
 # define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT                 108
 # define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG                117
 # define PKCS12_F_PKCS12_KEY_GEN_ASC                      110
 # define PKCS12_F_PKCS12_KEY_GEN_UNI                      111
 # define PKCS12_F_PKCS12_MAKE_KEYBAG                      112
 # define PKCS12_F_PKCS12_MAKE_SHKEYBAG                    113
 # define PKCS12_F_PKCS12_NEWPASS                          128
 # define PKCS12_F_PKCS12_PACK_P7DATA                      114
 # define PKCS12_F_PKCS12_PACK_P7ENCDATA                   115
 # define PKCS12_F_PKCS12_PARSE                            118
 # define PKCS12_F_PKCS12_PBE_CRYPT                        119
 # define PKCS12_F_PKCS12_PBE_KEYIVGEN                     120
 # define PKCS12_F_PKCS12_SETUP_MAC                        122
 # define PKCS12_F_PKCS12_SET_MAC                          123
 # define PKCS12_F_PKCS12_UNPACK_AUTHSAFES                 130
 # define PKCS12_F_PKCS12_UNPACK_P7DATA                    131
 # define PKCS12_F_PKCS12_VERIFY_MAC                       126
 # define PKCS12_F_PKCS8_ADD_KEYUSAGE                      124
 # define PKCS12_F_PKCS8_ENCRYPT                           125
 
 /* Reason codes. */
 # define PKCS12_R_CANT_PACK_STRUCTURE                     100
 # define PKCS12_R_CONTENT_TYPE_NOT_DATA                   121
 # define PKCS12_R_DECODE_ERROR                            101
 # define PKCS12_R_ENCODE_ERROR                            102
 # define PKCS12_R_ENCRYPT_ERROR                           103
 # define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE       120
 # define PKCS12_R_INVALID_NULL_ARGUMENT                   104
 # define PKCS12_R_INVALID_NULL_PKCS12_POINTER             105
 # define PKCS12_R_IV_GEN_ERROR                            106
 # define PKCS12_R_KEY_GEN_ERROR                           107
 # define PKCS12_R_MAC_ABSENT                              108
 # define PKCS12_R_MAC_GENERATION_ERROR                    109
 # define PKCS12_R_MAC_SETUP_ERROR                         110
 # define PKCS12_R_MAC_STRING_SET_ERROR                    111
 # define PKCS12_R_MAC_VERIFY_ERROR                        112
 # define PKCS12_R_MAC_VERIFY_FAILURE                      113
 # define PKCS12_R_PARSE_ERROR                             114
 # define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR           115
 # define PKCS12_R_PKCS12_CIPHERFINAL_ERROR                116
 # define PKCS12_R_PKCS12_PBE_CRYPT_ERROR                  117
 # define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM                118
 # define PKCS12_R_UNSUPPORTED_PKCS12_MODE                 119
 
 #ifdef  __cplusplus
 }
 #endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/pkcs7/pk7_doit.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/pkcs7/pk7_doit.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/pkcs7/pk7_doit.c	(revision 306191)
@@ -1,1295 +1,1295 @@
 /* crypto/pkcs7/pk7_doit.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.]
  */
 
 #include <stdio.h>
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/err.h>
 
 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
                          void *value);
 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
 
 static int PKCS7_type_is_other(PKCS7 *p7)
 {
     int isOther = 1;
 
     int nid = OBJ_obj2nid(p7->type);
 
     switch (nid) {
     case NID_pkcs7_data:
     case NID_pkcs7_signed:
     case NID_pkcs7_enveloped:
     case NID_pkcs7_signedAndEnveloped:
     case NID_pkcs7_digest:
     case NID_pkcs7_encrypted:
         isOther = 0;
         break;
     default:
         isOther = 1;
     }
 
     return isOther;
 
 }
 
 static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
 {
     if (PKCS7_type_is_data(p7))
         return p7->d.data;
     if (PKCS7_type_is_other(p7) && p7->d.other
         && (p7->d.other->type == V_ASN1_OCTET_STRING))
         return p7->d.other->value.octet_string;
     return NULL;
 }
 
 static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
 {
     BIO *btmp;
     const EVP_MD *md;
     if ((btmp = BIO_new(BIO_f_md())) == NULL) {
         PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
         goto err;
     }
 
     md = EVP_get_digestbyobj(alg->algorithm);
     if (md == NULL) {
         PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
         goto err;
     }
 
     BIO_set_md(btmp, md);
     if (*pbio == NULL)
         *pbio = btmp;
     else if (!BIO_push(*pbio, btmp)) {
         PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
         goto err;
     }
     btmp = NULL;
 
     return 1;
 
  err:
     if (btmp)
         BIO_free(btmp);
     return 0;
 
 }
 
 static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
                               unsigned char *key, int keylen)
 {
     EVP_PKEY_CTX *pctx = NULL;
     EVP_PKEY *pkey = NULL;
     unsigned char *ek = NULL;
     int ret = 0;
     size_t eklen;
 
     pkey = X509_get_pubkey(ri->cert);
 
     if (!pkey)
         return 0;
 
     pctx = EVP_PKEY_CTX_new(pkey, NULL);
     if (!pctx)
         return 0;
 
     if (EVP_PKEY_encrypt_init(pctx) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
                           EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
         PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
         goto err;
     }
 
     if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
         goto err;
 
     ek = OPENSSL_malloc(eklen);
 
     if (ek == NULL) {
         PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
         goto err;
 
     ASN1_STRING_set0(ri->enc_key, ek, eklen);
     ek = NULL;
 
     ret = 1;
 
  err:
     if (pkey)
         EVP_PKEY_free(pkey);
     if (pctx)
         EVP_PKEY_CTX_free(pctx);
     if (ek)
         OPENSSL_free(ek);
     return ret;
 
 }
 
 static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
                                PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
 {
     EVP_PKEY_CTX *pctx = NULL;
     unsigned char *ek = NULL;
     size_t eklen;
 
     int ret = -1;
 
     pctx = EVP_PKEY_CTX_new(pkey, NULL);
     if (!pctx)
         return -1;
 
     if (EVP_PKEY_decrypt_init(pctx) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
                           EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
         PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
         goto err;
     }
 
     if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
                          ri->enc_key->data, ri->enc_key->length) <= 0)
         goto err;
 
     ek = OPENSSL_malloc(eklen);
 
     if (ek == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     if (EVP_PKEY_decrypt(pctx, ek, &eklen,
                          ri->enc_key->data, ri->enc_key->length) <= 0) {
         ret = 0;
         PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
         goto err;
     }
 
     ret = 1;
 
     if (*pek) {
         OPENSSL_cleanse(*pek, *peklen);
         OPENSSL_free(*pek);
     }
 
     *pek = ek;
     *peklen = eklen;
 
  err:
     if (pctx)
         EVP_PKEY_CTX_free(pctx);
     if (!ret && ek)
         OPENSSL_free(ek);
 
     return ret;
 }
 
 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
 {
     int i;
     BIO *out = NULL, *btmp = NULL;
     X509_ALGOR *xa = NULL;
     const EVP_CIPHER *evp_cipher = NULL;
     STACK_OF(X509_ALGOR) *md_sk = NULL;
     STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
     X509_ALGOR *xalg = NULL;
     PKCS7_RECIP_INFO *ri = NULL;
     ASN1_OCTET_STRING *os = NULL;
 
     if (p7 == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
         return NULL;
     }
     /*
      * The content field in the PKCS7 ContentInfo is optional, but that really
      * only applies to inner content (precisely, detached signatures).
      *
      * When reading content, missing outer content is therefore treated as an
      * error.
      *
      * When creating content, PKCS7_content_new() must be called before
      * calling this method, so a NULL p7->d is always an error.
      */
     if (p7->d.ptr == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
         return NULL;
     }
 
     i = OBJ_obj2nid(p7->type);
     p7->state = PKCS7_S_HEADER;
 
     switch (i) {
     case NID_pkcs7_signed:
         md_sk = p7->d.sign->md_algs;
         os = PKCS7_get_octet_string(p7->d.sign->contents);
         break;
     case NID_pkcs7_signedAndEnveloped:
         rsk = p7->d.signed_and_enveloped->recipientinfo;
         md_sk = p7->d.signed_and_enveloped->md_algs;
         xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
         evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
             goto err;
         }
         break;
     case NID_pkcs7_enveloped:
         rsk = p7->d.enveloped->recipientinfo;
         xalg = p7->d.enveloped->enc_data->algorithm;
         evp_cipher = p7->d.enveloped->enc_data->cipher;
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
             goto err;
         }
         break;
     case NID_pkcs7_digest:
         xa = p7->d.digest->md;
         os = PKCS7_get_octet_string(p7->d.digest->contents);
         break;
     case NID_pkcs7_data:
         break;
     default:
         PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
         goto err;
     }
 
     for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
         if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
             goto err;
 
     if (xa && !PKCS7_bio_add_digest(&out, xa))
         goto err;
 
     if (evp_cipher != NULL) {
         unsigned char key[EVP_MAX_KEY_LENGTH];
         unsigned char iv[EVP_MAX_IV_LENGTH];
         int keylen, ivlen;
         EVP_CIPHER_CTX *ctx;
 
         if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
             goto err;
         }
         BIO_get_cipher_ctx(btmp, &ctx);
         keylen = EVP_CIPHER_key_length(evp_cipher);
         ivlen = EVP_CIPHER_iv_length(evp_cipher);
         xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
         if (ivlen > 0)
-            if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+            if (RAND_bytes(iv, ivlen) <= 0)
                 goto err;
         if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
             goto err;
         if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
             goto err;
         if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
             goto err;
 
         if (ivlen > 0) {
             if (xalg->parameter == NULL) {
                 xalg->parameter = ASN1_TYPE_new();
                 if (xalg->parameter == NULL)
                     goto err;
             }
             if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
                 goto err;
         }
 
         /* Lets do the pub key stuff :-) */
         for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
             ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
             if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
                 goto err;
         }
         OPENSSL_cleanse(key, keylen);
 
         if (out == NULL)
             out = btmp;
         else
             BIO_push(out, btmp);
         btmp = NULL;
     }
 
     if (bio == NULL) {
         if (PKCS7_is_detached(p7))
             bio = BIO_new(BIO_s_null());
         else if (os && os->length > 0)
             bio = BIO_new_mem_buf(os->data, os->length);
         if (bio == NULL) {
             bio = BIO_new(BIO_s_mem());
             if (bio == NULL)
                 goto err;
             BIO_set_mem_eof_return(bio, 0);
         }
     }
     if (out)
         BIO_push(out, bio);
     else
         out = bio;
     bio = NULL;
     if (0) {
  err:
         if (out != NULL)
             BIO_free_all(out);
         if (btmp != NULL)
             BIO_free_all(btmp);
         out = NULL;
     }
     return (out);
 }
 
 static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
 {
     int ret;
     ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
                         pcert->cert_info->issuer);
     if (ret)
         return ret;
     return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
                               ri->issuer_and_serial->serial);
 }
 
 /* int */
 BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
 {
     int i, j;
     BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
     X509_ALGOR *xa;
     ASN1_OCTET_STRING *data_body = NULL;
     const EVP_MD *evp_md;
     const EVP_CIPHER *evp_cipher = NULL;
     EVP_CIPHER_CTX *evp_ctx = NULL;
     X509_ALGOR *enc_alg = NULL;
     STACK_OF(X509_ALGOR) *md_sk = NULL;
     STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
     PKCS7_RECIP_INFO *ri = NULL;
     unsigned char *ek = NULL, *tkey = NULL;
     int eklen = 0, tkeylen = 0;
 
     if (p7 == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
         return NULL;
     }
 
     if (p7->d.ptr == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
         return NULL;
     }
 
     i = OBJ_obj2nid(p7->type);
     p7->state = PKCS7_S_HEADER;
 
     switch (i) {
     case NID_pkcs7_signed:
         /*
          * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
          * field and optional content.
          * data_body is NULL if that structure has no (=detached) content
          * or if the contentType is wrong (i.e., not "data").
          */
         data_body = PKCS7_get_octet_string(p7->d.sign->contents);
         if (!PKCS7_is_detached(p7) && data_body == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                      PKCS7_R_INVALID_SIGNED_DATA_TYPE);
             goto err;
         }
         md_sk = p7->d.sign->md_algs;
         break;
     case NID_pkcs7_signedAndEnveloped:
         rsk = p7->d.signed_and_enveloped->recipientinfo;
         md_sk = p7->d.signed_and_enveloped->md_algs;
         /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
         enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                      PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
             goto err;
         }
         break;
     case NID_pkcs7_enveloped:
         rsk = p7->d.enveloped->recipientinfo;
         enc_alg = p7->d.enveloped->enc_data->algorithm;
         /* data_body is NULL if the optional EncryptedContent is missing. */
         data_body = p7->d.enveloped->enc_data->enc_data;
         evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
         if (evp_cipher == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                      PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
             goto err;
         }
         break;
     default:
         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
         goto err;
     }
 
     /* Detached content must be supplied via in_bio instead. */
     if (data_body == NULL && in_bio == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
         goto err;
     }
 
     /* We will be checking the signature */
     if (md_sk != NULL) {
         for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
             xa = sk_X509_ALGOR_value(md_sk, i);
             if ((btmp = BIO_new(BIO_f_md())) == NULL) {
                 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
                 goto err;
             }
 
             j = OBJ_obj2nid(xa->algorithm);
             evp_md = EVP_get_digestbynid(j);
             if (evp_md == NULL) {
                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                          PKCS7_R_UNKNOWN_DIGEST_TYPE);
                 goto err;
             }
 
             BIO_set_md(btmp, evp_md);
             if (out == NULL)
                 out = btmp;
             else
                 BIO_push(out, btmp);
             btmp = NULL;
         }
     }
 
     if (evp_cipher != NULL) {
 #if 0
         unsigned char key[EVP_MAX_KEY_LENGTH];
         unsigned char iv[EVP_MAX_IV_LENGTH];
         unsigned char *p;
         int keylen, ivlen;
         int max;
         X509_OBJECT ret;
 #endif
 
         if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
             PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
             goto err;
         }
 
         /*
          * It was encrypted, we need to decrypt the secret key with the
          * private key
          */
 
         /*
          * Find the recipientInfo which matches the passed certificate (if
          * any)
          */
 
         if (pcert) {
             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
                 if (!pkcs7_cmp_ri(ri, pcert))
                     break;
                 ri = NULL;
             }
             if (ri == NULL) {
                 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
                          PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
                 goto err;
             }
         }
 
         /* If we haven't got a certificate try each ri in turn */
         if (pcert == NULL) {
             /*
              * Always attempt to decrypt all rinfo even after sucess as a
              * defence against MMA timing attacks.
              */
             for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
                 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
 
                 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
                     goto err;
                 ERR_clear_error();
             }
         } else {
             /* Only exit on fatal errors, not decrypt failure */
             if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
                 goto err;
             ERR_clear_error();
         }
 
         evp_ctx = NULL;
         BIO_get_cipher_ctx(etmp, &evp_ctx);
         if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
             goto err;
         if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
             goto err;
         /* Generate random key as MMA defence */
         tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
         tkey = OPENSSL_malloc(tkeylen);
         if (!tkey)
             goto err;
         if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
             goto err;
         if (ek == NULL) {
             ek = tkey;
             eklen = tkeylen;
             tkey = NULL;
         }
 
         if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
             /*
              * Some S/MIME clients don't use the same key and effective key
              * length. The key length is determined by the size of the
              * decrypted RSA key.
              */
             if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
                 /* Use random key as MMA defence */
                 OPENSSL_cleanse(ek, eklen);
                 OPENSSL_free(ek);
                 ek = tkey;
                 eklen = tkeylen;
                 tkey = NULL;
             }
         }
         /* Clear errors so we don't leak information useful in MMA */
         ERR_clear_error();
         if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
             goto err;
 
         if (ek) {
             OPENSSL_cleanse(ek, eklen);
             OPENSSL_free(ek);
             ek = NULL;
         }
         if (tkey) {
             OPENSSL_cleanse(tkey, tkeylen);
             OPENSSL_free(tkey);
             tkey = NULL;
         }
 
         if (out == NULL)
             out = etmp;
         else
             BIO_push(out, etmp);
         etmp = NULL;
     }
 #if 1
     if (in_bio != NULL) {
         bio = in_bio;
     } else {
 # if 0
         bio = BIO_new(BIO_s_mem());
         /*
          * We need to set this so that when we have read all the data, the
          * encrypt BIO, if present, will read EOF and encode the last few
          * bytes
          */
         BIO_set_mem_eof_return(bio, 0);
 
         if (data_body->length > 0)
             BIO_write(bio, (char *)data_body->data, data_body->length);
 # else
         if (data_body->length > 0)
             bio = BIO_new_mem_buf(data_body->data, data_body->length);
         else {
             bio = BIO_new(BIO_s_mem());
             if (bio == NULL)
                 goto err;
             BIO_set_mem_eof_return(bio, 0);
         }
         if (bio == NULL)
             goto err;
 # endif
     }
     BIO_push(out, bio);
     bio = NULL;
 #endif
     if (0) {
  err:
         if (ek) {
             OPENSSL_cleanse(ek, eklen);
             OPENSSL_free(ek);
         }
         if (tkey) {
             OPENSSL_cleanse(tkey, tkeylen);
             OPENSSL_free(tkey);
         }
         if (out != NULL)
             BIO_free_all(out);
         if (btmp != NULL)
             BIO_free_all(btmp);
         if (etmp != NULL)
             BIO_free_all(etmp);
         if (bio != NULL)
             BIO_free_all(bio);
         out = NULL;
     }
     return (out);
 }
 
 static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
 {
     for (;;) {
         bio = BIO_find_type(bio, BIO_TYPE_MD);
         if (bio == NULL) {
             PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
             return NULL;
         }
         BIO_get_md_ctx(bio, pmd);
         if (*pmd == NULL) {
             PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
         if (EVP_MD_CTX_type(*pmd) == nid)
             return bio;
         bio = BIO_next(bio);
     }
     return NULL;
 }
 
 static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
 {
     unsigned char md_data[EVP_MAX_MD_SIZE];
     unsigned int md_len;
 
     /* Add signing time if not already present */
     if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
         if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
             PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
             return 0;
         }
     }
 
     /* Add digest */
     if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
         PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
         return 0;
     }
     if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
         PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
     /* Now sign the attributes */
     if (!PKCS7_SIGNER_INFO_sign(si))
         return 0;
 
     return 1;
 }
 
 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
 {
     int ret = 0;
     int i, j;
     BIO *btmp;
     PKCS7_SIGNER_INFO *si;
     EVP_MD_CTX *mdc, ctx_tmp;
     STACK_OF(X509_ATTRIBUTE) *sk;
     STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
     ASN1_OCTET_STRING *os = NULL;
 
     if (p7 == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
         return 0;
     }
 
     if (p7->d.ptr == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
         return 0;
     }
 
     EVP_MD_CTX_init(&ctx_tmp);
     i = OBJ_obj2nid(p7->type);
     p7->state = PKCS7_S_HEADER;
 
     switch (i) {
     case NID_pkcs7_data:
         os = p7->d.data;
         break;
     case NID_pkcs7_signedAndEnveloped:
         /* XXXXXXXXXXXXXXXX */
         si_sk = p7->d.signed_and_enveloped->signer_info;
         os = p7->d.signed_and_enveloped->enc_data->enc_data;
         if (!os) {
             os = M_ASN1_OCTET_STRING_new();
             if (!os) {
                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             p7->d.signed_and_enveloped->enc_data->enc_data = os;
         }
         break;
     case NID_pkcs7_enveloped:
         /* XXXXXXXXXXXXXXXX */
         os = p7->d.enveloped->enc_data->enc_data;
         if (!os) {
             os = M_ASN1_OCTET_STRING_new();
             if (!os) {
                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             p7->d.enveloped->enc_data->enc_data = os;
         }
         break;
     case NID_pkcs7_signed:
         si_sk = p7->d.sign->signer_info;
         os = PKCS7_get_octet_string(p7->d.sign->contents);
         /* If detached data then the content is excluded */
         if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
             M_ASN1_OCTET_STRING_free(os);
             os = NULL;
             p7->d.sign->contents->d.data = NULL;
         }
         break;
 
     case NID_pkcs7_digest:
         os = PKCS7_get_octet_string(p7->d.digest->contents);
         /* If detached data then the content is excluded */
         if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
             M_ASN1_OCTET_STRING_free(os);
             os = NULL;
             p7->d.digest->contents->d.data = NULL;
         }
         break;
 
     default:
         PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
         goto err;
     }
 
     if (si_sk != NULL) {
         for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
             si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
             if (si->pkey == NULL)
                 continue;
 
             j = OBJ_obj2nid(si->digest_alg->algorithm);
 
             btmp = bio;
 
             btmp = PKCS7_find_digest(&mdc, btmp, j);
 
             if (btmp == NULL)
                 goto err;
 
             /*
              * We now have the EVP_MD_CTX, lets do the signing.
              */
             if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc))
                 goto err;
 
             sk = si->auth_attr;
 
             /*
              * If there are attributes, we add the digest attribute and only
              * sign the attributes
              */
             if (sk_X509_ATTRIBUTE_num(sk) > 0) {
                 if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
                     goto err;
             } else {
                 unsigned char *abuf = NULL;
                 unsigned int abuflen;
                 abuflen = EVP_PKEY_size(si->pkey);
                 abuf = OPENSSL_malloc(abuflen);
                 if (!abuf)
                     goto err;
 
                 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) {
                     PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
                     goto err;
                 }
                 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
             }
         }
     } else if (i == NID_pkcs7_digest) {
         unsigned char md_data[EVP_MAX_MD_SIZE];
         unsigned int md_len;
         if (!PKCS7_find_digest(&mdc, bio,
                                OBJ_obj2nid(p7->d.digest->md->algorithm)))
             goto err;
         if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
             goto err;
         M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
     }
 
     if (!PKCS7_is_detached(p7)) {
         /*
          * NOTE(emilia): I think we only reach os == NULL here because detached
          * digested data support is broken.
          */
         if (os == NULL)
             goto err;
         if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
             char *cont;
             long contlen;
             btmp = BIO_find_type(bio, BIO_TYPE_MEM);
             if (btmp == NULL) {
                 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
                 goto err;
             }
             contlen = BIO_get_mem_data(btmp, &cont);
             /*
              * Mark the BIO read only then we can use its copy of the data
              * instead of making an extra copy.
              */
             BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
             BIO_set_mem_eof_return(btmp, 0);
             ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
         }
     }
     ret = 1;
  err:
     EVP_MD_CTX_cleanup(&ctx_tmp);
     return (ret);
 }
 
 int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
 {
     EVP_MD_CTX mctx;
     EVP_PKEY_CTX *pctx;
     unsigned char *abuf = NULL;
     int alen;
     size_t siglen;
     const EVP_MD *md = NULL;
 
     md = EVP_get_digestbyobj(si->digest_alg->algorithm);
     if (md == NULL)
         return 0;
 
     EVP_MD_CTX_init(&mctx);
     if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
                           EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
         PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
         goto err;
     }
 
     alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
                          ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
     if (!abuf)
         goto err;
     if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
         goto err;
     OPENSSL_free(abuf);
     abuf = NULL;
     if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
         goto err;
     abuf = OPENSSL_malloc(siglen);
     if (!abuf)
         goto err;
     if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
         goto err;
 
     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
                           EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
         PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
         goto err;
     }
 
     EVP_MD_CTX_cleanup(&mctx);
 
     ASN1_STRING_set0(si->enc_digest, abuf, siglen);
 
     return 1;
 
  err:
     if (abuf)
         OPENSSL_free(abuf);
     EVP_MD_CTX_cleanup(&mctx);
     return 0;
 
 }
 
 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
                      PKCS7 *p7, PKCS7_SIGNER_INFO *si)
 {
     PKCS7_ISSUER_AND_SERIAL *ias;
     int ret = 0, i;
     STACK_OF(X509) *cert;
     X509 *x509;
 
     if (p7 == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
         return 0;
     }
 
     if (p7->d.ptr == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
         return 0;
     }
 
     if (PKCS7_type_is_signed(p7)) {
         cert = p7->d.sign->cert;
     } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
         cert = p7->d.signed_and_enveloped->cert;
     } else {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
         goto err;
     }
     /* XXXXXXXXXXXXXXXXXXXXXXX */
     ias = si->issuer_and_serial;
 
     x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
 
     /* were we able to find the cert in passed to us */
     if (x509 == NULL) {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
                  PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
         goto err;
     }
 
     /* Lets verify */
     if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
         goto err;
     }
     X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
     i = X509_verify_cert(ctx);
     if (i <= 0) {
         PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
         X509_STORE_CTX_cleanup(ctx);
         goto err;
     }
     X509_STORE_CTX_cleanup(ctx);
 
     return PKCS7_signatureVerify(bio, p7, si, x509);
  err:
     return ret;
 }
 
 int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
                           X509 *x509)
 {
     ASN1_OCTET_STRING *os;
     EVP_MD_CTX mdc_tmp, *mdc;
     int ret = 0, i;
     int md_type;
     STACK_OF(X509_ATTRIBUTE) *sk;
     BIO *btmp;
     EVP_PKEY *pkey;
 
     EVP_MD_CTX_init(&mdc_tmp);
 
     if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
         goto err;
     }
 
     md_type = OBJ_obj2nid(si->digest_alg->algorithm);
 
     btmp = bio;
     for (;;) {
         if ((btmp == NULL) ||
             ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
             goto err;
         }
         BIO_get_md_ctx(btmp, &mdc);
         if (mdc == NULL) {
             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
             goto err;
         }
         if (EVP_MD_CTX_type(mdc) == md_type)
             break;
         /*
          * Workaround for some broken clients that put the signature OID
          * instead of the digest OID in digest_alg->algorithm
          */
         if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
             break;
         btmp = BIO_next(btmp);
     }
 
     /*
      * mdc is the digest ctx that we want, unless there are attributes, in
      * which case the digest is the signed attributes
      */
     if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc))
         goto err;
 
     sk = si->auth_attr;
     if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
         unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
         unsigned int md_len;
         int alen;
         ASN1_OCTET_STRING *message_digest;
 
         if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len))
             goto err;
         message_digest = PKCS7_digest_from_attributes(sk);
         if (!message_digest) {
             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
                      PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
             goto err;
         }
         if ((message_digest->length != (int)md_len) ||
             (memcmp(message_digest->data, md_dat, md_len))) {
 #if 0
             {
                 int ii;
                 for (ii = 0; ii < message_digest->length; ii++)
                     printf("%02X", message_digest->data[ii]);
                 printf(" sent\n");
                 for (ii = 0; ii < md_len; ii++)
                     printf("%02X", md_dat[ii]);
                 printf(" calc\n");
             }
 #endif
             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
             ret = -1;
             goto err;
         }
 
         if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL))
             goto err;
 
         alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
                              ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
         if (alen <= 0) {
             PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
             ret = -1;
             goto err;
         }
         if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen))
             goto err;
 
         OPENSSL_free(abuf);
     }
 
     os = si->enc_digest;
     pkey = X509_get_pubkey(x509);
     if (!pkey) {
         ret = -1;
         goto err;
     }
 
     i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey);
     EVP_PKEY_free(pkey);
     if (i <= 0) {
         PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
         ret = -1;
         goto err;
     } else
         ret = 1;
  err:
     EVP_MD_CTX_cleanup(&mdc_tmp);
     return (ret);
 }
 
 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
 {
     STACK_OF(PKCS7_RECIP_INFO) *rsk;
     PKCS7_RECIP_INFO *ri;
     int i;
 
     i = OBJ_obj2nid(p7->type);
     if (i != NID_pkcs7_signedAndEnveloped)
         return NULL;
     if (p7->d.signed_and_enveloped == NULL)
         return NULL;
     rsk = p7->d.signed_and_enveloped->recipientinfo;
     if (rsk == NULL)
         return NULL;
     if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
         return (NULL);
     ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
     return (ri->issuer_and_serial);
 }
 
 ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
 {
     return (get_attribute(si->auth_attr, nid));
 }
 
 ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
 {
     return (get_attribute(si->unauth_attr, nid));
 }
 
 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
 {
     int i;
     X509_ATTRIBUTE *xa;
     ASN1_OBJECT *o;
 
     o = OBJ_nid2obj(nid);
     if (!o || !sk)
         return (NULL);
     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
         xa = sk_X509_ATTRIBUTE_value(sk, i);
         if (OBJ_cmp(xa->object, o) == 0) {
             if (!xa->single && sk_ASN1_TYPE_num(xa->value.set))
                 return (sk_ASN1_TYPE_value(xa->value.set, 0));
             else
                 return (NULL);
         }
     }
     return (NULL);
 }
 
 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
 {
     ASN1_TYPE *astype;
     if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest)))
         return NULL;
     return astype->value.octet_string;
 }
 
 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
                                 STACK_OF(X509_ATTRIBUTE) *sk)
 {
     int i;
 
     if (p7si->auth_attr != NULL)
         sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
     p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
     if (p7si->auth_attr == NULL)
         return 0;
     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
         if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
                                    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
                                                       (sk, i))))
             == NULL)
             return (0);
     }
     return (1);
 }
 
 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
                          STACK_OF(X509_ATTRIBUTE) *sk)
 {
     int i;
 
     if (p7si->unauth_attr != NULL)
         sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
     p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
     if (p7si->unauth_attr == NULL)
         return 0;
     for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
         if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
                                    X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
                                                       (sk, i))))
             == NULL)
             return (0);
     }
     return (1);
 }
 
 int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
                                void *value)
 {
     return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
 }
 
 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
                         void *value)
 {
     return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
 }
 
 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
                          void *value)
 {
     X509_ATTRIBUTE *attr = NULL;
 
     if (*sk == NULL) {
         *sk = sk_X509_ATTRIBUTE_new_null();
         if (*sk == NULL)
             return 0;
  new_attrib:
         if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value)))
             return 0;
         if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
             X509_ATTRIBUTE_free(attr);
             return 0;
         }
     } else {
         int i;
 
         for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
             attr = sk_X509_ATTRIBUTE_value(*sk, i);
             if (OBJ_obj2nid(attr->object) == nid) {
                 X509_ATTRIBUTE_free(attr);
                 attr = X509_ATTRIBUTE_create(nid, atrtype, value);
                 if (attr == NULL)
                     return 0;
                 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
                     X509_ATTRIBUTE_free(attr);
                     return 0;
                 }
                 goto end;
             }
         }
         goto new_attrib;
     }
  end:
     return (1);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/rand/rand_unix.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/rand/rand_unix.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/rand/rand_unix.c	(revision 306191)
@@ -1,447 +1,447 @@
 /* crypto/rand/rand_unix.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-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
  *    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>
 
 #define USE_SOCKETS
 #include "e_os.h"
 #include "cryptlib.h"
 #include <openssl/rand.h>
 #include "rand_lcl.h"
 
 #if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
 
 # include <sys/types.h>
 # include <sys/time.h>
 # include <sys/times.h>
 # include <sys/stat.h>
 # include <fcntl.h>
 # include <unistd.h>
 # include <time.h>
 # if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
                                  * everywhere */
 #  include <poll.h>
 # endif
 # include <limits.h>
 # ifndef FD_SETSIZE
 #  define FD_SETSIZE (8*sizeof(fd_set))
 # endif
 
 # if defined(OPENSSL_SYS_VOS)
 
 /*
  * The following algorithm repeatedly samples the real-time clock (RTC) to
  * generate a sequence of unpredictable data.  The algorithm relies upon the
  * uneven execution speed of the code (due to factors such as cache misses,
  * interrupts, bus activity, and scheduling) and upon the rather large
  * relative difference between the speed of the clock and the rate at which
  * it can be read.
  *
  * If this code is ported to an environment where execution speed is more
  * constant or where the RTC ticks at a much slower rate, or the clock can be
  * read with fewer instructions, it is likely that the results would be far
  * more predictable.
  *
  * As a precaution, we generate 4 times the minimum required amount of seed
  * data.
  */
 
 int RAND_poll(void)
 {
     short int code;
     gid_t curr_gid;
     pid_t curr_pid;
     uid_t curr_uid;
     int i, k;
     struct timespec ts;
     unsigned char v;
 
 #  ifdef OPENSSL_SYS_VOS_HPPA
     long duration;
     extern void s$sleep(long *_duration, short int *_code);
 #  else
 #   ifdef OPENSSL_SYS_VOS_IA32
     long long duration;
     extern void s$sleep2(long long *_duration, short int *_code);
 #   else
 #    error "Unsupported Platform."
 #   endif                       /* OPENSSL_SYS_VOS_IA32 */
 #  endif                        /* OPENSSL_SYS_VOS_HPPA */
 
     /*
      * Seed with the gid, pid, and uid, to ensure *some* variation between
      * different processes.
      */
 
     curr_gid = getgid();
     RAND_add(&curr_gid, sizeof curr_gid, 1);
     curr_gid = 0;
 
     curr_pid = getpid();
     RAND_add(&curr_pid, sizeof curr_pid, 1);
     curr_pid = 0;
 
     curr_uid = getuid();
     RAND_add(&curr_uid, sizeof curr_uid, 1);
     curr_uid = 0;
 
     for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
         /*
          * burn some cpu; hope for interrupts, cache collisions, bus
          * interference, etc.
          */
         for (k = 0; k < 99; k++)
             ts.tv_nsec = random();
 
 #  ifdef OPENSSL_SYS_VOS_HPPA
         /* sleep for 1/1024 of a second (976 us).  */
         duration = 1;
         s$sleep(&duration, &code);
 #  else
 #   ifdef OPENSSL_SYS_VOS_IA32
         /* sleep for 1/65536 of a second (15 us).  */
         duration = 1;
         s$sleep2(&duration, &code);
 #   endif                       /* OPENSSL_SYS_VOS_IA32 */
 #  endif                        /* OPENSSL_SYS_VOS_HPPA */
 
         /* get wall clock time.  */
         clock_gettime(CLOCK_REALTIME, &ts);
 
         /* take 8 bits */
         v = (unsigned char)(ts.tv_nsec % 256);
         RAND_add(&v, sizeof v, 1);
         v = 0;
     }
     return 1;
 }
 # elif defined __OpenBSD__
 int RAND_poll(void)
 {
     u_int32_t rnd = 0, i;
     unsigned char buf[ENTROPY_NEEDED];
 
     for (i = 0; i < sizeof(buf); i++) {
         if (i % 4 == 0)
             rnd = arc4random();
         buf[i] = rnd;
         rnd >>= 8;
     }
     RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
-    memset(buf, 0, sizeof(buf));
+    OPENSSL_cleanse(buf, sizeof(buf));
 
     return 1;
 }
 # else                          /* !defined(__OpenBSD__) */
 int RAND_poll(void)
 {
     unsigned long l;
     pid_t curr_pid = getpid();
 #  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
     unsigned char tmpbuf[ENTROPY_NEEDED];
     int n = 0;
 #  endif
 #  ifdef DEVRANDOM
     static const char *randomfiles[] = { DEVRANDOM };
     struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])];
     int fd;
     unsigned int i;
 #  endif
 #  ifdef DEVRANDOM_EGD
     static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
     const char **egdsocket = NULL;
 #  endif
 
 #  ifdef DEVRANDOM
     memset(randomstats, 0, sizeof(randomstats));
     /*
      * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
      * this. Use /dev/urandom if you can as /dev/random may block if it runs
      * out of random entries.
      */
 
     for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) &&
          (n < ENTROPY_NEEDED); i++) {
         if ((fd = open(randomfiles[i], O_RDONLY
 #   ifdef O_NONBLOCK
                        | O_NONBLOCK
 #   endif
 #   ifdef O_BINARY
                        | O_BINARY
 #   endif
 #   ifdef O_NOCTTY              /* If it happens to be a TTY (god forbid), do
                                  * not make it our controlling tty */
                        | O_NOCTTY
 #   endif
              )) >= 0) {
             int usec = 10 * 1000; /* spend 10ms on each file */
             int r;
             unsigned int j;
             struct stat *st = &randomstats[i];
 
             /*
              * Avoid using same input... Used to be O_NOFOLLOW above, but
              * it's not universally appropriate...
              */
             if (fstat(fd, st) != 0) {
                 close(fd);
                 continue;
             }
             for (j = 0; j < i; j++) {
                 if (randomstats[j].st_ino == st->st_ino &&
                     randomstats[j].st_dev == st->st_dev)
                     break;
             }
             if (j < i) {
                 close(fd);
                 continue;
             }
 
             do {
                 int try_read = 0;
 
 #   if defined(OPENSSL_SYS_BEOS_R5)
                 /*
                  * select() is broken in BeOS R5, so we simply try to read
                  * something and snooze if we couldn't
                  */
                 try_read = 1;
 
 #   elif defined(OPENSSL_SYS_LINUX)
                 /* use poll() */
                 struct pollfd pset;
 
                 pset.fd = fd;
                 pset.events = POLLIN;
                 pset.revents = 0;
 
                 if (poll(&pset, 1, usec / 1000) < 0)
                     usec = 0;
                 else
                     try_read = (pset.revents & POLLIN) != 0;
 
 #   else
                 /* use select() */
                 fd_set fset;
                 struct timeval t;
 
                 t.tv_sec = 0;
                 t.tv_usec = usec;
 
                 if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
                     /*
                      * can't use select, so just try to read once anyway
                      */
                     try_read = 1;
                 } else {
                     FD_ZERO(&fset);
                     FD_SET(fd, &fset);
 
                     if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
                         usec = t.tv_usec;
                         if (FD_ISSET(fd, &fset))
                             try_read = 1;
                     } else
                         usec = 0;
                 }
 #   endif
 
                 if (try_read) {
                     r = read(fd, (unsigned char *)tmpbuf + n,
                              ENTROPY_NEEDED - n);
                     if (r > 0)
                         n += r;
 #   if defined(OPENSSL_SYS_BEOS_R5)
                     if (r == 0)
                         snooze(t.tv_usec);
 #   endif
                 } else
                     r = -1;
 
                 /*
                  * Some Unixen will update t in select(), some won't.  For
                  * those who won't, or if we didn't use select() in the first
                  * place, give up here, otherwise, we will do this once again
                  * for the remaining time.
                  */
                 if (usec == 10 * 1000)
                     usec = 0;
             }
             while ((r > 0 ||
                     (errno == EINTR || errno == EAGAIN)) && usec != 0
                    && n < ENTROPY_NEEDED);
 
             close(fd);
         }
     }
 #  endif                        /* defined(DEVRANDOM) */
 
 #  ifdef DEVRANDOM_EGD
     /*
      * Use an EGD socket to read entropy from an EGD or PRNGD entropy
      * collecting daemon.
      */
 
     for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
          egdsocket++) {
         int r;
 
         r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
                                  ENTROPY_NEEDED - n);
         if (r > 0)
             n += r;
     }
 #  endif                        /* defined(DEVRANDOM_EGD) */
 
 #  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
     if (n > 0) {
         RAND_add(tmpbuf, sizeof tmpbuf, (double)n);
         OPENSSL_cleanse(tmpbuf, n);
     }
 #  endif
 
     /* put in some default random data, we need more than just this */
     l = curr_pid;
     RAND_add(&l, sizeof(l), 0.0);
     l = getuid();
     RAND_add(&l, sizeof(l), 0.0);
 
     l = time(NULL);
     RAND_add(&l, sizeof(l), 0.0);
 
 #  if defined(OPENSSL_SYS_BEOS)
     {
         system_info sysInfo;
         get_system_info(&sysInfo);
         RAND_add(&sysInfo, sizeof(sysInfo), 0);
     }
 #  endif
 
 #  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
     return 1;
 #  else
     return 0;
 #  endif
 }
 
 # endif                         /* defined(__OpenBSD__) */
 #endif                          /* !(defined(OPENSSL_SYS_WINDOWS) ||
                                  * defined(OPENSSL_SYS_WIN32) ||
                                  * defined(OPENSSL_SYS_VMS) ||
                                  * defined(OPENSSL_SYS_OS2) ||
                                  * defined(OPENSSL_SYS_VXWORKS) ||
                                  * defined(OPENSSL_SYS_NETWARE)) */
 
 #if defined(OPENSSL_SYS_VXWORKS)
 int RAND_poll(void)
 {
     return 0;
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_lib.c	(revision 306191)
@@ -1,357 +1,363 @@
 /* crypto/srp/srp_lib.c */
 /*
  * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
  * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
  * EdelKey project and contributed to the OpenSSL project 2004.
  */
 /* ====================================================================
  * Copyright (c) 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).
  *
  */
 #ifndef OPENSSL_NO_SRP
 # include "cryptlib.h"
 # include "srp_lcl.h"
 # include <openssl/srp.h>
 # include <openssl/evp.h>
 
 # if (BN_BYTES == 8)
 #  if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__)
 #   define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64)
 #  elif defined(__arch64__)
 #   define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL)
 #  else
 #   define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL)
 #  endif
 # elif (BN_BYTES == 4)
 #  define bn_pack4(a1,a2,a3,a4)  ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL)
 # else
 #  error "unsupported BN_BYTES"
 # endif
 
 # include "srp_grps.h"
 
 static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g)
 {
     /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */
 
     unsigned char digest[SHA_DIGEST_LENGTH];
     unsigned char *tmp;
     EVP_MD_CTX ctxt;
     int longg;
     int longN = BN_num_bytes(N);
 
     if (BN_ucmp(g, N) >= 0)
         return NULL;
 
     if ((tmp = OPENSSL_malloc(longN)) == NULL)
         return NULL;
     BN_bn2bin(N, tmp);
 
     EVP_MD_CTX_init(&ctxt);
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     EVP_DigestUpdate(&ctxt, tmp, longN);
 
     memset(tmp, 0, longN);
     longg = BN_bn2bin(g, tmp);
     /* use the zeros behind to pad on left */
     EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg);
     EVP_DigestUpdate(&ctxt, tmp, longg);
     OPENSSL_free(tmp);
 
     EVP_DigestFinal_ex(&ctxt, digest, NULL);
     EVP_MD_CTX_cleanup(&ctxt);
     return BN_bin2bn(digest, sizeof(digest), NULL);
 }
 
 BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N)
 {
     /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */
 
     BIGNUM *u;
     unsigned char cu[SHA_DIGEST_LENGTH];
     unsigned char *cAB;
     EVP_MD_CTX ctxt;
     int longN;
     if ((A == NULL) || (B == NULL) || (N == NULL))
         return NULL;
 
     if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0)
         return NULL;
 
     longN = BN_num_bytes(N);
 
     if ((cAB = OPENSSL_malloc(2 * longN)) == NULL)
         return NULL;
 
     memset(cAB, 0, longN);
 
     EVP_MD_CTX_init(&ctxt);
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN);
     EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN);
     OPENSSL_free(cAB);
     EVP_DigestFinal_ex(&ctxt, cu, NULL);
     EVP_MD_CTX_cleanup(&ctxt);
 
     if (!(u = BN_bin2bn(cu, sizeof(cu), NULL)))
         return NULL;
     if (!BN_is_zero(u))
         return u;
     BN_free(u);
     return NULL;
 }
 
 BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
                             BIGNUM *N)
 {
     BIGNUM *tmp = NULL, *S = NULL;
     BN_CTX *bn_ctx;
 
     if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
         return NULL;
 
-    if ((bn_ctx = BN_CTX_new()) == NULL ||
-        (tmp = BN_new()) == NULL || (S = BN_new()) == NULL)
+    if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL)
         goto err;
 
     /* S = (A*v**u) ** b */
 
     if (!BN_mod_exp(tmp, v, u, N, bn_ctx))
         goto err;
     if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx))
         goto err;
-    if (!BN_mod_exp(S, tmp, b, N, bn_ctx))
-        goto err;
+
+    S = BN_new();
+    if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) {
+        BN_free(S);
+        S = NULL;
+    }
  err:
     BN_CTX_free(bn_ctx);
     BN_clear_free(tmp);
     return S;
 }
 
 BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v)
 {
     BIGNUM *kv = NULL, *gb = NULL;
     BIGNUM *B = NULL, *k = NULL;
     BN_CTX *bn_ctx;
 
     if (b == NULL || N == NULL || g == NULL || v == NULL ||
         (bn_ctx = BN_CTX_new()) == NULL)
         return NULL;
 
     if ((kv = BN_new()) == NULL ||
         (gb = BN_new()) == NULL || (B = BN_new()) == NULL)
         goto err;
 
     /* B = g**b + k*v */
 
     if (!BN_mod_exp(gb, g, b, N, bn_ctx) ||
         !(k = srp_Calc_k(N, g)) ||
         !BN_mod_mul(kv, v, k, N, bn_ctx) ||
         !BN_mod_add(B, gb, kv, N, bn_ctx)) {
         BN_free(B);
         B = NULL;
     }
  err:
     BN_CTX_free(bn_ctx);
     BN_clear_free(kv);
     BN_clear_free(gb);
     BN_free(k);
     return B;
 }
 
 BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass)
 {
     unsigned char dig[SHA_DIGEST_LENGTH];
     EVP_MD_CTX ctxt;
     unsigned char *cs;
 
     if ((s == NULL) || (user == NULL) || (pass == NULL))
         return NULL;
 
     if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL)
         return NULL;
 
     EVP_MD_CTX_init(&ctxt);
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     EVP_DigestUpdate(&ctxt, user, strlen(user));
     EVP_DigestUpdate(&ctxt, ":", 1);
     EVP_DigestUpdate(&ctxt, pass, strlen(pass));
     EVP_DigestFinal_ex(&ctxt, dig, NULL);
 
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     BN_bn2bin(s, cs);
     EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s));
     OPENSSL_free(cs);
     EVP_DigestUpdate(&ctxt, dig, sizeof(dig));
     EVP_DigestFinal_ex(&ctxt, dig, NULL);
     EVP_MD_CTX_cleanup(&ctxt);
 
     return BN_bin2bn(dig, sizeof(dig), NULL);
 }
 
 BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g)
 {
     BN_CTX *bn_ctx;
     BIGNUM *A = NULL;
 
     if (a == NULL || N == NULL || g == NULL ||
         (bn_ctx = BN_CTX_new()) == NULL)
         return NULL;
 
     if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) {
         BN_free(A);
         A = NULL;
     }
     BN_CTX_free(bn_ctx);
     return A;
 }
 
 BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
                             BIGNUM *a, BIGNUM *u)
 {
     BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL;
     BN_CTX *bn_ctx;
 
     if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL
         || a == NULL || (bn_ctx = BN_CTX_new()) == NULL)
         return NULL;
 
     if ((tmp = BN_new()) == NULL ||
         (tmp2 = BN_new()) == NULL ||
-        (tmp3 = BN_new()) == NULL || (K = BN_new()) == NULL)
+        (tmp3 = BN_new()) == NULL)
         goto err;
 
     if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
         goto err;
     if (!(k = srp_Calc_k(N, g)))
         goto err;
     if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx))
         goto err;
     if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
         goto err;
 
     if (!BN_mod_mul(tmp3, u, x, N, bn_ctx))
         goto err;
     if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx))
         goto err;
-    if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx))
-        goto err;
+    K = BN_new();
+    if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) {
+        BN_free(K);
+        K = NULL;
+    }
 
  err:
     BN_CTX_free(bn_ctx);
     BN_clear_free(tmp);
     BN_clear_free(tmp2);
     BN_clear_free(tmp3);
     BN_free(k);
     return K;
 }
 
 int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N)
 {
     BIGNUM *r;
     BN_CTX *bn_ctx;
     int ret = 0;
 
     if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL)
         return 0;
 
     if ((r = BN_new()) == NULL)
         goto err;
     /* Checks if B % N == 0 */
     if (!BN_nnmod(r, B, N, bn_ctx))
         goto err;
     ret = !BN_is_zero(r);
  err:
     BN_CTX_free(bn_ctx);
     BN_free(r);
     return ret;
 }
 
 int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N)
 {
     /* Checks if A % N == 0 */
     return SRP_Verify_B_mod_N(A, N);
 }
 
 /*
  * Check if G and N are kwown parameters. The values have been generated
  * from the ietf-tls-srp draft version 8
  */
 char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N)
 {
     size_t i;
     if ((g == NULL) || (N == NULL))
         return 0;
 
     srp_bn_print(g);
     srp_bn_print(N);
 
     for (i = 0; i < KNOWN_GN_NUMBER; i++) {
         if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0)
             return knowngN[i].id;
     }
     return NULL;
 }
 
 SRP_gN *SRP_get_default_gN(const char *id)
 {
     size_t i;
 
     if (id == NULL)
         return knowngN;
     for (i = 0; i < KNOWN_GN_NUMBER; i++) {
         if (strcmp(knowngN[i].id, id) == 0)
             return knowngN + i;
     }
     return NULL;
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_vfy.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_vfy.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/srp/srp_vfy.c	(revision 306191)
@@ -1,705 +1,705 @@
 /* crypto/srp/srp_vfy.c */
 /*
  * Written by Christophe Renou (christophe.renou@edelweb.fr) with the
  * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the
  * EdelKey project and contributed to the OpenSSL project 2004.
  */
 /* ====================================================================
  * Copyright (c) 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).
  *
  */
 #ifndef OPENSSL_NO_SRP
 # include "cryptlib.h"
 # include "srp_lcl.h"
 # include <openssl/srp.h>
 # include <openssl/evp.h>
 # include <openssl/buffer.h>
 # include <openssl/rand.h>
 # include <openssl/txt_db.h>
 
 # define SRP_RANDOM_SALT_LEN 20
 # define MAX_LEN 2500
 
 static char b64table[] =
     "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./";
 
 /*
  * the following two conversion routines have been inspired by code from
  * Stanford
  */
 
 /*
  * Convert a base64 string into raw byte array representation.
  */
 static int t_fromb64(unsigned char *a, const char *src)
 {
     char *loc;
     int i, j;
     int size;
 
     while (*src && (*src == ' ' || *src == '\t' || *src == '\n'))
         ++src;
     size = strlen(src);
     i = 0;
     while (i < size) {
         loc = strchr(b64table, src[i]);
         if (loc == (char *)0)
             break;
         else
             a[i] = loc - b64table;
         ++i;
     }
     /* if nothing valid to process we have a zero length response */
     if (i == 0)
         return 0;
     size = i;
     i = size - 1;
     j = size;
     while (1) {
         a[j] = a[i];
         if (--i < 0)
             break;
         a[j] |= (a[i] & 3) << 6;
         --j;
         a[j] = (unsigned char)((a[i] & 0x3c) >> 2);
         if (--i < 0)
             break;
         a[j] |= (a[i] & 0xf) << 4;
         --j;
         a[j] = (unsigned char)((a[i] & 0x30) >> 4);
         if (--i < 0)
             break;
         a[j] |= (a[i] << 2);
 
         a[--j] = 0;
         if (--i < 0)
             break;
     }
     while (a[j] == 0 && j <= size)
         ++j;
     i = 0;
     while (j <= size)
         a[i++] = a[j++];
     return i;
 }
 
 /*
  * Convert a raw byte string into a null-terminated base64 ASCII string.
  */
 static char *t_tob64(char *dst, const unsigned char *src, int size)
 {
     int c, pos = size % 3;
     unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0;
     char *olddst = dst;
 
     switch (pos) {
     case 1:
         b2 = src[0];
         break;
     case 2:
         b1 = src[0];
         b2 = src[1];
         break;
     }
 
     while (1) {
         c = (b0 & 0xfc) >> 2;
         if (notleading || c != 0) {
             *dst++ = b64table[c];
             notleading = 1;
         }
         c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4);
         if (notleading || c != 0) {
             *dst++ = b64table[c];
             notleading = 1;
         }
         c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6);
         if (notleading || c != 0) {
             *dst++ = b64table[c];
             notleading = 1;
         }
         c = b2 & 0x3f;
         if (notleading || c != 0) {
             *dst++ = b64table[c];
             notleading = 1;
         }
         if (pos >= size)
             break;
         else {
             b0 = src[pos++];
             b1 = src[pos++];
             b2 = src[pos++];
         }
     }
 
     *dst++ = '\0';
     return olddst;
 }
 
 void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
 {
     if (user_pwd == NULL)
         return;
     BN_free(user_pwd->s);
     BN_clear_free(user_pwd->v);
     OPENSSL_free(user_pwd->id);
     OPENSSL_free(user_pwd->info);
     OPENSSL_free(user_pwd);
 }
 
 static SRP_user_pwd *SRP_user_pwd_new()
 {
     SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd));
     if (ret == NULL)
         return NULL;
     ret->N = NULL;
     ret->g = NULL;
     ret->s = NULL;
     ret->v = NULL;
     ret->id = NULL;
     ret->info = NULL;
     return ret;
 }
 
 static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
                                 const BIGNUM *N)
 {
     vinfo->N = N;
     vinfo->g = g;
 }
 
 static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id,
                                 const char *info)
 {
     if (id != NULL && NULL == (vinfo->id = BUF_strdup(id)))
         return 0;
     return (info == NULL || NULL != (vinfo->info = BUF_strdup(info)));
 }
 
 static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
                                const char *v)
 {
     unsigned char tmp[MAX_LEN];
     int len;
 
     if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
         return 0;
     len = t_fromb64(tmp, v);
     if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
         return 0;
     len = t_fromb64(tmp, s);
     return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL);
 }
 
 static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
 {
     vinfo->v = v;
     vinfo->s = s;
     return (vinfo->s != NULL && vinfo->v != NULL);
 }
 
 static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
 {
     SRP_user_pwd *ret;
 
     if (src == NULL)
         return NULL;
     if ((ret = SRP_user_pwd_new()) == NULL)
         return NULL;
 
     SRP_user_pwd_set_gN(ret, src->g, src->N);
     if (!SRP_user_pwd_set_ids(ret, src->id, src->info)
         || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) {
             SRP_user_pwd_free(ret);
             return NULL;
     }
     return ret;
 }
 
 SRP_VBASE *SRP_VBASE_new(char *seed_key)
 {
     SRP_VBASE *vb = (SRP_VBASE *)OPENSSL_malloc(sizeof(SRP_VBASE));
 
     if (vb == NULL)
         return NULL;
     if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) ||
         !(vb->gN_cache = sk_SRP_gN_cache_new_null())) {
         OPENSSL_free(vb);
         return NULL;
     }
     vb->default_g = NULL;
     vb->default_N = NULL;
     vb->seed_key = NULL;
     if ((seed_key != NULL) && (vb->seed_key = BUF_strdup(seed_key)) == NULL) {
         sk_SRP_user_pwd_free(vb->users_pwd);
         sk_SRP_gN_cache_free(vb->gN_cache);
         OPENSSL_free(vb);
         return NULL;
     }
     return vb;
 }
 
 int SRP_VBASE_free(SRP_VBASE *vb)
 {
     sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
     sk_SRP_gN_cache_free(vb->gN_cache);
     OPENSSL_free(vb->seed_key);
     OPENSSL_free(vb);
     return 0;
 }
 
 static SRP_gN_cache *SRP_gN_new_init(const char *ch)
 {
     unsigned char tmp[MAX_LEN];
     int len;
 
     SRP_gN_cache *newgN =
         (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache));
     if (newgN == NULL)
         return NULL;
 
     if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
         goto err;
 
     len = t_fromb64(tmp, ch);
     if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
         return newgN;
 
     OPENSSL_free(newgN->b64_bn);
  err:
     OPENSSL_free(newgN);
     return NULL;
 }
 
 static void SRP_gN_free(SRP_gN_cache *gN_cache)
 {
     if (gN_cache == NULL)
         return;
     OPENSSL_free(gN_cache->b64_bn);
     BN_free(gN_cache->bn);
     OPENSSL_free(gN_cache);
 }
 
 static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
 {
     int i;
 
     SRP_gN *gN;
     if (gN_tab != NULL)
         for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) {
             gN = sk_SRP_gN_value(gN_tab, i);
             if (gN && (id == NULL || strcmp(gN->id, id) == 0))
                 return gN;
         }
 
     return SRP_get_default_gN(id);
 }
 
 static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
 {
     int i;
     if (gN_cache == NULL)
         return NULL;
 
     /* search if we have already one... */
     for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) {
         SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
         if (strcmp(cache->b64_bn, ch) == 0)
             return cache->bn;
     }
     {                           /* it is the first time that we find it */
         SRP_gN_cache *newgN = SRP_gN_new_init(ch);
         if (newgN) {
             if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0)
                 return newgN->bn;
             SRP_gN_free(newgN);
         }
     }
     return NULL;
 }
 
 /*
  * this function parses verifier file. Format is:
  * string(index):base64(N):base64(g):0
  * string(username):base64(v):base64(salt):int(index)
  */
 
 int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
 {
     int error_code;
     STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
     char *last_index = NULL;
     int i;
     char **pp;
 
     SRP_gN *gN = NULL;
     SRP_user_pwd *user_pwd = NULL;
 
     TXT_DB *tmpdb = NULL;
     BIO *in = BIO_new(BIO_s_file());
 
     error_code = SRP_ERR_OPEN_FILE;
 
     if (in == NULL || BIO_read_filename(in, verifier_file) <= 0)
         goto err;
 
     error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;
 
     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
         goto err;
 
     error_code = SRP_ERR_MEMORY;
 
     if (vb->seed_key) {
         last_index = SRP_get_default_gN(NULL)->id;
     }
     for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) {
         pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i);
         if (pp[DB_srptype][0] == DB_SRP_INDEX) {
             /*
              * we add this couple in the internal Stack
              */
 
             if ((gN = (SRP_gN *) OPENSSL_malloc(sizeof(SRP_gN))) == NULL)
                 goto err;
 
             if (!(gN->id = BUF_strdup(pp[DB_srpid]))
                 || !(gN->N =
                      SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier]))
                 || !(gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt]))
                 || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0)
                 goto err;
 
             gN = NULL;
 
             if (vb->seed_key != NULL) {
                 last_index = pp[DB_srpid];
             }
         } else if (pp[DB_srptype][0] == DB_SRP_VALID) {
             /* it is a user .... */
             SRP_gN *lgN;
             if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) {
                 error_code = SRP_ERR_MEMORY;
                 if ((user_pwd = SRP_user_pwd_new()) == NULL)
                     goto err;
 
                 SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N);
                 if (!SRP_user_pwd_set_ids
                     (user_pwd, pp[DB_srpid], pp[DB_srpinfo]))
                     goto err;
 
                 error_code = SRP_ERR_VBASE_BN_LIB;
                 if (!SRP_user_pwd_set_sv
                     (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier]))
                     goto err;
 
                 if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
                     goto err;
                 user_pwd = NULL; /* abandon responsability */
             }
         }
     }
 
     if (last_index != NULL) {
         /* this means that we want to simulate a default user */
 
         if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) {
             error_code = SRP_ERR_VBASE_BN_LIB;
             goto err;
         }
         vb->default_g = gN->g;
         vb->default_N = gN->N;
         gN = NULL;
     }
     error_code = SRP_NO_ERROR;
 
  err:
     /*
      * there may be still some leaks to fix, if this fails, the application
      * terminates most likely
      */
 
     if (gN != NULL) {
         OPENSSL_free(gN->id);
         OPENSSL_free(gN);
     }
 
     SRP_user_pwd_free(user_pwd);
 
     if (tmpdb)
         TXT_DB_free(tmpdb);
     if (in)
         BIO_free_all(in);
 
     sk_SRP_gN_free(SRP_gN_tab);
 
     return error_code;
 
 }
 
 static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
 {
     int i;
     SRP_user_pwd *user;
 
     if (vb == NULL)
         return NULL;
 
     for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) {
         user = sk_SRP_user_pwd_value(vb->users_pwd, i);
         if (strcmp(user->id, username) == 0)
             return user;
     }
 
     return NULL;
 }
 
 /*
  * This method ignores the configured seed and fails for an unknown user.
  * Ownership of the returned pointer is not released to the caller.
  * In other words, caller must not free the result.
  */
 SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
 {
     return find_user(vb, username);
 }
 
 /*
  * Ownership of the returned pointer is released to the caller.
  * In other words, caller must free the result once done.
  */
 SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
 {
     SRP_user_pwd *user;
     unsigned char digv[SHA_DIGEST_LENGTH];
     unsigned char digs[SHA_DIGEST_LENGTH];
     EVP_MD_CTX ctxt;
 
     if (vb == NULL)
         return NULL;
 
     if ((user = find_user(vb, username)) != NULL)
         return srp_user_pwd_dup(user);
 
     if ((vb->seed_key == NULL) ||
         (vb->default_g == NULL) || (vb->default_N == NULL))
         return NULL;
 
 /* if the user is unknown we set parameters as well if we have a seed_key */
 
     if ((user = SRP_user_pwd_new()) == NULL)
         return NULL;
 
     SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N);
 
     if (!SRP_user_pwd_set_ids(user, username, NULL))
         goto err;
 
-    if (RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH) < 0)
+    if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
         goto err;
     EVP_MD_CTX_init(&ctxt);
     EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
     EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key));
     EVP_DigestUpdate(&ctxt, username, strlen(username));
     EVP_DigestFinal_ex(&ctxt, digs, NULL);
     EVP_MD_CTX_cleanup(&ctxt);
     if (SRP_user_pwd_set_sv_BN
         (user, BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
          BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
         return user;
 
  err:SRP_user_pwd_free(user);
     return NULL;
 }
 
 /*
  * create a verifier (*salt,*verifier,g and N are in base64)
  */
 char *SRP_create_verifier(const char *user, const char *pass, char **salt,
                           char **verifier, const char *N, const char *g)
 {
     int len;
     char *result = NULL, *vf = NULL;
     BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL;
     unsigned char tmp[MAX_LEN];
     unsigned char tmp2[MAX_LEN];
     char *defgNid = NULL;
     int vfsize = 0;
 
     if ((user == NULL) ||
         (pass == NULL) || (salt == NULL) || (verifier == NULL))
         goto err;
 
     if (N) {
         if (!(len = t_fromb64(tmp, N)))
             goto err;
         N_bn = BN_bin2bn(tmp, len, NULL);
         if (!(len = t_fromb64(tmp, g)))
             goto err;
         g_bn = BN_bin2bn(tmp, len, NULL);
         defgNid = "*";
     } else {
         SRP_gN *gN = SRP_get_gN_by_id(g, NULL);
         if (gN == NULL)
             goto err;
         N_bn = gN->N;
         g_bn = gN->g;
         defgNid = gN->id;
     }
 
     if (*salt == NULL) {
-        if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
             goto err;
 
         s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
     } else {
         if (!(len = t_fromb64(tmp2, *salt)))
             goto err;
         s = BN_bin2bn(tmp2, len, NULL);
     }
 
     if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn))
         goto err;
 
     BN_bn2bin(v, tmp);
     vfsize = BN_num_bytes(v) * 2;
     if (((vf = OPENSSL_malloc(vfsize)) == NULL))
         goto err;
     t_tob64(vf, tmp, BN_num_bytes(v));
 
     if (*salt == NULL) {
         char *tmp_salt;
 
         if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) {
             goto err;
         }
         t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN);
         *salt = tmp_salt;
     }
 
     *verifier = vf;
     vf = NULL;
     result = defgNid;
 
  err:
     if (N) {
         BN_free(N_bn);
         BN_free(g_bn);
     }
     OPENSSL_cleanse(vf, vfsize);
     OPENSSL_free(vf);
     BN_clear_free(s);
     BN_clear_free(v);
     return result;
 }
 
 /*
  * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
  * then the provided salt will be used. On successful exit *verifier will point
  * to a newly allocated BIGNUM containing the verifier and (if a salt was not
  * provided) *salt will be populated with a newly allocated BIGNUM containing a
  * random salt.
  * The caller is responsible for freeing the allocated *salt and *verifier
  * BIGNUMS.
  */
 int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
                            BIGNUM **verifier, BIGNUM *N, BIGNUM *g)
 {
     int result = 0;
     BIGNUM *x = NULL;
     BN_CTX *bn_ctx = BN_CTX_new();
     unsigned char tmp2[MAX_LEN];
     BIGNUM *salttmp = NULL;
 
     if ((user == NULL) ||
         (pass == NULL) ||
         (salt == NULL) ||
         (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL))
         goto err;
 
     srp_bn_print(N);
     srp_bn_print(g);
 
     if (*salt == NULL) {
-        if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+        if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
             goto err;
 
         salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
     } else {
         salttmp = *salt;
     }
 
     x = SRP_Calc_x(salttmp, user, pass);
 
     *verifier = BN_new();
     if (*verifier == NULL)
         goto err;
 
     if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) {
         BN_clear_free(*verifier);
         goto err;
     }
 
     srp_bn_print(*verifier);
 
     result = 1;
     *salt = salttmp;
 
  err:
     if (*salt != salttmp)
         BN_clear_free(salttmp);
     BN_clear_free(x);
     BN_CTX_free(bn_ctx);
     return result;
 }
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/ts/ts_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/ts/ts_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/ts/ts_lib.c	(revision 306191)
@@ -1,143 +1,142 @@
 /* crypto/ts/ts_lib.c */
 /*
  * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project
  * 2002.
  */
 /* ====================================================================
  * 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/objects.h>
 #include <openssl/bn.h>
 #include <openssl/x509v3.h>
 #include "ts.h"
 
 /* Local function declarations. */
 
 /* Function definitions. */
 
 int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num)
 {
     BIGNUM num_bn;
     int result = 0;
     char *hex;
 
     BN_init(&num_bn);
     ASN1_INTEGER_to_BN(num, &num_bn);
     if ((hex = BN_bn2hex(&num_bn))) {
         result = BIO_write(bio, "0x", 2) > 0;
         result = result && BIO_write(bio, hex, strlen(hex)) > 0;
         OPENSSL_free(hex);
     }
     BN_free(&num_bn);
 
     return result;
 }
 
 int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
 {
     char obj_txt[128];
 
-    int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
-    BIO_write(bio, obj_txt, len);
-    BIO_write(bio, "\n", 1);
+    OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
+    BIO_printf(bio, "%s\n", obj_txt);
 
     return 1;
 }
 
 int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions)
 {
     int i, critical, n;
     X509_EXTENSION *ex;
     ASN1_OBJECT *obj;
 
     BIO_printf(bio, "Extensions:\n");
     n = X509v3_get_ext_count(extensions);
     for (i = 0; i < n; i++) {
         ex = X509v3_get_ext(extensions, i);
         obj = X509_EXTENSION_get_object(ex);
         i2a_ASN1_OBJECT(bio, obj);
         critical = X509_EXTENSION_get_critical(ex);
         BIO_printf(bio, ": %s\n", critical ? "critical" : "");
         if (!X509V3_EXT_print(bio, ex, 0, 4)) {
             BIO_printf(bio, "%4s", "");
             M_ASN1_OCTET_STRING_print(bio, ex->value);
         }
         BIO_write(bio, "\n", 1);
     }
 
     return 1;
 }
 
 int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg)
 {
     int i = OBJ_obj2nid(alg->algorithm);
     return BIO_printf(bio, "Hash Algorithm: %s\n",
                       (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
 }
 
 int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a)
 {
     const ASN1_OCTET_STRING *msg;
 
     TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a));
 
     BIO_printf(bio, "Message data:\n");
     msg = TS_MSG_IMPRINT_get_msg(a);
     BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg),
                     M_ASN1_STRING_length(msg), 4);
 
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/whrlpool/wp_dgst.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/whrlpool/wp_dgst.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/whrlpool/wp_dgst.c	(revision 306191)
@@ -1,257 +1,258 @@
 /**
  * The Whirlpool hashing function.
  *
  * <P>
  * <b>References</b>
  *
  * <P>
  * The Whirlpool algorithm was developed by
  * <a href="mailto:pbarreto@scopus.com.br">Paulo S. L. M. Barreto</a> and
  * <a href="mailto:vincent.rijmen@cryptomathic.com">Vincent Rijmen</a>.
  *
  * See
  *      P.S.L.M. Barreto, V. Rijmen,
  *      ``The Whirlpool hashing function,''
  *      NESSIE submission, 2000 (tweaked version, 2001),
  *      <https://www.cosic.esat.kuleuven.ac.be/nessie/workshop/submissions/whirlpool.zip>
  *
  * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and
  * Vincent Rijmen. Lookup "reference implementations" on
  * <http://planeta.terra.com.br/informatica/paulobarreto/>
  *
  * =============================================================================
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''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 AUTHORS 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.
  *
  */
 
 /*
  * OpenSSL-specific implementation notes.
  *
  * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect
  * number of *bytes* as input length argument. Bit-oriented routine
  * as specified by authors is called WHIRLPOOL_BitUpdate[!] and
  * does not have one-stroke counterpart.
  *
  * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially
  * to serve WHIRLPOOL_Update. This is done for performance.
  *
  * Unlike authors' reference implementation, block processing
  * routine whirlpool_block is designed to operate on multi-block
  * input. This is done for perfomance.
  */
 
+#include <openssl/crypto.h>
 #include "wp_locl.h"
 #include <openssl/crypto.h>
 #include <string.h>
 
 fips_md_init(WHIRLPOOL)
 {
     memset(c, 0, sizeof(*c));
     return (1);
 }
 
 int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes)
 {
     /*
      * Well, largest suitable chunk size actually is
      * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not
      * to care about excessive calls to WHIRLPOOL_BitUpdate...
      */
     size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4);
     const unsigned char *inp = _inp;
 
     while (bytes >= chunk) {
         WHIRLPOOL_BitUpdate(c, inp, chunk * 8);
         bytes -= chunk;
         inp += chunk;
     }
     if (bytes)
         WHIRLPOOL_BitUpdate(c, inp, bytes * 8);
 
     return (1);
 }
 
 void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits)
 {
     size_t n;
     unsigned int bitoff = c->bitoff,
         bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7;
     const unsigned char *inp = _inp;
 
     /*
      * This 256-bit increment procedure relies on the size_t being natural
      * size of CPU register, so that we don't have to mask the value in order
      * to detect overflows.
      */
     c->bitlen[0] += bits;
     if (c->bitlen[0] < bits) {  /* overflow */
         n = 1;
         do {
             c->bitlen[n]++;
         } while (c->bitlen[n] == 0
                  && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t)));
     }
 #ifndef OPENSSL_SMALL_FOOTPRINT
  reconsider:
     if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */
         while (bits) {
             if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) {
                 whirlpool_block(c, inp, n);
                 inp += n * WHIRLPOOL_BBLOCK / 8;
                 bits %= WHIRLPOOL_BBLOCK;
             } else {
                 unsigned int byteoff = bitoff / 8;
 
                 bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */
                 if (bits >= bitrem) {
                     bits -= bitrem;
                     bitrem /= 8;
                     memcpy(c->data + byteoff, inp, bitrem);
                     inp += bitrem;
                     whirlpool_block(c, c->data, 1);
                     bitoff = 0;
                 } else {
                     memcpy(c->data + byteoff, inp, bits / 8);
                     bitoff += (unsigned int)bits;
                     bits = 0;
                 }
                 c->bitoff = bitoff;
             }
         }
     } else                      /* bit-oriented loop */
 #endif
     {
         /*-
                    inp
                    |
                    +-------+-------+-------
                       |||||||||||||||||||||
                    +-------+-------+-------
         +-------+-------+-------+-------+-------
         ||||||||||||||                          c->data
         +-------+-------+-------+-------+-------
                 |
                 c->bitoff/8
         */
         while (bits) {
             unsigned int byteoff = bitoff / 8;
             unsigned char b;
 
 #ifndef OPENSSL_SMALL_FOOTPRINT
             if (bitrem == inpgap) {
                 c->data[byteoff++] |= inp[0] & (0xff >> inpgap);
                 inpgap = 8 - inpgap;
                 bitoff += inpgap;
                 bitrem = 0;     /* bitoff%8 */
                 bits -= inpgap;
                 inpgap = 0;     /* bits%8 */
                 inp++;
                 if (bitoff == WHIRLPOOL_BBLOCK) {
                     whirlpool_block(c, c->data, 1);
                     bitoff = 0;
                 }
                 c->bitoff = bitoff;
                 goto reconsider;
             } else
 #endif
             if (bits >= 8) {
                 b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap)));
                 b &= 0xff;
                 if (bitrem)
                     c->data[byteoff++] |= b >> bitrem;
                 else
                     c->data[byteoff++] = b;
                 bitoff += 8;
                 bits -= 8;
                 inp++;
                 if (bitoff >= WHIRLPOOL_BBLOCK) {
                     whirlpool_block(c, c->data, 1);
                     byteoff = 0;
                     bitoff %= WHIRLPOOL_BBLOCK;
                 }
                 if (bitrem)
                     c->data[byteoff] = b << (8 - bitrem);
             } else {            /* remaining less than 8 bits */
 
                 b = (inp[0] << inpgap) & 0xff;
                 if (bitrem)
                     c->data[byteoff++] |= b >> bitrem;
                 else
                     c->data[byteoff++] = b;
                 bitoff += (unsigned int)bits;
                 if (bitoff == WHIRLPOOL_BBLOCK) {
                     whirlpool_block(c, c->data, 1);
                     byteoff = 0;
                     bitoff %= WHIRLPOOL_BBLOCK;
                 }
                 if (bitrem)
                     c->data[byteoff] = b << (8 - bitrem);
                 bits = 0;
             }
             c->bitoff = bitoff;
         }
     }
 }
 
 int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c)
 {
     unsigned int bitoff = c->bitoff, byteoff = bitoff / 8;
     size_t i, j, v;
     unsigned char *p;
 
     bitoff %= 8;
     if (bitoff)
         c->data[byteoff] |= 0x80 >> bitoff;
     else
         c->data[byteoff] = 0x80;
     byteoff++;
 
     /* pad with zeros */
     if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) {
         if (byteoff < WHIRLPOOL_BBLOCK / 8)
             memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff);
         whirlpool_block(c, c->data, 1);
         byteoff = 0;
     }
     if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER))
         memset(&c->data[byteoff], 0,
                (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff);
     /* smash 256-bit c->bitlen in big-endian order */
     p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */
     for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++)
         for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8)
             *p-- = (unsigned char)(v & 0xff);
 
     whirlpool_block(c, c->data, 1);
 
     if (md) {
         memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH);
-        memset(c, 0, sizeof(*c));
+        OPENSSL_cleanse(c, sizeof(*c));
         return (1);
     }
     return (0);
 }
 
 unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md)
 {
     WHIRLPOOL_CTX ctx;
     static unsigned char m[WHIRLPOOL_DIGEST_LENGTH];
 
     if (md == NULL)
         md = m;
     WHIRLPOOL_Init(&ctx);
     WHIRLPOOL_Update(&ctx, inp, bytes);
     WHIRLPOOL_Final(md, &ctx);
     return (md);
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509.h	(revision 306191)
@@ -1,1302 +1,1304 @@
 /* crypto/x509/x509.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.]
  */
 /* ====================================================================
  * 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_X509_H
 # define HEADER_X509_H
 
 # include <openssl/e_os2.h>
 # include <openssl/symhacks.h>
 # ifndef OPENSSL_NO_BUFFER
 #  include <openssl/buffer.h>
 # endif
 # ifndef OPENSSL_NO_EVP
 #  include <openssl/evp.h>
 # endif
 # ifndef OPENSSL_NO_BIO
 #  include <openssl/bio.h>
 # endif
 # include <openssl/stack.h>
 # include <openssl/asn1.h>
 # include <openssl/safestack.h>
 
 # ifndef OPENSSL_NO_EC
 #  include <openssl/ec.h>
 # endif
 
 # ifndef OPENSSL_NO_ECDSA
 #  include <openssl/ecdsa.h>
 # endif
 
 # ifndef OPENSSL_NO_ECDH
 #  include <openssl/ecdh.h>
 # endif
 
 # ifndef OPENSSL_NO_DEPRECATED
 #  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
 # endif
 
 # ifndef OPENSSL_NO_SHA
 #  include <openssl/sha.h>
 # endif
 # include <openssl/ossl_typ.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 # ifdef OPENSSL_SYS_WIN32
 /* Under Win32 these are defined in wincrypt.h */
 #  undef X509_NAME
 #  undef X509_CERT_PAIR
 #  undef X509_EXTENSIONS
 # endif
 
 # define X509_FILETYPE_PEM       1
 # define X509_FILETYPE_ASN1      2
 # define X509_FILETYPE_DEFAULT   3
 
 # define X509v3_KU_DIGITAL_SIGNATURE     0x0080
 # define X509v3_KU_NON_REPUDIATION       0x0040
 # define X509v3_KU_KEY_ENCIPHERMENT      0x0020
 # define X509v3_KU_DATA_ENCIPHERMENT     0x0010
 # define X509v3_KU_KEY_AGREEMENT         0x0008
 # define X509v3_KU_KEY_CERT_SIGN         0x0004
 # define X509v3_KU_CRL_SIGN              0x0002
 # define X509v3_KU_ENCIPHER_ONLY         0x0001
 # define X509v3_KU_DECIPHER_ONLY         0x8000
 # define X509v3_KU_UNDEF                 0xffff
 
 typedef struct X509_objects_st {
     int nid;
     int (*a2i) (void);
     int (*i2a) (void);
 } X509_OBJECTS;
 
 struct X509_algor_st {
     ASN1_OBJECT *algorithm;
     ASN1_TYPE *parameter;
 } /* X509_ALGOR */ ;
 
 DECLARE_ASN1_SET_OF(X509_ALGOR)
 
 typedef STACK_OF(X509_ALGOR) X509_ALGORS;
 
 typedef struct X509_val_st {
     ASN1_TIME *notBefore;
     ASN1_TIME *notAfter;
 } X509_VAL;
 
 struct X509_pubkey_st {
     X509_ALGOR *algor;
     ASN1_BIT_STRING *public_key;
     EVP_PKEY *pkey;
 };
 
 typedef struct X509_sig_st {
     X509_ALGOR *algor;
     ASN1_OCTET_STRING *digest;
 } X509_SIG;
 
 typedef struct X509_name_entry_st {
     ASN1_OBJECT *object;
     ASN1_STRING *value;
     int set;
     int size;                   /* temp variable */
 } X509_NAME_ENTRY;
 
 DECLARE_STACK_OF(X509_NAME_ENTRY)
 DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
 
 /* we always keep X509_NAMEs in 2 forms. */
 struct X509_name_st {
     STACK_OF(X509_NAME_ENTRY) *entries;
     int modified;               /* true if 'bytes' needs to be built */
 # ifndef OPENSSL_NO_BUFFER
     BUF_MEM *bytes;
 # else
     char *bytes;
 # endif
 /*      unsigned long hash; Keep the hash around for lookups */
     unsigned char *canon_enc;
     int canon_enclen;
 } /* X509_NAME */ ;
 
 DECLARE_STACK_OF(X509_NAME)
 
 # define X509_EX_V_NETSCAPE_HACK         0x8000
 # define X509_EX_V_INIT                  0x0001
 typedef struct X509_extension_st {
     ASN1_OBJECT *object;
     ASN1_BOOLEAN critical;
     ASN1_OCTET_STRING *value;
 } X509_EXTENSION;
 
 typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
 
 DECLARE_STACK_OF(X509_EXTENSION)
 DECLARE_ASN1_SET_OF(X509_EXTENSION)
 
 /* a sequence of these are used */
 typedef struct x509_attributes_st {
     ASN1_OBJECT *object;
     int single;                 /* 0 for a set, 1 for a single item (which is
                                  * wrong) */
     union {
         char *ptr;
         /*
          * 0
          */ STACK_OF(ASN1_TYPE) *set;
         /*
          * 1
          */ ASN1_TYPE *single;
     } value;
 } X509_ATTRIBUTE;
 
 DECLARE_STACK_OF(X509_ATTRIBUTE)
 DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
 
 typedef struct X509_req_info_st {
     ASN1_ENCODING enc;
     ASN1_INTEGER *version;
     X509_NAME *subject;
     X509_PUBKEY *pubkey;
     /*  d=2 hl=2 l=  0 cons: cont: 00 */
     STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
 } X509_REQ_INFO;
 
 typedef struct X509_req_st {
     X509_REQ_INFO *req_info;
     X509_ALGOR *sig_alg;
     ASN1_BIT_STRING *signature;
     int references;
 } X509_REQ;
 
 typedef struct x509_cinf_st {
     ASN1_INTEGER *version;      /* [ 0 ] default of v1 */
     ASN1_INTEGER *serialNumber;
     X509_ALGOR *signature;
     X509_NAME *issuer;
     X509_VAL *validity;
     X509_NAME *subject;
     X509_PUBKEY *key;
     ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */
     ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
     STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
     ASN1_ENCODING enc;
 } X509_CINF;
 
 /*
  * This stuff is certificate "auxiliary info" it contains details which are
  * useful in certificate stores and databases. When used this is tagged onto
  * the end of the certificate itself
  */
 
 typedef struct x509_cert_aux_st {
     STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
     STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
     ASN1_UTF8STRING *alias;     /* "friendly name" */
     ASN1_OCTET_STRING *keyid;   /* key id of private key */
     STACK_OF(X509_ALGOR) *other; /* other unspecified info */
 } X509_CERT_AUX;
 
 struct x509_st {
     X509_CINF *cert_info;
     X509_ALGOR *sig_alg;
     ASN1_BIT_STRING *signature;
     int valid;
     int references;
     char *name;
     CRYPTO_EX_DATA ex_data;
     /* These contain copies of various extension values */
     long ex_pathlen;
     long ex_pcpathlen;
     unsigned long ex_flags;
     unsigned long ex_kusage;
     unsigned long ex_xkusage;
     unsigned long ex_nscert;
     ASN1_OCTET_STRING *skid;
     AUTHORITY_KEYID *akid;
     X509_POLICY_CACHE *policy_cache;
     STACK_OF(DIST_POINT) *crldp;
     STACK_OF(GENERAL_NAME) *altname;
     NAME_CONSTRAINTS *nc;
 # ifndef OPENSSL_NO_RFC3779
     STACK_OF(IPAddressFamily) *rfc3779_addr;
     struct ASIdentifiers_st *rfc3779_asid;
 # endif
 # ifndef OPENSSL_NO_SHA
     unsigned char sha1_hash[SHA_DIGEST_LENGTH];
 # endif
     X509_CERT_AUX *aux;
 } /* X509 */ ;
 
 DECLARE_STACK_OF(X509)
 DECLARE_ASN1_SET_OF(X509)
 
 /* This is used for a table of trust checking functions */
 
 typedef struct x509_trust_st {
     int trust;
     int flags;
     int (*check_trust) (struct x509_trust_st *, X509 *, int);
     char *name;
     int arg1;
     void *arg2;
 } X509_TRUST;
 
 DECLARE_STACK_OF(X509_TRUST)
 
 typedef struct x509_cert_pair_st {
     X509 *forward;
     X509 *reverse;
 } X509_CERT_PAIR;
 
 /* standard trust ids */
 
 # define X509_TRUST_DEFAULT      -1/* Only valid in purpose settings */
 
 # define X509_TRUST_COMPAT       1
 # define X509_TRUST_SSL_CLIENT   2
 # define X509_TRUST_SSL_SERVER   3
 # define X509_TRUST_EMAIL        4
 # define X509_TRUST_OBJECT_SIGN  5
 # define X509_TRUST_OCSP_SIGN    6
 # define X509_TRUST_OCSP_REQUEST 7
 # define X509_TRUST_TSA          8
 
 /* Keep these up to date! */
 # define X509_TRUST_MIN          1
 # define X509_TRUST_MAX          8
 
 /* trust_flags values */
 # define X509_TRUST_DYNAMIC      1
 # define X509_TRUST_DYNAMIC_NAME 2
 
 /* check_trust return codes */
 
 # define X509_TRUST_TRUSTED      1
 # define X509_TRUST_REJECTED     2
 # define X509_TRUST_UNTRUSTED    3
 
 /* Flags for X509_print_ex() */
 
 # define X509_FLAG_COMPAT                0
 # define X509_FLAG_NO_HEADER             1L
 # define X509_FLAG_NO_VERSION            (1L << 1)
 # define X509_FLAG_NO_SERIAL             (1L << 2)
 # define X509_FLAG_NO_SIGNAME            (1L << 3)
 # define X509_FLAG_NO_ISSUER             (1L << 4)
 # define X509_FLAG_NO_VALIDITY           (1L << 5)
 # define X509_FLAG_NO_SUBJECT            (1L << 6)
 # define X509_FLAG_NO_PUBKEY             (1L << 7)
 # define X509_FLAG_NO_EXTENSIONS         (1L << 8)
 # define X509_FLAG_NO_SIGDUMP            (1L << 9)
 # define X509_FLAG_NO_AUX                (1L << 10)
 # define X509_FLAG_NO_ATTRIBUTES         (1L << 11)
 
 /* Flags specific to X509_NAME_print_ex() */
 
 /* The field separator information */
 
 # define XN_FLAG_SEP_MASK        (0xf << 16)
 
 # define XN_FLAG_COMPAT          0/* Traditional SSLeay: use old
                                    * X509_NAME_print */
 # define XN_FLAG_SEP_COMMA_PLUS  (1 << 16)/* RFC2253 ,+ */
 # define XN_FLAG_SEP_CPLUS_SPC   (2 << 16)/* ,+ spaced: more readable */
 # define XN_FLAG_SEP_SPLUS_SPC   (3 << 16)/* ;+ spaced */
 # define XN_FLAG_SEP_MULTILINE   (4 << 16)/* One line per field */
 
 # define XN_FLAG_DN_REV          (1 << 20)/* Reverse DN order */
 
 /* How the field name is shown */
 
 # define XN_FLAG_FN_MASK         (0x3 << 21)
 
 # define XN_FLAG_FN_SN           0/* Object short name */
 # define XN_FLAG_FN_LN           (1 << 21)/* Object long name */
 # define XN_FLAG_FN_OID          (2 << 21)/* Always use OIDs */
 # define XN_FLAG_FN_NONE         (3 << 21)/* No field names */
 
 # define XN_FLAG_SPC_EQ          (1 << 23)/* Put spaces round '=' */
 
 /*
  * This determines if we dump fields we don't recognise: RFC2253 requires
  * this.
  */
 
 # define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24)
 
 # define XN_FLAG_FN_ALIGN        (1 << 25)/* Align field names to 20
                                            * characters */
 
 /* Complete set of RFC2253 flags */
 
 # define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \
                         XN_FLAG_SEP_COMMA_PLUS | \
                         XN_FLAG_DN_REV | \
                         XN_FLAG_FN_SN | \
                         XN_FLAG_DUMP_UNKNOWN_FIELDS)
 
 /* readable oneline form */
 
 # define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \
                         ASN1_STRFLGS_ESC_QUOTE | \
                         XN_FLAG_SEP_CPLUS_SPC | \
                         XN_FLAG_SPC_EQ | \
                         XN_FLAG_FN_SN)
 
 /* readable multiline form */
 
 # define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \
                         ASN1_STRFLGS_ESC_MSB | \
                         XN_FLAG_SEP_MULTILINE | \
                         XN_FLAG_SPC_EQ | \
                         XN_FLAG_FN_LN | \
                         XN_FLAG_FN_ALIGN)
 
 struct x509_revoked_st {
     ASN1_INTEGER *serialNumber;
     ASN1_TIME *revocationDate;
     STACK_OF(X509_EXTENSION) /* optional */ *extensions;
     /* Set up if indirect CRL */
     STACK_OF(GENERAL_NAME) *issuer;
     /* Revocation reason */
     int reason;
     int sequence;               /* load sequence */
 };
 
 DECLARE_STACK_OF(X509_REVOKED)
 DECLARE_ASN1_SET_OF(X509_REVOKED)
 
 typedef struct X509_crl_info_st {
     ASN1_INTEGER *version;
     X509_ALGOR *sig_alg;
     X509_NAME *issuer;
     ASN1_TIME *lastUpdate;
     ASN1_TIME *nextUpdate;
     STACK_OF(X509_REVOKED) *revoked;
     STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
     ASN1_ENCODING enc;
 } X509_CRL_INFO;
 
 struct X509_crl_st {
     /* actual signature */
     X509_CRL_INFO *crl;
     X509_ALGOR *sig_alg;
     ASN1_BIT_STRING *signature;
     int references;
     int flags;
     /* Copies of various extensions */
     AUTHORITY_KEYID *akid;
     ISSUING_DIST_POINT *idp;
     /* Convenient breakdown of IDP */
     int idp_flags;
     int idp_reasons;
     /* CRL and base CRL numbers for delta processing */
     ASN1_INTEGER *crl_number;
     ASN1_INTEGER *base_crl_number;
 # ifndef OPENSSL_NO_SHA
     unsigned char sha1_hash[SHA_DIGEST_LENGTH];
 # endif
     STACK_OF(GENERAL_NAMES) *issuers;
     const X509_CRL_METHOD *meth;
     void *meth_data;
 } /* X509_CRL */ ;
 
 DECLARE_STACK_OF(X509_CRL)
 DECLARE_ASN1_SET_OF(X509_CRL)
 
 typedef struct private_key_st {
     int version;
     /* The PKCS#8 data types */
     X509_ALGOR *enc_algor;
     ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */
     /* When decrypted, the following will not be NULL */
     EVP_PKEY *dec_pkey;
     /* used to encrypt and decrypt */
     int key_length;
     char *key_data;
     int key_free;               /* true if we should auto free key_data */
     /* expanded version of 'enc_algor' */
     EVP_CIPHER_INFO cipher;
     int references;
 } X509_PKEY;
 
 # ifndef OPENSSL_NO_EVP
 typedef struct X509_info_st {
     X509 *x509;
     X509_CRL *crl;
     X509_PKEY *x_pkey;
     EVP_CIPHER_INFO enc_cipher;
     int enc_len;
     char *enc_data;
     int references;
 } X509_INFO;
 
 DECLARE_STACK_OF(X509_INFO)
 # endif
 
 /*
  * The next 2 structures and their 8 routines were sent to me by Pat Richard
  * <patr@x509.com> and are used to manipulate Netscapes spki structures -
  * useful if you are writing a CA web page
  */
 typedef struct Netscape_spkac_st {
     X509_PUBKEY *pubkey;
     ASN1_IA5STRING *challenge;  /* challenge sent in atlas >= PR2 */
 } NETSCAPE_SPKAC;
 
 typedef struct Netscape_spki_st {
     NETSCAPE_SPKAC *spkac;      /* signed public key and challenge */
     X509_ALGOR *sig_algor;
     ASN1_BIT_STRING *signature;
 } NETSCAPE_SPKI;
 
 /* Netscape certificate sequence structure */
 typedef struct Netscape_certificate_sequence {
     ASN1_OBJECT *type;
     STACK_OF(X509) *certs;
 } NETSCAPE_CERT_SEQUENCE;
 
 /*- Unused (and iv length is wrong)
 typedef struct CBCParameter_st
         {
         unsigned char iv[8];
         } CBC_PARAM;
 */
 
 /* Password based encryption structure */
 
 typedef struct PBEPARAM_st {
     ASN1_OCTET_STRING *salt;
     ASN1_INTEGER *iter;
 } PBEPARAM;
 
 /* Password based encryption V2 structures */
 
 typedef struct PBE2PARAM_st {
     X509_ALGOR *keyfunc;
     X509_ALGOR *encryption;
 } PBE2PARAM;
 
 typedef struct PBKDF2PARAM_st {
 /* Usually OCTET STRING but could be anything */
     ASN1_TYPE *salt;
     ASN1_INTEGER *iter;
     ASN1_INTEGER *keylength;
     X509_ALGOR *prf;
 } PBKDF2PARAM;
 
 /* PKCS#8 private key info structure */
 
 struct pkcs8_priv_key_info_st {
     /* Flag for various broken formats */
     int broken;
 # define PKCS8_OK                0
 # define PKCS8_NO_OCTET          1
 # define PKCS8_EMBEDDED_PARAM    2
 # define PKCS8_NS_DB             3
 # define PKCS8_NEG_PRIVKEY       4
     ASN1_INTEGER *version;
     X509_ALGOR *pkeyalg;
     /* Should be OCTET STRING but some are broken */
     ASN1_TYPE *pkey;
     STACK_OF(X509_ATTRIBUTE) *attributes;
 };
 
 #ifdef  __cplusplus
 }
 #endif
 
 # include <openssl/x509_vfy.h>
 # include <openssl/pkcs7.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 # define X509_EXT_PACK_UNKNOWN   1
 # define X509_EXT_PACK_STRING    2
 
 # define         X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version)
 /* #define      X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */
 # define         X509_get_notBefore(x) ((x)->cert_info->validity->notBefore)
 # define         X509_get_notAfter(x) ((x)->cert_info->validity->notAfter)
 # define         X509_extract_key(x)     X509_get_pubkey(x)/*****/
 # define         X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version)
 # define         X509_REQ_get_subject_name(x) ((x)->req_info->subject)
 # define         X509_REQ_extract_key(a) X509_REQ_get_pubkey(a)
 # define         X509_name_cmp(a,b)      X509_NAME_cmp((a),(b))
 # define         X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm))
 
 # define         X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version)
 # define         X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
 # define         X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
 # define         X509_CRL_get_issuer(x) ((x)->crl->issuer)
 # define         X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
 
 void X509_CRL_set_default_method(const X509_CRL_METHOD *meth);
 X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
                                      int (*crl_free) (X509_CRL *crl),
                                      int (*crl_lookup) (X509_CRL *crl,
                                                         X509_REVOKED **ret,
                                                         ASN1_INTEGER *ser,
                                                         X509_NAME *issuer),
                                      int (*crl_verify) (X509_CRL *crl,
                                                         EVP_PKEY *pk));
 void X509_CRL_METHOD_free(X509_CRL_METHOD *m);
 
 void X509_CRL_set_meth_data(X509_CRL *crl, void *dat);
 void *X509_CRL_get_meth_data(X509_CRL *crl);
 
 /*
  * This one is only used so that a binary form can output, as in
  * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf)
  */
 # define         X509_get_X509_PUBKEY(x) ((x)->cert_info->key)
 
 const char *X509_verify_cert_error_string(long n);
 
 # ifndef OPENSSL_NO_EVP
 int X509_verify(X509 *a, EVP_PKEY *r);
 
 int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r);
 int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r);
 int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r);
 
 NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len);
 char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x);
 EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x);
 int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey);
 
 int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki);
 
 int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent);
 int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig);
 
 int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
 int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx);
 int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md);
 int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx);
 int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md);
 int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx);
 int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md);
 
 int X509_pubkey_digest(const X509 *data, const EVP_MD *type,
                        unsigned char *md, unsigned int *len);
 int X509_digest(const X509 *data, const EVP_MD *type,
                 unsigned char *md, unsigned int *len);
 int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len);
 int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type,
                     unsigned char *md, unsigned int *len);
 int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type,
                      unsigned char *md, unsigned int *len);
 # endif
 
 # ifndef OPENSSL_NO_FP_API
 X509 *d2i_X509_fp(FILE *fp, X509 **x509);
 int i2d_X509_fp(FILE *fp, X509 *x509);
 X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl);
 int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl);
 X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req);
 int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req);
 #  ifndef OPENSSL_NO_RSA
 RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa);
 int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa);
 RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa);
 int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa);
 RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa);
 int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa);
 #  endif
 #  ifndef OPENSSL_NO_DSA
 DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa);
 int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa);
 DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa);
 int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa);
 #  endif
 #  ifndef OPENSSL_NO_EC
 EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey);
 int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey);
 EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey);
 int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey);
 #  endif
 X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8);
 int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8);
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,
                                                 PKCS8_PRIV_KEY_INFO **p8inf);
 int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf);
 int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key);
 int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a);
 int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a);
 # endif
 
 # ifndef OPENSSL_NO_BIO
 X509 *d2i_X509_bio(BIO *bp, X509 **x509);
 int i2d_X509_bio(BIO *bp, X509 *x509);
 X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl);
 int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl);
 X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req);
 int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req);
 #  ifndef OPENSSL_NO_RSA
 RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa);
 int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa);
 RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa);
 int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa);
 RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa);
 int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa);
 #  endif
 #  ifndef OPENSSL_NO_DSA
 DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa);
 int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa);
 DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa);
 int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa);
 #  endif
 #  ifndef OPENSSL_NO_EC
 EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey);
 int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey);
 EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey);
 int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey);
 #  endif
 X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8);
 int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8);
 PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,
                                                  PKCS8_PRIV_KEY_INFO **p8inf);
 int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf);
 int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key);
 int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a);
 int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey);
 EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a);
 # endif
 
 X509 *X509_dup(X509 *x509);
 X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa);
 X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex);
 X509_CRL *X509_CRL_dup(X509_CRL *crl);
 X509_REQ *X509_REQ_dup(X509_REQ *req);
 X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn);
 int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype,
                     void *pval);
 void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
                      X509_ALGOR *algor);
 void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
 int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
 
 X509_NAME *X509_NAME_dup(X509_NAME *xn);
 X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
 
 int X509_cmp_time(const ASN1_TIME *s, time_t *t);
 int X509_cmp_current_time(const ASN1_TIME *s);
 ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t);
 ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                             int offset_day, long offset_sec, time_t *t);
 ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
 
 const char *X509_get_default_cert_area(void);
 const char *X509_get_default_cert_dir(void);
 const char *X509_get_default_cert_file(void);
 const char *X509_get_default_cert_dir_env(void);
 const char *X509_get_default_cert_file_env(void);
 const char *X509_get_default_private_dir(void);
 
 X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md);
 X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey);
 
 DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
 DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS)
 DECLARE_ASN1_FUNCTIONS(X509_VAL)
 
 DECLARE_ASN1_FUNCTIONS(X509_PUBKEY)
 
 int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey);
 EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key);
 int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain);
 int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp);
 EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length);
 # ifndef OPENSSL_NO_RSA
 int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp);
 RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length);
 # endif
 # ifndef OPENSSL_NO_DSA
 int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp);
 DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length);
 # endif
 # ifndef OPENSSL_NO_EC
 int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp);
 EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length);
 # endif
 
 DECLARE_ASN1_FUNCTIONS(X509_SIG)
 DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO)
 DECLARE_ASN1_FUNCTIONS(X509_REQ)
 
 DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE)
 X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value);
 
 DECLARE_ASN1_FUNCTIONS(X509_EXTENSION)
 DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS)
 
 DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY)
 
 DECLARE_ASN1_FUNCTIONS(X509_NAME)
 
 int X509_NAME_set(X509_NAME **xn, X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(X509_CINF)
 
 DECLARE_ASN1_FUNCTIONS(X509)
 DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX)
 
 DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
 
 int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                           CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
 int X509_set_ex_data(X509 *r, int idx, void *arg);
 void *X509_get_ex_data(X509 *r, int idx);
 int i2d_X509_AUX(X509 *a, unsigned char **pp);
 X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
 
 int X509_alias_set1(X509 *x, unsigned char *name, int len);
 int X509_keyid_set1(X509 *x, unsigned char *id, int len);
 unsigned char *X509_alias_get0(X509 *x, int *len);
 unsigned char *X509_keyid_get0(X509 *x, int *len);
 int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *,
                                                                 int);
 int X509_TRUST_set(int *t, int trust);
 int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj);
 int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj);
 void X509_trust_clear(X509 *x);
 void X509_reject_clear(X509 *x);
 
 DECLARE_ASN1_FUNCTIONS(X509_REVOKED)
 DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO)
 DECLARE_ASN1_FUNCTIONS(X509_CRL)
 
 int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev);
 int X509_CRL_get0_by_serial(X509_CRL *crl,
                             X509_REVOKED **ret, ASN1_INTEGER *serial);
 int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x);
 
 X509_PKEY *X509_PKEY_new(void);
 void X509_PKEY_free(X509_PKEY *a);
 int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp);
 X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp,
                          long length);
 
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI)
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC)
 DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
 
 # ifndef OPENSSL_NO_EVP
 X509_INFO *X509_INFO_new(void);
 void X509_INFO_free(X509_INFO *a);
 char *X509_NAME_oneline(X509_NAME *a, char *buf, int size);
 
 int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1,
                 ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey);
 
 int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
                 unsigned char *md, unsigned int *len);
 
 int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1,
               X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
               char *data, EVP_PKEY *pkey, const EVP_MD *type);
 
 int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data,
                      unsigned char *md, unsigned int *len);
 
 int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
                      ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey);
 
 int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
                    X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data,
                    EVP_PKEY *pkey, const EVP_MD *type);
 int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1,
                        X509_ALGOR *algor2, ASN1_BIT_STRING *signature,
                        void *asn, EVP_MD_CTX *ctx);
 # endif
 
 int X509_set_version(X509 *x, long version);
 int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial);
 ASN1_INTEGER *X509_get_serialNumber(X509 *x);
 int X509_set_issuer_name(X509 *x, X509_NAME *name);
 X509_NAME *X509_get_issuer_name(X509 *a);
 int X509_set_subject_name(X509 *x, X509_NAME *name);
 X509_NAME *X509_get_subject_name(X509 *a);
 int X509_set_notBefore(X509 *x, const ASN1_TIME *tm);
 int X509_set_notAfter(X509 *x, const ASN1_TIME *tm);
 int X509_set_pubkey(X509 *x, EVP_PKEY *pkey);
 EVP_PKEY *X509_get_pubkey(X509 *x);
 ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x);
 int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ );
 
 int X509_REQ_set_version(X509_REQ *x, long version);
 int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
 int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
 EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req);
 int X509_REQ_extension_nid(int nid);
 int *X509_REQ_get_extension_nids(void);
 void X509_REQ_set_extension_nids(int *nids);
 STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req);
 int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts,
                                 int nid);
 int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts);
 int X509_REQ_get_attr_count(const X509_REQ *req);
 int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos);
 int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj,
                              int lastpos);
 X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc);
 X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc);
 int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr);
 int X509_REQ_add1_attr_by_OBJ(X509_REQ *req,
                               const ASN1_OBJECT *obj, int type,
                               const unsigned char *bytes, int len);
 int X509_REQ_add1_attr_by_NID(X509_REQ *req,
                               int nid, int type,
                               const unsigned char *bytes, int len);
 int X509_REQ_add1_attr_by_txt(X509_REQ *req,
                               const char *attrname, int type,
                               const unsigned char *bytes, int len);
 
 int X509_CRL_set_version(X509_CRL *x, long version);
 int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
 int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
 int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
 int X509_CRL_sort(X509_CRL *crl);
 
 int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
 int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
 
 int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey);
 
 int X509_check_private_key(X509 *x509, EVP_PKEY *pkey);
 
 int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
 unsigned long X509_issuer_and_serial_hash(X509 *a);
 
 int X509_issuer_name_cmp(const X509 *a, const X509 *b);
 unsigned long X509_issuer_name_hash(X509 *a);
 
 int X509_subject_name_cmp(const X509 *a, const X509 *b);
 unsigned long X509_subject_name_hash(X509 *x);
 
 # ifndef OPENSSL_NO_MD5
 unsigned long X509_issuer_name_hash_old(X509 *a);
 unsigned long X509_subject_name_hash_old(X509 *x);
 # endif
 
 int X509_cmp(const X509 *a, const X509 *b);
 int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b);
 unsigned long X509_NAME_hash(X509_NAME *x);
 unsigned long X509_NAME_hash_old(X509_NAME *x);
 
 int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b);
 int X509_CRL_match(const X509_CRL *a, const X509_CRL *b);
 # ifndef OPENSSL_NO_FP_API
 int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag,
                      unsigned long cflag);
 int X509_print_fp(FILE *bp, X509 *x);
 int X509_CRL_print_fp(FILE *bp, X509_CRL *x);
 int X509_REQ_print_fp(FILE *bp, X509_REQ *req);
 int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent,
                           unsigned long flags);
 # endif
 
 # ifndef OPENSSL_NO_BIO
 int X509_NAME_print(BIO *bp, X509_NAME *name, int obase);
 int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent,
                        unsigned long flags);
 int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag,
                   unsigned long cflag);
 int X509_print(BIO *bp, X509 *x);
 int X509_ocspid_print(BIO *bp, X509 *x);
 int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent);
 int X509_CRL_print(BIO *bp, X509_CRL *x);
 int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag,
                       unsigned long cflag);
 int X509_REQ_print(BIO *bp, X509_REQ *req);
 # endif
 
 int X509_NAME_entry_count(X509_NAME *name);
 int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len);
 int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
                               char *buf, int len);
 
 /*
  * NOTE: you should be passsing -1, not 0 as lastpos.  The functions that use
  * lastpos, search after that position on.
  */
 int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos);
 int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj,
                                int lastpos);
 X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc);
 X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc);
 int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne,
                         int loc, int set);
 int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type,
                                unsigned char *bytes, int len, int loc,
                                int set);
 int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type,
                                unsigned char *bytes, int len, int loc,
                                int set);
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
                                                const char *field, int type,
                                                const unsigned char *bytes,
                                                int len);
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
                                                int type, unsigned char *bytes,
                                                int len);
 int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type,
                                const unsigned char *bytes, int len, int loc,
                                int set);
 X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne,
                                                ASN1_OBJECT *obj, int type,
                                                const unsigned char *bytes,
                                                int len);
 int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj);
 int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type,
                              const unsigned char *bytes, int len);
 ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne);
 ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne);
 
 int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x);
 int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x,
                           int nid, int lastpos);
 int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x,
                           ASN1_OBJECT *obj, int lastpos);
 int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x,
                                int crit, int lastpos);
 X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc);
 X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc);
 STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
                                          X509_EXTENSION *ex, int loc);
 
 int X509_get_ext_count(X509 *x);
 int X509_get_ext_by_NID(X509 *x, int nid, int lastpos);
 int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos);
 int X509_get_ext_by_critical(X509 *x, int crit, int lastpos);
 X509_EXTENSION *X509_get_ext(X509 *x, int loc);
 X509_EXTENSION *X509_delete_ext(X509 *x, int loc);
 int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc);
 void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx);
 int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit,
                       unsigned long flags);
 
 int X509_CRL_get_ext_count(X509_CRL *x);
 int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos);
 int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos);
 int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos);
 X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc);
 X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc);
 int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc);
 void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx);
 int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit,
                           unsigned long flags);
 
 int X509_REVOKED_get_ext_count(X509_REVOKED *x);
 int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos);
 int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj,
                                 int lastpos);
 int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos);
 X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc);
 X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc);
 int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc);
 void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx);
 int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit,
                               unsigned long flags);
 
 X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex,
                                              int nid, int crit,
                                              ASN1_OCTET_STRING *data);
 X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
                                              ASN1_OBJECT *obj, int crit,
                                              ASN1_OCTET_STRING *data);
 int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj);
 int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit);
 int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data);
 ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex);
 ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne);
 int X509_EXTENSION_get_critical(X509_EXTENSION *ex);
 
 int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x);
 int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid,
                            int lastpos);
 int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk,
                            ASN1_OBJECT *obj, int lastpos);
 X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc);
 X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc);
 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
                                            X509_ATTRIBUTE *attr);
 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE)
                                                   **x, const ASN1_OBJECT *obj,
                                                   int type,
                                                   const unsigned char *bytes,
                                                   int len);
 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE)
                                                   **x, int nid, int type,
                                                   const unsigned char *bytes,
                                                   int len);
 STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
                                                   **x, const char *attrname,
                                                   int type,
                                                   const unsigned char *bytes,
                                                   int len);
 void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj,
                               int lastpos, int type);
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
                                              int atrtype, const void *data,
                                              int len);
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
                                              const ASN1_OBJECT *obj,
                                              int atrtype, const void *data,
                                              int len);
 X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
                                              const char *atrname, int type,
                                              const unsigned char *bytes,
                                              int len);
 int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj);
 int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
                              const void *data, int len);
 void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype,
                                void *data);
 int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr);
 ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr);
 ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx);
 
 int EVP_PKEY_get_attr_count(const EVP_PKEY *key);
 int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos);
 int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj,
                              int lastpos);
 X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc);
 X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc);
 int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr);
 int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key,
                               const ASN1_OBJECT *obj, int type,
                               const unsigned char *bytes, int len);
 int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key,
                               int nid, int type,
                               const unsigned char *bytes, int len);
 int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key,
                               const char *attrname, int type,
                               const unsigned char *bytes, int len);
 
 int X509_verify_cert(X509_STORE_CTX *ctx);
 
 /* lookup a cert from a X509 STACK */
 X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name,
                                      ASN1_INTEGER *serial);
 X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name);
 
 DECLARE_ASN1_FUNCTIONS(PBEPARAM)
 DECLARE_ASN1_FUNCTIONS(PBE2PARAM)
 DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM)
 
 int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
                          const unsigned char *salt, int saltlen);
 
 X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
                           const unsigned char *salt, int saltlen);
 X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
                            unsigned char *salt, int saltlen);
 X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
                               unsigned char *salt, int saltlen,
                               unsigned char *aiv, int prf_nid);
 
 X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
                              int prf_nid, int keylen);
 
 /* PKCS#8 utilities */
 
 DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
 
 EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8);
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey);
 PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken);
 PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken);
 
 int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
                     int version, int ptype, void *pval,
                     unsigned char *penc, int penclen);
 int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
                     const unsigned char **pk, int *ppklen,
                     X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8);
 
 int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
                            int ptype, void *pval,
                            unsigned char *penc, int penclen);
 int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
                            const unsigned char **pk, int *ppklen,
                            X509_ALGOR **pa, X509_PUBKEY *pub);
 
 int X509_check_trust(X509 *x, int id, int flags);
 int X509_TRUST_get_count(void);
 X509_TRUST *X509_TRUST_get0(int idx);
 int X509_TRUST_get_by_id(int id);
 int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int),
                    char *name, int arg1, void *arg2);
 void X509_TRUST_cleanup(void);
 int X509_TRUST_get_flags(X509_TRUST *xp);
 char *X509_TRUST_get0_name(X509_TRUST *xp);
 int X509_TRUST_get_trust(X509_TRUST *xp);
 
 /* 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_X509_strings(void);
 
 /* Error codes for the X509 functions. */
 
 /* Function codes. */
 # define X509_F_ADD_CERT_DIR                              100
 # define X509_F_BY_FILE_CTRL                              101
+# define X509_F_CHECK_NAME_CONSTRAINTS                    106
 # define X509_F_CHECK_POLICY                              145
 # define X509_F_DIR_CTRL                                  102
 # define X509_F_GET_CERT_BY_SUBJECT                       103
 # define X509_F_NETSCAPE_SPKI_B64_DECODE                  129
 # define X509_F_NETSCAPE_SPKI_B64_ENCODE                  130
 # define X509_F_X509AT_ADD1_ATTR                          135
 # define X509_F_X509V3_ADD_EXT                            104
 # define X509_F_X509_ATTRIBUTE_CREATE_BY_NID              136
 # define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ              137
 # define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT              140
 # define X509_F_X509_ATTRIBUTE_GET0_DATA                  139
 # define X509_F_X509_ATTRIBUTE_SET1_DATA                  138
 # define X509_F_X509_CHECK_PRIVATE_KEY                    128
 # define X509_F_X509_CRL_PRINT_FP                         147
 # define X509_F_X509_EXTENSION_CREATE_BY_NID              108
 # define X509_F_X509_EXTENSION_CREATE_BY_OBJ              109
 # define X509_F_X509_GET_PUBKEY_PARAMETERS                110
 # define X509_F_X509_LOAD_CERT_CRL_FILE                   132
 # define X509_F_X509_LOAD_CERT_FILE                       111
 # define X509_F_X509_LOAD_CRL_FILE                        112
 # define X509_F_X509_NAME_ADD_ENTRY                       113
 # define X509_F_X509_NAME_ENTRY_CREATE_BY_NID             114
 # define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT             131
 # define X509_F_X509_NAME_ENTRY_SET_OBJECT                115
 # define X509_F_X509_NAME_ONELINE                         116
 # define X509_F_X509_NAME_PRINT                           117
 # define X509_F_X509_PRINT_EX_FP                          118
 # define X509_F_X509_PUBKEY_GET                           119
 # define X509_F_X509_PUBKEY_SET                           120
 # define X509_F_X509_REQ_CHECK_PRIVATE_KEY                144
 # define X509_F_X509_REQ_PRINT_EX                         121
 # define X509_F_X509_REQ_PRINT_FP                         122
 # define X509_F_X509_REQ_TO_X509                          123
 # define X509_F_X509_STORE_ADD_CERT                       124
 # define X509_F_X509_STORE_ADD_CRL                        125
 # define X509_F_X509_STORE_CTX_GET1_ISSUER                146
 # define X509_F_X509_STORE_CTX_INIT                       143
 # define X509_F_X509_STORE_CTX_NEW                        142
 # define X509_F_X509_STORE_CTX_PURPOSE_INHERIT            134
 # define X509_F_X509_TO_X509_REQ                          126
 # define X509_F_X509_TRUST_ADD                            133
 # define X509_F_X509_TRUST_SET                            141
 # define X509_F_X509_VERIFY_CERT                          127
 
 /* Reason codes. */
 # define X509_R_BAD_X509_FILETYPE                         100
 # define X509_R_BASE64_DECODE_ERROR                       118
 # define X509_R_CANT_CHECK_DH_KEY                         114
 # define X509_R_CERT_ALREADY_IN_HASH_TABLE                101
 # define X509_R_ERR_ASN1_LIB                              102
 # define X509_R_INVALID_DIRECTORY                         113
 # define X509_R_INVALID_FIELD_NAME                        119
 # define X509_R_INVALID_TRUST                             123
 # define X509_R_KEY_TYPE_MISMATCH                         115
 # define X509_R_KEY_VALUES_MISMATCH                       116
 # define X509_R_LOADING_CERT_DIR                          103
 # define X509_R_LOADING_DEFAULTS                          104
 # define X509_R_METHOD_NOT_SUPPORTED                      124
 # define X509_R_NAME_TOO_LONG                             134
 # define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY              105
 # define X509_R_PUBLIC_KEY_DECODE_ERROR                   125
 # define X509_R_PUBLIC_KEY_ENCODE_ERROR                   126
 # define X509_R_SHOULD_RETRY                              106
 # define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN        107
 # define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY            108
 # define X509_R_UNKNOWN_KEY_TYPE                          117
 # define X509_R_UNKNOWN_NID                               109
 # define X509_R_UNKNOWN_PURPOSE_ID                        121
 # define X509_R_UNKNOWN_TRUST_ID                          120
 # define X509_R_UNSUPPORTED_ALGORITHM                     111
 # define X509_R_WRONG_LOOKUP_TYPE                         112
 # define X509_R_WRONG_TYPE                                122
 
-#ifdef  __cplusplus
+# ifdef  __cplusplus
 }
-#endif
+# endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_err.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_err.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_err.c	(revision 306191)
@@ -1,179 +1,180 @@
 /* crypto/x509/x509_err.c */
 /* ====================================================================
  * Copyright (c) 1999-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
  *    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 <openssl/x509.h>
 
 /* BEGIN ERROR CODES */
 #ifndef OPENSSL_NO_ERR
 
 # define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0)
 # define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason)
 
 static ERR_STRING_DATA X509_str_functs[] = {
     {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"},
     {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"},
+    {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"},
     {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"},
     {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"},
     {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"},
     {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"},
     {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"},
     {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"},
     {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"},
     {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID),
      "X509_ATTRIBUTE_create_by_NID"},
     {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ),
      "X509_ATTRIBUTE_create_by_OBJ"},
     {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT),
      "X509_ATTRIBUTE_create_by_txt"},
     {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"},
     {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"},
     {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"},
     {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"},
     {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID),
      "X509_EXTENSION_create_by_NID"},
     {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ),
      "X509_EXTENSION_create_by_OBJ"},
     {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS),
      "X509_get_pubkey_parameters"},
     {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"},
     {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"},
     {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"},
     {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"},
     {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID),
      "X509_NAME_ENTRY_create_by_NID"},
     {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT),
      "X509_NAME_ENTRY_create_by_txt"},
     {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT),
      "X509_NAME_ENTRY_set_object"},
     {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"},
     {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"},
     {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"},
     {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"},
     {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"},
     {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY),
      "X509_REQ_check_private_key"},
     {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"},
     {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"},
     {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"},
     {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"},
     {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"},
     {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER),
      "X509_STORE_CTX_get1_issuer"},
     {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"},
     {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"},
     {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT),
      "X509_STORE_CTX_purpose_inherit"},
     {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"},
     {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"},
     {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"},
     {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"},
     {0, NULL}
 };
 
 static ERR_STRING_DATA X509_str_reasons[] = {
     {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"},
     {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"},
     {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"},
     {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE),
      "cert already in hash table"},
     {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"},
     {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"},
     {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"},
     {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"},
     {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"},
     {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"},
     {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"},
     {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"},
     {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"},
     {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"},
     {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY),
      "no cert set for us to verify"},
     {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"},
     {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"},
     {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"},
     {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN),
      "unable to find parameters in chain"},
     {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY),
      "unable to get certs public key"},
     {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"},
     {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"},
     {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"},
     {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"},
     {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"},
     {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"},
     {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"},
     {0, NULL}
 };
 
 #endif
 
 void ERR_load_X509_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
 
     if (ERR_func_error_string(X509_str_functs[0].error) == NULL) {
         ERR_load_strings(0, X509_str_functs);
         ERR_load_strings(0, X509_str_reasons);
     }
 #endif
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_txt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_txt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_txt.c	(revision 306191)
@@ -1,191 +1,197 @@
 /* crypto/x509/x509_txt.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.]
  */
 
 #include <stdio.h>
 #include <time.h>
 #include <errno.h>
 
 #include "cryptlib.h"
 #include <openssl/lhash.h>
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
 #include <openssl/asn1.h>
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 
 const char *X509_verify_cert_error_string(long n)
 {
     static char buf[100];
 
     switch ((int)n) {
     case X509_V_OK:
         return ("ok");
     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
         return ("unable to get issuer certificate");
     case X509_V_ERR_UNABLE_TO_GET_CRL:
         return ("unable to get certificate CRL");
     case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
         return ("unable to decrypt certificate's signature");
     case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
         return ("unable to decrypt CRL's signature");
     case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
         return ("unable to decode issuer public key");
     case X509_V_ERR_CERT_SIGNATURE_FAILURE:
         return ("certificate signature failure");
     case X509_V_ERR_CRL_SIGNATURE_FAILURE:
         return ("CRL signature failure");
     case X509_V_ERR_CERT_NOT_YET_VALID:
         return ("certificate is not yet valid");
     case X509_V_ERR_CRL_NOT_YET_VALID:
         return ("CRL is not yet valid");
     case X509_V_ERR_CERT_HAS_EXPIRED:
         return ("certificate has expired");
     case X509_V_ERR_CRL_HAS_EXPIRED:
         return ("CRL has expired");
     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
         return ("format error in certificate's notBefore field");
     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
         return ("format error in certificate's notAfter field");
     case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
         return ("format error in CRL's lastUpdate field");
     case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
         return ("format error in CRL's nextUpdate field");
     case X509_V_ERR_OUT_OF_MEM:
         return ("out of memory");
     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
         return ("self signed certificate");
     case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
         return ("self signed certificate in certificate chain");
     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
         return ("unable to get local issuer certificate");
     case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
         return ("unable to verify the first certificate");
     case X509_V_ERR_CERT_CHAIN_TOO_LONG:
         return ("certificate chain too long");
     case X509_V_ERR_CERT_REVOKED:
         return ("certificate revoked");
     case X509_V_ERR_INVALID_CA:
         return ("invalid CA certificate");
     case X509_V_ERR_INVALID_NON_CA:
         return ("invalid non-CA certificate (has CA markings)");
     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
         return ("path length constraint exceeded");
     case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED:
         return ("proxy path length constraint exceeded");
     case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED:
         return
             ("proxy certificates not allowed, please set the appropriate flag");
     case X509_V_ERR_INVALID_PURPOSE:
         return ("unsupported certificate purpose");
     case X509_V_ERR_CERT_UNTRUSTED:
         return ("certificate not trusted");
     case X509_V_ERR_CERT_REJECTED:
         return ("certificate rejected");
     case X509_V_ERR_APPLICATION_VERIFICATION:
         return ("application verification failure");
     case X509_V_ERR_SUBJECT_ISSUER_MISMATCH:
         return ("subject issuer mismatch");
     case X509_V_ERR_AKID_SKID_MISMATCH:
         return ("authority and subject key identifier mismatch");
     case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH:
         return ("authority and issuer serial number mismatch");
     case X509_V_ERR_KEYUSAGE_NO_CERTSIGN:
         return ("key usage does not include certificate signing");
     case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
         return ("unable to get CRL issuer certificate");
     case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
         return ("unhandled critical extension");
     case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN:
         return ("key usage does not include CRL signing");
     case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE:
         return ("key usage does not include digital signature");
     case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION:
         return ("unhandled critical CRL extension");
     case X509_V_ERR_INVALID_EXTENSION:
         return ("invalid or inconsistent certificate extension");
     case X509_V_ERR_INVALID_POLICY_EXTENSION:
         return ("invalid or inconsistent certificate policy extension");
     case X509_V_ERR_NO_EXPLICIT_POLICY:
         return ("no explicit policy");
     case X509_V_ERR_DIFFERENT_CRL_SCOPE:
         return ("Different CRL scope");
     case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE:
         return ("Unsupported extension feature");
     case X509_V_ERR_UNNESTED_RESOURCE:
         return ("RFC 3779 resource not subset of parent's resources");
 
     case X509_V_ERR_PERMITTED_VIOLATION:
         return ("permitted subtree violation");
     case X509_V_ERR_EXCLUDED_VIOLATION:
         return ("excluded subtree violation");
     case X509_V_ERR_SUBTREE_MINMAX:
         return ("name constraints minimum and maximum not supported");
     case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE:
         return ("unsupported name constraint type");
     case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX:
         return ("unsupported or invalid name constraint syntax");
     case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX:
         return ("unsupported or invalid name syntax");
     case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
         return ("CRL path validation error");
+    case X509_V_ERR_INVALID_CALL:
+        return ("Invalid certificate verification context");
+    case X509_V_ERR_STORE_LOOKUP:
+        return ("Issuer certificate lookup error");
+    case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
+        return ("proxy subject name violation");
 
     default:
         BIO_snprintf(buf, sizeof buf, "error number %ld", n);
         return (buf);
     }
 }
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.c	(revision 306191)
@@ -1,2230 +1,2350 @@
 /* crypto/x509/x509_vfy.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.]
  */
 
 #include <stdio.h>
 #include <time.h>
 #include <errno.h>
 
 #include "cryptlib.h"
 #include <openssl/crypto.h>
 #include <openssl/lhash.h>
 #include <openssl/buffer.h>
 #include <openssl/evp.h>
 #include <openssl/asn1.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/objects.h>
 
 /* CRL score values */
 
 /* No unhandled critical extensions */
 
 #define CRL_SCORE_NOCRITICAL    0x100
 
 /* certificate is within CRL scope */
 
 #define CRL_SCORE_SCOPE         0x080
 
 /* CRL times valid */
 
 #define CRL_SCORE_TIME          0x040
 
 /* Issuer name matches certificate */
 
 #define CRL_SCORE_ISSUER_NAME   0x020
 
 /* If this score or above CRL is probably valid */
 
 #define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE)
 
 /* CRL issuer is certificate issuer */
 
 #define CRL_SCORE_ISSUER_CERT   0x018
 
 /* CRL issuer is on certificate path */
 
 #define CRL_SCORE_SAME_PATH     0x008
 
 /* CRL issuer matches CRL AKID */
 
 #define CRL_SCORE_AKID          0x004
 
 /* Have a delta CRL with valid times */
 
 #define CRL_SCORE_TIME_DELTA    0x002
 
 static int null_callback(int ok, X509_STORE_CTX *e);
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
 static int check_chain_extensions(X509_STORE_CTX *ctx);
 static int check_name_constraints(X509_STORE_CTX *ctx);
 static int check_trust(X509_STORE_CTX *ctx);
 static int check_revocation(X509_STORE_CTX *ctx);
 static int check_cert(X509_STORE_CTX *ctx);
 static int check_policy(X509_STORE_CTX *ctx);
 
 static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
                          unsigned int *preasons, X509_CRL *crl, X509 *x);
 static int get_crl_delta(X509_STORE_CTX *ctx,
                          X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x);
 static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl,
                          int *pcrl_score, X509_CRL *base,
                          STACK_OF(X509_CRL) *crls);
 static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer,
                            int *pcrl_score);
 static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
                            unsigned int *preasons);
 static int check_crl_path(X509_STORE_CTX *ctx, X509 *x);
 static int check_crl_chain(X509_STORE_CTX *ctx,
                            STACK_OF(X509) *cert_path,
                            STACK_OF(X509) *crl_path);
 
 static int internal_verify(X509_STORE_CTX *ctx);
 const char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT;
 
 static int null_callback(int ok, X509_STORE_CTX *e)
 {
     return ok;
 }
 
 #if 0
 static int x509_subject_cmp(X509 **a, X509 **b)
 {
     return X509_subject_name_cmp(*a, *b);
 }
 #endif
 
 int X509_verify_cert(X509_STORE_CTX *ctx)
 {
     X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
     int bad_chain = 0;
     X509_VERIFY_PARAM *param = ctx->param;
     int depth, i, ok = 0;
     int num, j, retry;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
     STACK_OF(X509) *sktmp = NULL;
     if (ctx->cert == NULL) {
         X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+        ctx->error = X509_V_ERR_INVALID_CALL;
         return -1;
     }
     if (ctx->chain != NULL) {
         /*
          * This X509_STORE_CTX has already been used to verify a cert. We
          * cannot do another one.
          */
         X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+        ctx->error = X509_V_ERR_INVALID_CALL;
         return -1;
     }
 
     cb = ctx->verify_cb;
 
     /*
      * first we make sure the chain we are going to build is present and that
      * the first entry is in place
      */
     if (((ctx->chain = sk_X509_new_null()) == NULL) ||
         (!sk_X509_push(ctx->chain, ctx->cert))) {
         X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        ok = -1;
         goto end;
     }
     CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509);
     ctx->last_untrusted = 1;
 
     /* We use a temporary STACK so we can chop and hack at it */
     if (ctx->untrusted != NULL
         && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
         X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
+        ok = -1;
         goto end;
     }
 
     num = sk_X509_num(ctx->chain);
     x = sk_X509_value(ctx->chain, num - 1);
     depth = param->depth;
 
     for (;;) {
         /* If we have enough, we break */
         if (depth < num)
             break;              /* FIXME: If this happens, we should take
                                  * note of it and, if appropriate, use the
                                  * X509_V_ERR_CERT_CHAIN_TOO_LONG error code
                                  * later. */
 
         /* If we are self signed, we break */
         if (ctx->check_issued(ctx, x, x))
             break;
 
         /* If we were passed a cert chain, use it first */
         if (ctx->untrusted != NULL) {
             xtmp = find_issuer(ctx, sktmp, x);
             if (xtmp != NULL) {
                 if (!sk_X509_push(ctx->chain, xtmp)) {
                     X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+                    ctx->error = X509_V_ERR_OUT_OF_MEM;
+                    ok = -1;
                     goto end;
                 }
                 CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509);
                 (void)sk_X509_delete_ptr(sktmp, xtmp);
                 ctx->last_untrusted++;
                 x = xtmp;
                 num++;
                 /*
                  * reparse the full chain for the next one
                  */
                 continue;
             }
         }
         break;
     }
 
     /* Remember how many untrusted certs we have */
     j = num;
     /*
      * at this point, chain should contain a list of untrusted certificates.
      * We now need to add at least one trusted one, if possible, otherwise we
      * complain.
      */
 
     do {
         /*
          * Examine last certificate in chain and see if it is self signed.
          */
         i = sk_X509_num(ctx->chain);
         x = sk_X509_value(ctx->chain, i - 1);
         if (ctx->check_issued(ctx, x, x)) {
             /* we have a self signed certificate */
             if (sk_X509_num(ctx->chain) == 1) {
                 /*
                  * We have a single self signed certificate: see if we can
                  * find it in the store. We must have an exact match to avoid
                  * possible impersonation.
                  */
                 ok = ctx->get_issuer(&xtmp, ctx, x);
                 if ((ok <= 0) || X509_cmp(x, xtmp)) {
                     ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
                     ctx->current_cert = x;
                     ctx->error_depth = i - 1;
                     if (ok == 1)
                         X509_free(xtmp);
                     bad_chain = 1;
                     ok = cb(0, ctx);
                     if (!ok)
                         goto end;
                 } else {
                     /*
                      * We have a match: replace certificate with store
                      * version so we get any trust settings.
                      */
                     X509_free(x);
                     x = xtmp;
                     (void)sk_X509_set(ctx->chain, i - 1, x);
                     ctx->last_untrusted = 0;
                 }
             } else {
                 /*
                  * extract and save self signed certificate for later use
                  */
                 chain_ss = sk_X509_pop(ctx->chain);
                 ctx->last_untrusted--;
                 num--;
                 j--;
                 x = sk_X509_value(ctx->chain, num - 1);
             }
         }
         /* We now lookup certs from the certificate store */
         for (;;) {
             /* If we have enough, we break */
             if (depth < num)
                 break;
             /* If we are self signed, we break */
             if (ctx->check_issued(ctx, x, x))
                 break;
             ok = ctx->get_issuer(&xtmp, ctx, x);
-            if (ok < 0)
-                return ok;
+            if (ok < 0) {
+                ctx->error = X509_V_ERR_STORE_LOOKUP;
+                goto end;
+            }
             if (ok == 0)
                 break;
             x = xtmp;
             if (!sk_X509_push(ctx->chain, x)) {
                 X509_free(xtmp);
                 X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
-                return 0;
+                ctx->error = X509_V_ERR_OUT_OF_MEM;
+                ok = -1;
+                goto end;
             }
             num++;
         }
 
         /*
          * If we haven't got a least one certificate from our store then check
          * if there is an alternative chain that could be used.  We only do this
          * if the user hasn't switched off alternate chain checking
          */
         retry = 0;
         if (num == ctx->last_untrusted &&
             !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) {
             while (j-- > 1) {
                 xtmp2 = sk_X509_value(ctx->chain, j - 1);
                 ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
-                if (ok < 0)
+                if (ok < 0) {
+                    ctx->error = X509_V_ERR_STORE_LOOKUP;
                     goto end;
+                }
                 /* Check if we found an alternate chain */
                 if (ok > 0) {
                     /*
                      * Free up the found cert we'll add it again later
                      */
                     X509_free(xtmp);
 
                     /*
                      * Dump all the certs above this point - we've found an
                      * alternate chain
                      */
                     while (num > j) {
                         xtmp = sk_X509_pop(ctx->chain);
                         X509_free(xtmp);
                         num--;
                     }
                     ctx->last_untrusted = sk_X509_num(ctx->chain);
                     retry = 1;
                     break;
                 }
             }
         }
     } while (retry);
 
     /* Is last certificate looked up self signed? */
     if (!ctx->check_issued(ctx, x, x)) {
         if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) {
             if (ctx->last_untrusted >= num)
                 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
             else
                 ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
             ctx->current_cert = x;
         } else {
 
             sk_X509_push(ctx->chain, chain_ss);
             num++;
             ctx->last_untrusted = num;
             ctx->current_cert = chain_ss;
             ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
             chain_ss = NULL;
         }
 
         ctx->error_depth = num - 1;
         bad_chain = 1;
         ok = cb(0, ctx);
         if (!ok)
             goto end;
     }
 
     /* We have the chain complete: now we need to check its purpose */
     ok = check_chain_extensions(ctx);
 
     if (!ok)
         goto end;
 
     /* Check name constraints */
 
     ok = check_name_constraints(ctx);
 
     if (!ok)
         goto end;
 
     /* The chain extensions are OK: check trust */
 
     if (param->trust > 0)
         ok = check_trust(ctx);
 
     if (!ok)
         goto end;
 
     /* We may as well copy down any DSA parameters that are required */
     X509_get_pubkey_parameters(NULL, ctx->chain);
 
     /*
      * Check revocation status: we do this after copying parameters because
      * they may be needed for CRL signature verification.
      */
 
     ok = ctx->check_revocation(ctx);
     if (!ok)
         goto end;
 
     /* At this point, we have a chain and need to verify it */
     if (ctx->verify != NULL)
         ok = ctx->verify(ctx);
     else
         ok = internal_verify(ctx);
     if (!ok)
         goto end;
 
 #ifndef OPENSSL_NO_RFC3779
     /* RFC 3779 path validation, now that CRL check has been done */
     ok = v3_asid_validate_path(ctx);
     if (!ok)
         goto end;
     ok = v3_addr_validate_path(ctx);
     if (!ok)
         goto end;
 #endif
 
     /* If we get this far evaluate policies */
     if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
         ok = ctx->check_policy(ctx);
     if (!ok)
         goto end;
     if (0) {
  end:
         X509_get_pubkey_parameters(NULL, ctx->chain);
     }
     if (sktmp != NULL)
         sk_X509_free(sktmp);
     if (chain_ss != NULL)
         X509_free(chain_ss);
+
+    /* Safety net, error returns must set ctx->error */
+    if (ok <= 0 && ctx->error == X509_V_OK)
+        ctx->error = X509_V_ERR_UNSPECIFIED;
     return ok;
 }
 
 /*
  * Given a STACK_OF(X509) find the issuer of cert (if any)
  */
 
 static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x)
 {
     int i;
     X509 *issuer;
     for (i = 0; i < sk_X509_num(sk); i++) {
         issuer = sk_X509_value(sk, i);
         if (ctx->check_issued(ctx, x, issuer))
             return issuer;
     }
     return NULL;
 }
 
 /* Given a possible certificate and issuer check them */
 
 static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer)
 {
     int ret;
     ret = X509_check_issued(issuer, x);
     if (ret == X509_V_OK)
         return 1;
     /* If we haven't asked for issuer errors don't set ctx */
     if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK))
         return 0;
 
     ctx->error = ret;
     ctx->current_cert = x;
     ctx->current_issuer = issuer;
     return ctx->verify_cb(0, ctx);
     return 0;
 }
 
 /* Alternative lookup method: look from a STACK stored in other_ctx */
 
 static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
 {
     *issuer = find_issuer(ctx, ctx->other_ctx, x);
     if (*issuer) {
         CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
         return 1;
     } else
         return 0;
 }
 
 /*
  * Check a certificate chains extensions for consistency with the supplied
  * purpose
  */
 
 static int check_chain_extensions(X509_STORE_CTX *ctx)
 {
 #ifdef OPENSSL_NO_CHAIN_VERIFY
     return 1;
 #else
     int i, ok = 0, must_be_ca, plen = 0;
     X509 *x;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
     int proxy_path_length = 0;
     int purpose;
     int allow_proxy_certs;
     cb = ctx->verify_cb;
 
     /*-
      *  must_be_ca can have 1 of 3 values:
      * -1: we accept both CA and non-CA certificates, to allow direct
      *     use of self-signed certificates (which are marked as CA).
      * 0:  we only accept non-CA certificates.  This is currently not
      *     used, but the possibility is present for future extensions.
      * 1:  we only accept CA certificates.  This is currently used for
      *     all certificates in the chain except the leaf certificate.
      */
     must_be_ca = -1;
 
     /* CRL path validation */
     if (ctx->parent) {
         allow_proxy_certs = 0;
         purpose = X509_PURPOSE_CRL_SIGN;
     } else {
         allow_proxy_certs =
             ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
         /*
          * A hack to keep people who don't want to modify their software
          * happy
          */
         if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
             allow_proxy_certs = 1;
         purpose = ctx->param->purpose;
     }
 
     /* Check all untrusted certificates */
     for (i = 0; i < ctx->last_untrusted; i++) {
         int ret;
         x = sk_X509_value(ctx->chain, i);
         if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
             && (x->ex_flags & EXFLAG_CRITICAL)) {
             ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION;
             ctx->error_depth = i;
             ctx->current_cert = x;
             ok = cb(0, ctx);
             if (!ok)
                 goto end;
         }
         if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) {
             ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
             ctx->error_depth = i;
             ctx->current_cert = x;
             ok = cb(0, ctx);
             if (!ok)
                 goto end;
         }
         ret = X509_check_ca(x);
         switch (must_be_ca) {
         case -1:
             if ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
                 && (ret != 1) && (ret != 0)) {
                 ret = 0;
                 ctx->error = X509_V_ERR_INVALID_CA;
             } else
                 ret = 1;
             break;
         case 0:
             if (ret != 0) {
                 ret = 0;
                 ctx->error = X509_V_ERR_INVALID_NON_CA;
             } else
                 ret = 1;
             break;
         default:
             if ((ret == 0)
                 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
                     && (ret != 1))) {
                 ret = 0;
                 ctx->error = X509_V_ERR_INVALID_CA;
             } else
                 ret = 1;
             break;
         }
         if (ret == 0) {
             ctx->error_depth = i;
             ctx->current_cert = x;
             ok = cb(0, ctx);
             if (!ok)
                 goto end;
         }
         if (ctx->param->purpose > 0) {
             ret = X509_check_purpose(x, purpose, must_be_ca > 0);
             if ((ret == 0)
                 || ((ctx->param->flags & X509_V_FLAG_X509_STRICT)
                     && (ret != 1))) {
                 ctx->error = X509_V_ERR_INVALID_PURPOSE;
                 ctx->error_depth = i;
                 ctx->current_cert = x;
                 ok = cb(0, ctx);
                 if (!ok)
                     goto end;
             }
         }
         /* Check pathlen if not self issued */
         if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
             && (x->ex_pathlen != -1)
             && (plen > (x->ex_pathlen + proxy_path_length + 1))) {
             ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
             ctx->error_depth = i;
             ctx->current_cert = x;
             ok = cb(0, ctx);
             if (!ok)
                 goto end;
         }
         /* Increment path length if not self issued */
         if (!(x->ex_flags & EXFLAG_SI))
             plen++;
         /*
          * If this certificate is a proxy certificate, the next certificate
          * must be another proxy certificate or a EE certificate.  If not,
          * the next certificate must be a CA certificate.
          */
         if (x->ex_flags & EXFLAG_PROXY) {
-            if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
-                ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
-                ctx->error_depth = i;
-                ctx->current_cert = x;
-                ok = cb(0, ctx);
-                if (!ok)
-                    goto end;
+            /*
+             * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint
+             * is less than max_path_length, the former should be copied to
+             * the latter, and 4.1.4 (a) stipulates that max_path_length
+             * should be verified to be larger than zero and decrement it.
+             *
+             * Because we're checking the certs in the reverse order, we start
+             * with verifying that proxy_path_length isn't larger than pcPLC,
+             * and copy the latter to the former if it is, and finally,
+             * increment proxy_path_length.
+             */
+            if (x->ex_pcpathlen != -1) {
+                if (proxy_path_length > x->ex_pcpathlen) {
+                    ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+                    ctx->error_depth = i;
+                    ctx->current_cert = x;
+                    ok = cb(0, ctx);
+                    if (!ok)
+                        goto end;
+                }
+                proxy_path_length = x->ex_pcpathlen;
             }
             proxy_path_length++;
             must_be_ca = 0;
         } else
             must_be_ca = 1;
     }
     ok = 1;
  end:
     return ok;
 #endif
 }
 
 static int check_name_constraints(X509_STORE_CTX *ctx)
 {
     X509 *x;
     int i, j, rv;
     /* Check name constraints for all certificates */
     for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) {
         x = sk_X509_value(ctx->chain, i);
         /* Ignore self issued certs unless last in chain */
         if (i && (x->ex_flags & EXFLAG_SI))
             continue;
+
         /*
+         * Proxy certificates policy has an extra constraint, where the
+         * certificate subject MUST be the issuer with a single CN entry
+         * added.
+         * (RFC 3820: 3.4, 4.1.3 (a)(4))
+         */
+        if (x->ex_flags & EXFLAG_PROXY) {
+            X509_NAME *tmpsubject = X509_get_subject_name(x);
+            X509_NAME *tmpissuer = X509_get_issuer_name(x);
+            X509_NAME_ENTRY *tmpentry = NULL;
+            int last_object_nid = 0;
+            int err = X509_V_OK;
+            int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1;
+
+            /* Check that there are at least two RDNs */
+            if (last_object_loc < 1) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that there is exactly one more RDN in subject as
+             * there is in issuer.
+             */
+            if (X509_NAME_entry_count(tmpsubject)
+                != X509_NAME_entry_count(tmpissuer) + 1) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that the last subject component isn't part of a
+             * multivalued RDN
+             */
+            if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set
+                == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+                goto proxy_name_done;
+            }
+
+            /*
+             * Check that the last subject RDN is a commonName, and that
+             * all the previous RDNs match the issuer exactly
+             */
+            tmpsubject = X509_NAME_dup(tmpsubject);
+            if (tmpsubject == NULL) {
+                X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+                ctx->error = X509_V_ERR_OUT_OF_MEM;
+                return 0;
+            }
+
+            tmpentry =
+                X509_NAME_delete_entry(tmpsubject, last_object_loc);
+            last_object_nid =
+                OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry));
+
+            if (last_object_nid != NID_commonName
+                || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) {
+                err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+            }
+
+            X509_NAME_ENTRY_free(tmpentry);
+            X509_NAME_free(tmpsubject);
+
+         proxy_name_done:
+            if (err != X509_V_OK) {
+                ctx->error = err;
+                ctx->error_depth = i;
+                ctx->current_cert = x;
+                if (!ctx->verify_cb(0, ctx))
+                    return 0;
+            }
+        }
+
+        /*
          * Check against constraints for all certificates higher in chain
          * including trust anchor. Trust anchor not strictly speaking needed
          * but if it includes constraints it is to be assumed it expects them
          * to be obeyed.
          */
         for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) {
             NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
             if (nc) {
                 rv = NAME_CONSTRAINTS_check(x, nc);
-                if (rv != X509_V_OK) {
+                switch (rv) {
+                case X509_V_OK:
+                    continue;
+                case X509_V_ERR_OUT_OF_MEM:
                     ctx->error = rv;
+                    return 0;
+                default:
+                    ctx->error = rv;
                     ctx->error_depth = i;
                     ctx->current_cert = x;
                     if (!ctx->verify_cb(0, ctx))
                         return 0;
+                    break;
                 }
             }
         }
     }
     return 1;
 }
 
 static int check_trust(X509_STORE_CTX *ctx)
 {
 #ifdef OPENSSL_NO_CHAIN_VERIFY
     return 1;
 #else
     int i, ok;
     X509 *x;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
     cb = ctx->verify_cb;
 /* For now just check the last certificate in the chain */
     i = sk_X509_num(ctx->chain) - 1;
     x = sk_X509_value(ctx->chain, i);
     ok = X509_check_trust(x, ctx->param->trust, 0);
     if (ok == X509_TRUST_TRUSTED)
         return 1;
     ctx->error_depth = i;
     ctx->current_cert = x;
     if (ok == X509_TRUST_REJECTED)
         ctx->error = X509_V_ERR_CERT_REJECTED;
     else
         ctx->error = X509_V_ERR_CERT_UNTRUSTED;
     ok = cb(0, ctx);
     return ok;
 #endif
 }
 
 static int check_revocation(X509_STORE_CTX *ctx)
 {
     int i, last, ok;
     if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK))
         return 1;
     if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
         last = sk_X509_num(ctx->chain) - 1;
     else {
         /* If checking CRL paths this isn't the EE certificate */
         if (ctx->parent)
             return 1;
         last = 0;
     }
     for (i = 0; i <= last; i++) {
         ctx->error_depth = i;
         ok = check_cert(ctx);
         if (!ok)
             return ok;
     }
     return 1;
 }
 
 static int check_cert(X509_STORE_CTX *ctx)
 {
     X509_CRL *crl = NULL, *dcrl = NULL;
     X509 *x;
     int ok, cnum;
     unsigned int last_reasons;
     cnum = ctx->error_depth;
     x = sk_X509_value(ctx->chain, cnum);
     ctx->current_cert = x;
     ctx->current_issuer = NULL;
     ctx->current_crl_score = 0;
     ctx->current_reasons = 0;
     while (ctx->current_reasons != CRLDP_ALL_REASONS) {
         last_reasons = ctx->current_reasons;
         /* Try to retrieve relevant CRL */
         if (ctx->get_crl)
             ok = ctx->get_crl(ctx, &crl, x);
         else
             ok = get_crl_delta(ctx, &crl, &dcrl, x);
         /*
          * If error looking up CRL, nothing we can do except notify callback
          */
         if (!ok) {
             ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
             ok = ctx->verify_cb(0, ctx);
             goto err;
         }
         ctx->current_crl = crl;
         ok = ctx->check_crl(ctx, crl);
         if (!ok)
             goto err;
 
         if (dcrl) {
             ok = ctx->check_crl(ctx, dcrl);
             if (!ok)
                 goto err;
             ok = ctx->cert_crl(ctx, dcrl, x);
             if (!ok)
                 goto err;
         } else
             ok = 1;
 
         /* Don't look in full CRL if delta reason is removefromCRL */
         if (ok != 2) {
             ok = ctx->cert_crl(ctx, crl, x);
             if (!ok)
                 goto err;
         }
 
         X509_CRL_free(crl);
         X509_CRL_free(dcrl);
         crl = NULL;
         dcrl = NULL;
         /*
          * If reasons not updated we wont get anywhere by another iteration,
          * so exit loop.
          */
         if (last_reasons == ctx->current_reasons) {
             ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL;
             ok = ctx->verify_cb(0, ctx);
             goto err;
         }
     }
  err:
     X509_CRL_free(crl);
     X509_CRL_free(dcrl);
 
     ctx->current_crl = NULL;
     return ok;
 
 }
 
 /* Check CRL times against values in X509_STORE_CTX */
 
 static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify)
 {
     time_t *ptime;
     int i;
     if (notify)
         ctx->current_crl = crl;
     if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
         ptime = &ctx->param->check_time;
     else
         ptime = NULL;
 
     i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime);
     if (i == 0) {
         if (!notify)
             return 0;
         ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     if (i > 0) {
         if (!notify)
             return 0;
         ctx->error = X509_V_ERR_CRL_NOT_YET_VALID;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     if (X509_CRL_get_nextUpdate(crl)) {
         i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime);
 
         if (i == 0) {
             if (!notify)
                 return 0;
             ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD;
             if (!ctx->verify_cb(0, ctx))
                 return 0;
         }
         /* Ignore expiry of base CRL is delta is valid */
         if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) {
             if (!notify)
                 return 0;
             ctx->error = X509_V_ERR_CRL_HAS_EXPIRED;
             if (!ctx->verify_cb(0, ctx))
                 return 0;
         }
     }
 
     if (notify)
         ctx->current_crl = NULL;
 
     return 1;
 }
 
 static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
                       X509 **pissuer, int *pscore, unsigned int *preasons,
                       STACK_OF(X509_CRL) *crls)
 {
     int i, crl_score, best_score = *pscore;
     unsigned int reasons, best_reasons = 0;
     X509 *x = ctx->current_cert;
     X509_CRL *crl, *best_crl = NULL;
     X509 *crl_issuer = NULL, *best_crl_issuer = NULL;
 
     for (i = 0; i < sk_X509_CRL_num(crls); i++) {
         crl = sk_X509_CRL_value(crls, i);
         reasons = *preasons;
         crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
 
         if (crl_score > best_score) {
             best_crl = crl;
             best_crl_issuer = crl_issuer;
             best_score = crl_score;
             best_reasons = reasons;
         }
     }
 
     if (best_crl) {
         if (*pcrl)
             X509_CRL_free(*pcrl);
         *pcrl = best_crl;
         *pissuer = best_crl_issuer;
         *pscore = best_score;
         *preasons = best_reasons;
         CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
         if (*pdcrl) {
             X509_CRL_free(*pdcrl);
             *pdcrl = NULL;
         }
         get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
     }
 
     if (best_score >= CRL_SCORE_VALID)
         return 1;
 
     return 0;
 }
 
 /*
  * Compare two CRL extensions for delta checking purposes. They should be
  * both present or both absent. If both present all fields must be identical.
  */
 
 static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid)
 {
     ASN1_OCTET_STRING *exta, *extb;
     int i;
     i = X509_CRL_get_ext_by_NID(a, nid, -1);
     if (i >= 0) {
         /* Can't have multiple occurrences */
         if (X509_CRL_get_ext_by_NID(a, nid, i) != -1)
             return 0;
         exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i));
     } else
         exta = NULL;
 
     i = X509_CRL_get_ext_by_NID(b, nid, -1);
 
     if (i >= 0) {
 
         if (X509_CRL_get_ext_by_NID(b, nid, i) != -1)
             return 0;
         extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i));
     } else
         extb = NULL;
 
     if (!exta && !extb)
         return 1;
 
     if (!exta || !extb)
         return 0;
 
     if (ASN1_OCTET_STRING_cmp(exta, extb))
         return 0;
 
     return 1;
 }
 
 /* See if a base and delta are compatible */
 
 static int check_delta_base(X509_CRL *delta, X509_CRL *base)
 {
     /* Delta CRL must be a delta */
     if (!delta->base_crl_number)
         return 0;
     /* Base must have a CRL number */
     if (!base->crl_number)
         return 0;
     /* Issuer names must match */
     if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta)))
         return 0;
     /* AKID and IDP must match */
     if (!crl_extension_match(delta, base, NID_authority_key_identifier))
         return 0;
     if (!crl_extension_match(delta, base, NID_issuing_distribution_point))
         return 0;
     /* Delta CRL base number must not exceed Full CRL number. */
     if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0)
         return 0;
     /* Delta CRL number must exceed full CRL number */
     if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0)
         return 1;
     return 0;
 }
 
 /*
  * For a given base CRL find a delta... maybe extend to delta scoring or
  * retrieve a chain of deltas...
  */
 
 static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
                          X509_CRL *base, STACK_OF(X509_CRL) *crls)
 {
     X509_CRL *delta;
     int i;
     if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS))
         return;
     if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST))
         return;
     for (i = 0; i < sk_X509_CRL_num(crls); i++) {
         delta = sk_X509_CRL_value(crls, i);
         if (check_delta_base(delta, base)) {
             if (check_crl_time(ctx, delta, 0))
                 *pscore |= CRL_SCORE_TIME_DELTA;
             CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
             *dcrl = delta;
             return;
         }
     }
     *dcrl = NULL;
 }
 
 /*
  * For a given CRL return how suitable it is for the supplied certificate
  * 'x'. The return value is a mask of several criteria. If the issuer is not
  * the certificate issuer this is returned in *pissuer. The reasons mask is
  * also used to determine if the CRL is suitable: if no new reasons the CRL
  * is rejected, otherwise reasons is updated.
  */
 
 static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer,
                          unsigned int *preasons, X509_CRL *crl, X509 *x)
 {
 
     int crl_score = 0;
     unsigned int tmp_reasons = *preasons, crl_reasons;
 
     /* First see if we can reject CRL straight away */
 
     /* Invalid IDP cannot be processed */
     if (crl->idp_flags & IDP_INVALID)
         return 0;
     /* Reason codes or indirect CRLs need extended CRL support */
     if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) {
         if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS))
             return 0;
     } else if (crl->idp_flags & IDP_REASONS) {
         /* If no new reasons reject */
         if (!(crl->idp_reasons & ~tmp_reasons))
             return 0;
     }
     /* Don't process deltas at this stage */
     else if (crl->base_crl_number)
         return 0;
     /* If issuer name doesn't match certificate need indirect CRL */
     if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) {
         if (!(crl->idp_flags & IDP_INDIRECT))
             return 0;
     } else
         crl_score |= CRL_SCORE_ISSUER_NAME;
 
     if (!(crl->flags & EXFLAG_CRITICAL))
         crl_score |= CRL_SCORE_NOCRITICAL;
 
     /* Check expiry */
     if (check_crl_time(ctx, crl, 0))
         crl_score |= CRL_SCORE_TIME;
 
     /* Check authority key ID and locate certificate issuer */
     crl_akid_check(ctx, crl, pissuer, &crl_score);
 
     /* If we can't locate certificate issuer at this point forget it */
 
     if (!(crl_score & CRL_SCORE_AKID))
         return 0;
 
     /* Check cert for matching CRL distribution points */
 
     if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) {
         /* If no new reasons reject */
         if (!(crl_reasons & ~tmp_reasons))
             return 0;
         tmp_reasons |= crl_reasons;
         crl_score |= CRL_SCORE_SCOPE;
     }
 
     *preasons = tmp_reasons;
 
     return crl_score;
 
 }
 
 static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl,
                            X509 **pissuer, int *pcrl_score)
 {
     X509 *crl_issuer = NULL;
     X509_NAME *cnm = X509_CRL_get_issuer(crl);
     int cidx = ctx->error_depth;
     int i;
 
     if (cidx != sk_X509_num(ctx->chain) - 1)
         cidx++;
 
     crl_issuer = sk_X509_value(ctx->chain, cidx);
 
     if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
         if (*pcrl_score & CRL_SCORE_ISSUER_NAME) {
             *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT;
             *pissuer = crl_issuer;
             return;
         }
     }
 
     for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) {
         crl_issuer = sk_X509_value(ctx->chain, cidx);
         if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
             continue;
         if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
             *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH;
             *pissuer = crl_issuer;
             return;
         }
     }
 
     /* Anything else needs extended CRL support */
 
     if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT))
         return;
 
     /*
      * Otherwise the CRL issuer is not on the path. Look for it in the set of
      * untrusted certificates.
      */
     for (i = 0; i < sk_X509_num(ctx->untrusted); i++) {
         crl_issuer = sk_X509_value(ctx->untrusted, i);
         if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm))
             continue;
         if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) {
             *pissuer = crl_issuer;
             *pcrl_score |= CRL_SCORE_AKID;
             return;
         }
     }
 }
 
 /*
  * Check the path of a CRL issuer certificate. This creates a new
  * X509_STORE_CTX and populates it with most of the parameters from the
  * parent. This could be optimised somewhat since a lot of path checking will
  * be duplicated by the parent, but this will rarely be used in practice.
  */
 
 static int check_crl_path(X509_STORE_CTX *ctx, X509 *x)
 {
     X509_STORE_CTX crl_ctx;
     int ret;
     /* Don't allow recursive CRL path validation */
     if (ctx->parent)
         return 0;
     if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted))
         return -1;
 
     crl_ctx.crls = ctx->crls;
     /* Copy verify params across */
     X509_STORE_CTX_set0_param(&crl_ctx, ctx->param);
 
     crl_ctx.parent = ctx;
     crl_ctx.verify_cb = ctx->verify_cb;
 
     /* Verify CRL issuer */
     ret = X509_verify_cert(&crl_ctx);
 
     if (ret <= 0)
         goto err;
 
     /* Check chain is acceptable */
 
     ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain);
  err:
     X509_STORE_CTX_cleanup(&crl_ctx);
     return ret;
 }
 
 /*
  * RFC3280 says nothing about the relationship between CRL path and
  * certificate path, which could lead to situations where a certificate could
  * be revoked or validated by a CA not authorised to do so. RFC5280 is more
  * strict and states that the two paths must end in the same trust anchor,
  * though some discussions remain... until this is resolved we use the
  * RFC5280 version
  */
 
 static int check_crl_chain(X509_STORE_CTX *ctx,
                            STACK_OF(X509) *cert_path,
                            STACK_OF(X509) *crl_path)
 {
     X509 *cert_ta, *crl_ta;
     cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1);
     crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1);
     if (!X509_cmp(cert_ta, crl_ta))
         return 1;
     return 0;
 }
 
 /*-
  * Check for match between two dist point names: three separate cases.
  * 1. Both are relative names and compare X509_NAME types.
  * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES.
  * 3. Both are full names and compare two GENERAL_NAMES.
  * 4. One is NULL: automatic match.
  */
 
 static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b)
 {
     X509_NAME *nm = NULL;
     GENERAL_NAMES *gens = NULL;
     GENERAL_NAME *gena, *genb;
     int i, j;
     if (!a || !b)
         return 1;
     if (a->type == 1) {
         if (!a->dpname)
             return 0;
         /* Case 1: two X509_NAME */
         if (b->type == 1) {
             if (!b->dpname)
                 return 0;
             if (!X509_NAME_cmp(a->dpname, b->dpname))
                 return 1;
             else
                 return 0;
         }
         /* Case 2: set name and GENERAL_NAMES appropriately */
         nm = a->dpname;
         gens = b->name.fullname;
     } else if (b->type == 1) {
         if (!b->dpname)
             return 0;
         /* Case 2: set name and GENERAL_NAMES appropriately */
         gens = a->name.fullname;
         nm = b->dpname;
     }
 
     /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */
     if (nm) {
         for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
             gena = sk_GENERAL_NAME_value(gens, i);
             if (gena->type != GEN_DIRNAME)
                 continue;
             if (!X509_NAME_cmp(nm, gena->d.directoryName))
                 return 1;
         }
         return 0;
     }
 
     /* Else case 3: two GENERAL_NAMES */
 
     for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) {
         gena = sk_GENERAL_NAME_value(a->name.fullname, i);
         for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) {
             genb = sk_GENERAL_NAME_value(b->name.fullname, j);
             if (!GENERAL_NAME_cmp(gena, genb))
                 return 1;
         }
     }
 
     return 0;
 
 }
 
 static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score)
 {
     int i;
     X509_NAME *nm = X509_CRL_get_issuer(crl);
     /* If no CRLissuer return is successful iff don't need a match */
     if (!dp->CRLissuer)
         return ! !(crl_score & CRL_SCORE_ISSUER_NAME);
     for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) {
         GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i);
         if (gen->type != GEN_DIRNAME)
             continue;
         if (!X509_NAME_cmp(gen->d.directoryName, nm))
             return 1;
     }
     return 0;
 }
 
 /* Check CRLDP and IDP */
 
 static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score,
                            unsigned int *preasons)
 {
     int i;
     if (crl->idp_flags & IDP_ONLYATTR)
         return 0;
     if (x->ex_flags & EXFLAG_CA) {
         if (crl->idp_flags & IDP_ONLYUSER)
             return 0;
     } else {
         if (crl->idp_flags & IDP_ONLYCA)
             return 0;
     }
     *preasons = crl->idp_reasons;
     for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) {
         DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i);
         if (crldp_check_crlissuer(dp, crl, crl_score)) {
             if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) {
                 *preasons &= dp->dp_reasons;
                 return 1;
             }
         }
     }
     if ((!crl->idp || !crl->idp->distpoint)
         && (crl_score & CRL_SCORE_ISSUER_NAME))
         return 1;
     return 0;
 }
 
 /*
  * Retrieve CRL corresponding to current certificate. If deltas enabled try
  * to find a delta CRL too
  */
 
 static int get_crl_delta(X509_STORE_CTX *ctx,
                          X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x)
 {
     int ok;
     X509 *issuer = NULL;
     int crl_score = 0;
     unsigned int reasons;
     X509_CRL *crl = NULL, *dcrl = NULL;
     STACK_OF(X509_CRL) *skcrl;
     X509_NAME *nm = X509_get_issuer_name(x);
     reasons = ctx->current_reasons;
     ok = get_crl_sk(ctx, &crl, &dcrl,
                     &issuer, &crl_score, &reasons, ctx->crls);
 
     if (ok)
         goto done;
 
     /* Lookup CRLs from store */
 
     skcrl = ctx->lookup_crls(ctx, nm);
 
     /* If no CRLs found and a near match from get_crl_sk use that */
     if (!skcrl && crl)
         goto done;
 
     get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl);
 
     sk_X509_CRL_pop_free(skcrl, X509_CRL_free);
 
  done:
 
     /* If we got any kind of CRL use it and return success */
     if (crl) {
         ctx->current_issuer = issuer;
         ctx->current_crl_score = crl_score;
         ctx->current_reasons = reasons;
         *pcrl = crl;
         *pdcrl = dcrl;
         return 1;
     }
 
     return 0;
 }
 
 /* Check CRL validity */
 static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
 {
     X509 *issuer = NULL;
     EVP_PKEY *ikey = NULL;
     int ok = 0, chnum, cnum;
     cnum = ctx->error_depth;
     chnum = sk_X509_num(ctx->chain) - 1;
     /* if we have an alternative CRL issuer cert use that */
     if (ctx->current_issuer)
         issuer = ctx->current_issuer;
 
     /*
      * Else find CRL issuer: if not last certificate then issuer is next
      * certificate in chain.
      */
     else if (cnum < chnum)
         issuer = sk_X509_value(ctx->chain, cnum + 1);
     else {
         issuer = sk_X509_value(ctx->chain, chnum);
         /* If not self signed, can't check signature */
         if (!ctx->check_issued(ctx, issuer, issuer)) {
             ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER;
             ok = ctx->verify_cb(0, ctx);
             if (!ok)
                 goto err;
         }
     }
 
     if (issuer) {
         /*
          * Skip most tests for deltas because they have already been done
          */
         if (!crl->base_crl_number) {
             /* Check for cRLSign bit if keyUsage present */
             if ((issuer->ex_flags & EXFLAG_KUSAGE) &&
                 !(issuer->ex_kusage & KU_CRL_SIGN)) {
                 ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN;
                 ok = ctx->verify_cb(0, ctx);
                 if (!ok)
                     goto err;
             }
 
             if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) {
                 ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE;
                 ok = ctx->verify_cb(0, ctx);
                 if (!ok)
                     goto err;
             }
 
             if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) {
                 if (check_crl_path(ctx, ctx->current_issuer) <= 0) {
                     ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
                     ok = ctx->verify_cb(0, ctx);
                     if (!ok)
                         goto err;
                 }
             }
 
             if (crl->idp_flags & IDP_INVALID) {
                 ctx->error = X509_V_ERR_INVALID_EXTENSION;
                 ok = ctx->verify_cb(0, ctx);
                 if (!ok)
                     goto err;
             }
 
         }
 
         if (!(ctx->current_crl_score & CRL_SCORE_TIME)) {
             ok = check_crl_time(ctx, crl, 1);
             if (!ok)
                 goto err;
         }
 
         /* Attempt to get issuer certificate public key */
         ikey = X509_get_pubkey(issuer);
 
         if (!ikey) {
             ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
             ok = ctx->verify_cb(0, ctx);
             if (!ok)
                 goto err;
         } else {
             /* Verify CRL signature */
             if (X509_CRL_verify(crl, ikey) <= 0) {
                 ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE;
                 ok = ctx->verify_cb(0, ctx);
                 if (!ok)
                     goto err;
             }
         }
     }
 
     ok = 1;
 
  err:
     EVP_PKEY_free(ikey);
     return ok;
 }
 
 /* Check certificate against CRL */
 static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x)
 {
     int ok;
     X509_REVOKED *rev;
     /*
      * The rules changed for this... previously if a CRL contained unhandled
      * critical extensions it could still be used to indicate a certificate
      * was revoked. This has since been changed since critical extension can
      * change the meaning of CRL entries.
      */
     if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL)
         && (crl->flags & EXFLAG_CRITICAL)) {
         ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION;
         ok = ctx->verify_cb(0, ctx);
         if (!ok)
             return 0;
     }
     /*
      * Look for serial number of certificate in CRL If found make sure reason
      * is not removeFromCRL.
      */
     if (X509_CRL_get0_by_cert(crl, &rev, x)) {
         if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
             return 2;
         ctx->error = X509_V_ERR_CERT_REVOKED;
         ok = ctx->verify_cb(0, ctx);
         if (!ok)
             return 0;
     }
 
     return 1;
 }
 
 static int check_policy(X509_STORE_CTX *ctx)
 {
     int ret;
     if (ctx->parent)
         return 1;
     ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain,
                             ctx->param->policies, ctx->param->flags);
     if (ret == 0) {
         X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
         return 0;
     }
     /* Invalid or inconsistent extensions */
     if (ret == -1) {
         /*
          * Locate certificates with bad extensions and notify callback.
          */
         X509 *x;
         int i;
         for (i = 1; i < sk_X509_num(ctx->chain); i++) {
             x = sk_X509_value(ctx->chain, i);
             if (!(x->ex_flags & EXFLAG_INVALID_POLICY))
                 continue;
             ctx->current_cert = x;
             ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION;
             if (!ctx->verify_cb(0, ctx))
                 return 0;
         }
         return 1;
     }
     if (ret == -2) {
         ctx->current_cert = NULL;
         ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY;
         return ctx->verify_cb(0, ctx);
     }
 
     if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
         ctx->current_cert = NULL;
-        ctx->error = X509_V_OK;
+        /*
+         * Verification errors need to be "sticky", a callback may have allowed
+         * an SSL handshake to continue despite an error, and we must then
+         * remain in an error state.  Therefore, we MUST NOT clear earlier
+         * verification errors by setting the error to X509_V_OK.
+         */
         if (!ctx->verify_cb(2, ctx))
             return 0;
     }
 
     return 1;
 }
 
 static int check_cert_time(X509_STORE_CTX *ctx, X509 *x)
 {
     time_t *ptime;
     int i;
 
     if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME)
         ptime = &ctx->param->check_time;
     else
         ptime = NULL;
 
     i = X509_cmp_time(X509_get_notBefore(x), ptime);
     if (i == 0) {
         ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD;
         ctx->current_cert = x;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     if (i > 0) {
         ctx->error = X509_V_ERR_CERT_NOT_YET_VALID;
         ctx->current_cert = x;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     i = X509_cmp_time(X509_get_notAfter(x), ptime);
     if (i == 0) {
         ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD;
         ctx->current_cert = x;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     if (i < 0) {
         ctx->error = X509_V_ERR_CERT_HAS_EXPIRED;
         ctx->current_cert = x;
         if (!ctx->verify_cb(0, ctx))
             return 0;
     }
 
     return 1;
 }
 
 static int internal_verify(X509_STORE_CTX *ctx)
 {
     int ok = 0, n;
     X509 *xs, *xi;
     EVP_PKEY *pkey = NULL;
     int (*cb) (int xok, X509_STORE_CTX *xctx);
 
     cb = ctx->verify_cb;
 
     n = sk_X509_num(ctx->chain);
     ctx->error_depth = n - 1;
     n--;
     xi = sk_X509_value(ctx->chain, n);
 
     if (ctx->check_issued(ctx, xi, xi))
         xs = xi;
     else {
         if (n <= 0) {
             ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
             ctx->current_cert = xi;
             ok = cb(0, ctx);
             goto end;
         } else {
             n--;
             ctx->error_depth = n;
             xs = sk_X509_value(ctx->chain, n);
         }
     }
 
 /*      ctx->error=0;  not needed */
     while (n >= 0) {
         ctx->error_depth = n;
 
         /*
          * Skip signature check for self signed certificates unless
          * explicitly asked for. It doesn't add any security and just wastes
          * time.
          */
         if (!xs->valid
             && (xs != xi
                 || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) {
             if ((pkey = X509_get_pubkey(xi)) == NULL) {
                 ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY;
                 ctx->current_cert = xi;
                 ok = (*cb) (0, ctx);
                 if (!ok)
                     goto end;
             } else if (X509_verify(xs, pkey) <= 0) {
                 ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE;
                 ctx->current_cert = xs;
                 ok = (*cb) (0, ctx);
                 if (!ok) {
                     EVP_PKEY_free(pkey);
                     goto end;
                 }
             }
             EVP_PKEY_free(pkey);
             pkey = NULL;
         }
 
         xs->valid = 1;
 
         ok = check_cert_time(ctx, xs);
         if (!ok)
             goto end;
 
         /* The last error (if any) is still in the error value */
         ctx->current_issuer = xi;
         ctx->current_cert = xs;
         ok = (*cb) (1, ctx);
         if (!ok)
             goto end;
 
         n--;
         if (n >= 0) {
             xi = xs;
             xs = sk_X509_value(ctx->chain, n);
         }
     }
     ok = 1;
  end:
     return ok;
 }
 
 int X509_cmp_current_time(const ASN1_TIME *ctm)
 {
     return X509_cmp_time(ctm, NULL);
 }
 
 int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
 {
     char *str;
     ASN1_TIME atm;
     long offset;
     char buff1[24], buff2[24], *p;
     int i, j, remaining;
 
     p = buff1;
     remaining = ctm->length;
     str = (char *)ctm->data;
     /*
      * Note that the following (historical) code allows much more slack in the
      * time format than RFC5280. In RFC5280, the representation is fixed:
      * UTCTime: YYMMDDHHMMSSZ
      * GeneralizedTime: YYYYMMDDHHMMSSZ
      */
     if (ctm->type == V_ASN1_UTCTIME) {
         /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */
         int min_length = sizeof("YYMMDDHHMMZ") - 1;
         int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1;
         if (remaining < min_length || remaining > max_length)
             return 0;
         memcpy(p, str, 10);
         p += 10;
         str += 10;
         remaining -= 10;
     } else {
         /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */
         int min_length = sizeof("YYYYMMDDHHMMZ") - 1;
         int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1;
         if (remaining < min_length || remaining > max_length)
             return 0;
         memcpy(p, str, 12);
         p += 12;
         str += 12;
         remaining -= 12;
     }
 
     if ((*str == 'Z') || (*str == '-') || (*str == '+')) {
         *(p++) = '0';
         *(p++) = '0';
     } else {
         /* SS (seconds) */
         if (remaining < 2)
             return 0;
         *(p++) = *(str++);
         *(p++) = *(str++);
         remaining -= 2;
         /*
          * Skip any (up to three) fractional seconds...
          * TODO(emilia): in RFC5280, fractional seconds are forbidden.
          * Can we just kill them altogether?
          */
         if (remaining && *str == '.') {
             str++;
             remaining--;
             for (i = 0; i < 3 && remaining; i++, str++, remaining--) {
                 if (*str < '0' || *str > '9')
                     break;
             }
         }
 
     }
     *(p++) = 'Z';
     *(p++) = '\0';
 
     /* We now need either a terminating 'Z' or an offset. */
     if (!remaining)
         return 0;
     if (*str == 'Z') {
         if (remaining != 1)
             return 0;
         offset = 0;
     } else {
         /* (+-)HHMM */
         if ((*str != '+') && (*str != '-'))
             return 0;
         /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */
         if (remaining != 5)
             return 0;
         if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' ||
             str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9')
             return 0;
         offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60;
         offset += (str[3] - '0') * 10 + (str[4] - '0');
         if (*str == '-')
             offset = -offset;
     }
     atm.type = ctm->type;
     atm.flags = 0;
     atm.length = sizeof(buff2);
     atm.data = (unsigned char *)buff2;
 
     if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL)
         return 0;
 
     if (ctm->type == V_ASN1_UTCTIME) {
         i = (buff1[0] - '0') * 10 + (buff1[1] - '0');
         if (i < 50)
             i += 100;           /* cf. RFC 2459 */
         j = (buff2[0] - '0') * 10 + (buff2[1] - '0');
         if (j < 50)
             j += 100;
 
         if (i < j)
             return -1;
         if (i > j)
             return 1;
     }
     i = strcmp(buff1, buff2);
     if (i == 0)                 /* wait a second then return younger :-) */
         return -1;
     else
         return i;
 }
 
 ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj)
 {
     return X509_time_adj(s, adj, NULL);
 }
 
 ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm)
 {
     return X509_time_adj_ex(s, 0, offset_sec, in_tm);
 }
 
 ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                             int offset_day, long offset_sec, time_t *in_tm)
 {
     time_t t;
 
     if (in_tm)
         t = *in_tm;
     else
         time(&t);
 
     if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) {
         if (s->type == V_ASN1_UTCTIME)
             return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
         if (s->type == V_ASN1_GENERALIZEDTIME)
             return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
     }
     return ASN1_TIME_adj(s, t, offset_day, offset_sec);
 }
 
 int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain)
 {
     EVP_PKEY *ktmp = NULL, *ktmp2;
     int i, j;
 
     if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey))
         return 1;
 
     for (i = 0; i < sk_X509_num(chain); i++) {
         ktmp = X509_get_pubkey(sk_X509_value(chain, i));
         if (ktmp == NULL) {
             X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
                     X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY);
             return 0;
         }
         if (!EVP_PKEY_missing_parameters(ktmp))
             break;
         else {
             EVP_PKEY_free(ktmp);
             ktmp = NULL;
         }
     }
     if (ktmp == NULL) {
         X509err(X509_F_X509_GET_PUBKEY_PARAMETERS,
                 X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN);
         return 0;
     }
 
     /* first, populate the other certs */
     for (j = i - 1; j >= 0; j--) {
         ktmp2 = X509_get_pubkey(sk_X509_value(chain, j));
         EVP_PKEY_copy_parameters(ktmp2, ktmp);
         EVP_PKEY_free(ktmp2);
     }
 
     if (pkey != NULL)
         EVP_PKEY_copy_parameters(pkey, ktmp);
     EVP_PKEY_free(ktmp);
     return 1;
 }
 
 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                     CRYPTO_EX_new *new_func,
                                     CRYPTO_EX_dup *dup_func,
                                     CRYPTO_EX_free *free_func)
 {
     /*
      * This function is (usually) called only once, by
      * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c).
      */
     return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp,
                                    new_func, dup_func, free_func);
 }
 
 int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data)
 {
     return CRYPTO_set_ex_data(&ctx->ex_data, idx, data);
 }
 
 void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx)
 {
     return CRYPTO_get_ex_data(&ctx->ex_data, idx);
 }
 
 int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx)
 {
     return ctx->error;
 }
 
 void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err)
 {
     ctx->error = err;
 }
 
 int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx)
 {
     return ctx->error_depth;
 }
 
 X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx)
 {
     return ctx->current_cert;
 }
 
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx)
 {
     return ctx->chain;
 }
 
 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
 {
     int i;
     X509 *x;
     STACK_OF(X509) *chain;
     if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain)))
         return NULL;
     for (i = 0; i < sk_X509_num(chain); i++) {
         x = sk_X509_value(chain, i);
         CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
     }
     return chain;
 }
 
 X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
 {
     return ctx->current_issuer;
 }
 
 X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
 {
     return ctx->current_crl;
 }
 
 X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
 {
     return ctx->parent;
 }
 
 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
 {
     ctx->cert = x;
 }
 
 void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
 {
     ctx->untrusted = sk;
 }
 
 void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk)
 {
     ctx->crls = sk;
 }
 
 int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose)
 {
     return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0);
 }
 
 int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust)
 {
     return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust);
 }
 
 /*
  * This function is used to set the X509_STORE_CTX purpose and trust values.
  * This is intended to be used when another structure has its own trust and
  * purpose values which (if set) will be inherited by the ctx. If they aren't
  * set then we will usually have a default purpose in mind which should then
  * be used to set the trust value. An example of this is SSL use: an SSL
  * structure will have its own purpose and trust settings which the
  * application can set: if they aren't set then we use the default of SSL
  * client/server.
  */
 
 int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
                                    int purpose, int trust)
 {
     int idx;
     /* If purpose not set use default */
     if (!purpose)
         purpose = def_purpose;
     /* If we have a purpose then check it is valid */
     if (purpose) {
         X509_PURPOSE *ptmp;
         idx = X509_PURPOSE_get_by_id(purpose);
         if (idx == -1) {
             X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
                     X509_R_UNKNOWN_PURPOSE_ID);
             return 0;
         }
         ptmp = X509_PURPOSE_get0(idx);
         if (ptmp->trust == X509_TRUST_DEFAULT) {
             idx = X509_PURPOSE_get_by_id(def_purpose);
             if (idx == -1) {
                 X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
                         X509_R_UNKNOWN_PURPOSE_ID);
                 return 0;
             }
             ptmp = X509_PURPOSE_get0(idx);
         }
         /* If trust not set then get from purpose default */
         if (!trust)
             trust = ptmp->trust;
     }
     if (trust) {
         idx = X509_TRUST_get_by_id(trust);
         if (idx == -1) {
             X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT,
                     X509_R_UNKNOWN_TRUST_ID);
             return 0;
         }
     }
 
     if (purpose && !ctx->param->purpose)
         ctx->param->purpose = purpose;
     if (trust && !ctx->param->trust)
         ctx->param->trust = trust;
     return 1;
 }
 
 X509_STORE_CTX *X509_STORE_CTX_new(void)
 {
     X509_STORE_CTX *ctx;
     ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
     if (!ctx) {
         X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
     memset(ctx, 0, sizeof(X509_STORE_CTX));
     return ctx;
 }
 
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx)
 {
     if (!ctx)
         return;
     X509_STORE_CTX_cleanup(ctx);
     OPENSSL_free(ctx);
 }
 
 int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509,
                         STACK_OF(X509) *chain)
 {
     int ret = 1;
     ctx->ctx = store;
     ctx->current_method = 0;
     ctx->cert = x509;
     ctx->untrusted = chain;
     ctx->crls = NULL;
     ctx->last_untrusted = 0;
     ctx->other_ctx = NULL;
     ctx->valid = 0;
     ctx->chain = NULL;
     ctx->error = 0;
     ctx->explicit_policy = 0;
     ctx->error_depth = 0;
     ctx->current_cert = NULL;
     ctx->current_issuer = NULL;
     ctx->current_crl = NULL;
     ctx->current_crl_score = 0;
     ctx->current_reasons = 0;
     ctx->tree = NULL;
     ctx->parent = NULL;
     /* Zero ex_data to make sure we're cleanup-safe */
     memset(&ctx->ex_data, 0, sizeof(ctx->ex_data));
 
     ctx->param = X509_VERIFY_PARAM_new();
     if (!ctx->param) {
         X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
         return 0;
     }
 
     /*
      * Inherit callbacks and flags from X509_STORE if not set use defaults.
      */
     if (store)
         ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param);
     else
         ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE;
 
     if (store) {
         ctx->verify_cb = store->verify_cb;
         /* Seems to always be 0 in OpenSSL, else must be idempotent */
         ctx->cleanup = store->cleanup;
     } else
         ctx->cleanup = 0;
 
     if (ret)
         ret = X509_VERIFY_PARAM_inherit(ctx->param,
                                         X509_VERIFY_PARAM_lookup("default"));
 
     if (ret == 0) {
         X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     if (store && store->check_issued)
         ctx->check_issued = store->check_issued;
     else
         ctx->check_issued = check_issued;
 
     if (store && store->get_issuer)
         ctx->get_issuer = store->get_issuer;
     else
         ctx->get_issuer = X509_STORE_CTX_get1_issuer;
 
     if (store && store->verify_cb)
         ctx->verify_cb = store->verify_cb;
     else
         ctx->verify_cb = null_callback;
 
     if (store && store->verify)
         ctx->verify = store->verify;
     else
         ctx->verify = internal_verify;
 
     if (store && store->check_revocation)
         ctx->check_revocation = store->check_revocation;
     else
         ctx->check_revocation = check_revocation;
 
     if (store && store->get_crl)
         ctx->get_crl = store->get_crl;
     else
         ctx->get_crl = NULL;
 
     if (store && store->check_crl)
         ctx->check_crl = store->check_crl;
     else
         ctx->check_crl = check_crl;
 
     if (store && store->cert_crl)
         ctx->cert_crl = store->cert_crl;
     else
         ctx->cert_crl = cert_crl;
 
     if (store && store->lookup_certs)
         ctx->lookup_certs = store->lookup_certs;
     else
         ctx->lookup_certs = X509_STORE_get1_certs;
 
     if (store && store->lookup_crls)
         ctx->lookup_crls = store->lookup_crls;
     else
         ctx->lookup_crls = X509_STORE_get1_crls;
 
     ctx->check_policy = check_policy;
 
     if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx,
                            &ctx->ex_data))
         return 1;
     X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE);
 
  err:
     /*
      * On error clean up allocated storage, if the store context was not
      * allocated with X509_STORE_CTX_new() this is our last chance to do so.
      */
     X509_STORE_CTX_cleanup(ctx);
     return 0;
 }
 
 /*
  * Set alternative lookup method: just a STACK of trusted certificates. This
  * avoids X509_STORE nastiness where it isn't needed.
  */
 
 void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk)
 {
     ctx->other_ctx = sk;
     ctx->get_issuer = get_issuer_sk;
 }
 
 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx)
 {
     /*
      * We need to be idempotent because, unfortunately, free() also calls
      * cleanup(), so the natural call sequence new(), init(), cleanup(), free()
      * calls cleanup() for the same object twice!  Thus we must zero the
      * pointers below after they're freed!
      */
     /* Seems to always be 0 in OpenSSL, do this at most once. */
     if (ctx->cleanup != NULL) {
         ctx->cleanup(ctx);
         ctx->cleanup = NULL;
     }
     if (ctx->param != NULL) {
         if (ctx->parent == NULL)
             X509_VERIFY_PARAM_free(ctx->param);
         ctx->param = NULL;
     }
     if (ctx->tree != NULL) {
         X509_policy_tree_free(ctx->tree);
         ctx->tree = NULL;
     }
     if (ctx->chain != NULL) {
         sk_X509_pop_free(ctx->chain, X509_free);
         ctx->chain = NULL;
     }
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data));
     memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA));
 }
 
 void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth)
 {
     X509_VERIFY_PARAM_set_depth(ctx->param, depth);
 }
 
 void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags)
 {
     X509_VERIFY_PARAM_set_flags(ctx->param, flags);
 }
 
 void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
                              time_t t)
 {
     X509_VERIFY_PARAM_set_time(ctx->param, t);
 }
 
 void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
                                   int (*verify_cb) (int, X509_STORE_CTX *))
 {
     ctx->verify_cb = verify_cb;
 }
 
 X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx)
 {
     return ctx->tree;
 }
 
 int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx)
 {
     return ctx->explicit_policy;
 }
 
 int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name)
 {
     const X509_VERIFY_PARAM *param;
     param = X509_VERIFY_PARAM_lookup(name);
     if (!param)
         return 0;
     return X509_VERIFY_PARAM_inherit(ctx->param, param);
 }
 
 X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx)
 {
     return ctx->param;
 }
 
 void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param)
 {
     if (ctx->param)
         X509_VERIFY_PARAM_free(ctx->param);
     ctx->param = param;
 }
 
 IMPLEMENT_STACK_OF(X509)
 
 IMPLEMENT_ASN1_SET_OF(X509)
 
 IMPLEMENT_STACK_OF(X509_NAME)
 
 IMPLEMENT_STACK_OF(X509_ATTRIBUTE)
 
 IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE)
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509/x509_vfy.h	(revision 306191)
@@ -1,595 +1,615 @@
 /* crypto/x509/x509_vfy.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_X509_H
 # include <openssl/x509.h>
 /*
  * openssl/x509.h ends up #include-ing this file at about the only
  * appropriate moment.
  */
 #endif
 
 #ifndef HEADER_X509_VFY_H
 # define HEADER_X509_VFY_H
 
 # include <openssl/opensslconf.h>
 # ifndef OPENSSL_NO_LHASH
 #  include <openssl/lhash.h>
 # endif
 # include <openssl/bio.h>
 # include <openssl/crypto.h>
 # include <openssl/symhacks.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 # if 0
 /* Outer object */
 typedef struct x509_hash_dir_st {
     int num_dirs;
     char **dirs;
     int *dirs_type;
     int num_dirs_alloced;
 } X509_HASH_DIR_CTX;
 # endif
 
 typedef struct x509_file_st {
     int num_paths;              /* number of paths to files or directories */
     int num_alloced;
     char **paths;               /* the list of paths or directories */
     int *path_type;
 } X509_CERT_FILE_CTX;
 
 /*******************************/
 /*-
 SSL_CTX -> X509_STORE
                 -> X509_LOOKUP
                         ->X509_LOOKUP_METHOD
                 -> X509_LOOKUP
                         ->X509_LOOKUP_METHOD
 
 SSL     -> X509_STORE_CTX
                 ->X509_STORE
 
 The X509_STORE holds the tables etc for verification stuff.
 A X509_STORE_CTX is used while validating a single certificate.
 The X509_STORE has X509_LOOKUPs for looking up certs.
 The X509_STORE then calls a function to actually verify the
 certificate chain.
 */
 
 # define X509_LU_RETRY           -1
 # define X509_LU_FAIL            0
 # define X509_LU_X509            1
 # define X509_LU_CRL             2
 # define X509_LU_PKEY            3
 
 typedef struct x509_object_st {
     /* one of the above types */
     int type;
     union {
         char *ptr;
         X509 *x509;
         X509_CRL *crl;
         EVP_PKEY *pkey;
     } data;
 } X509_OBJECT;
 
 typedef struct x509_lookup_st X509_LOOKUP;
 
 DECLARE_STACK_OF(X509_LOOKUP)
 DECLARE_STACK_OF(X509_OBJECT)
 
 /* This is a static that defines the function interface */
 typedef struct x509_lookup_method_st {
     const char *name;
     int (*new_item) (X509_LOOKUP *ctx);
     void (*free) (X509_LOOKUP *ctx);
     int (*init) (X509_LOOKUP *ctx);
     int (*shutdown) (X509_LOOKUP *ctx);
     int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl,
                  char **ret);
     int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name,
                            X509_OBJECT *ret);
     int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name,
                                  ASN1_INTEGER *serial, X509_OBJECT *ret);
     int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type,
                                unsigned char *bytes, int len,
                                X509_OBJECT *ret);
     int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len,
                          X509_OBJECT *ret);
 } X509_LOOKUP_METHOD;
 
 /*
  * This structure hold all parameters associated with a verify operation by
  * including an X509_VERIFY_PARAM structure in related structures the
  * parameters used can be customized
  */
 
 typedef struct X509_VERIFY_PARAM_st {
     char *name;
     time_t check_time;          /* Time to use */
     unsigned long inh_flags;    /* Inheritance flags */
     unsigned long flags;        /* Various verify flags */
     int purpose;                /* purpose to check untrusted certificates */
     int trust;                  /* trust setting to check */
     int depth;                  /* Verify depth */
     STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */
 } X509_VERIFY_PARAM;
 
 DECLARE_STACK_OF(X509_VERIFY_PARAM)
 
 /*
  * This is used to hold everything.  It is used for all certificate
  * validation.  Once we have a certificate chain, the 'verify' function is
  * then called to actually check the cert chain.
  */
 struct x509_store_st {
     /* The following is a cache of trusted certs */
     int cache;                  /* if true, stash any hits */
     STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */
     /* These are external lookup methods */
     STACK_OF(X509_LOOKUP) *get_cert_methods;
     X509_VERIFY_PARAM *param;
     /* Callbacks for various operations */
     /* called to verify a certificate */
     int (*verify) (X509_STORE_CTX *ctx);
     /* error callback */
     int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
     /* get issuers cert from ctx */
     int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
     /* check issued */
     int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
     /* Check revocation status of chain */
     int (*check_revocation) (X509_STORE_CTX *ctx);
     /* retrieve CRL */
     int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
     /* Check CRL validity */
     int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
     /* Check certificate against CRL */
     int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
     STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
     STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
     int (*cleanup) (X509_STORE_CTX *ctx);
     CRYPTO_EX_DATA ex_data;
     int references;
 } /* X509_STORE */ ;
 
 int X509_STORE_set_depth(X509_STORE *store, int depth);
 
 # define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func))
 # define X509_STORE_set_verify_func(ctx,func)    ((ctx)->verify=(func))
 
 /* This is the functions plus an instance of the local variables. */
 struct x509_lookup_st {
     int init;                   /* have we been started */
     int skip;                   /* don't use us. */
     X509_LOOKUP_METHOD *method; /* the functions */
     char *method_data;          /* method data */
     X509_STORE *store_ctx;      /* who owns us */
 } /* X509_LOOKUP */ ;
 
 /*
  * This is a used when verifying cert chains.  Since the gathering of the
  * cert chain can take some time (and have to be 'retried', this needs to be
  * kept and passed around.
  */
 struct x509_store_ctx_st {      /* X509_STORE_CTX */
     X509_STORE *ctx;
     /* used when looking up certs */
     int current_method;
     /* The following are set by the caller */
     /* The cert to check */
     X509 *cert;
     /* chain of X509s - untrusted - passed in */
     STACK_OF(X509) *untrusted;
     /* set of CRLs passed in */
     STACK_OF(X509_CRL) *crls;
     X509_VERIFY_PARAM *param;
     /* Other info for use with get_issuer() */
     void *other_ctx;
     /* Callbacks for various operations */
     /* called to verify a certificate */
     int (*verify) (X509_STORE_CTX *ctx);
     /* error callback */
     int (*verify_cb) (int ok, X509_STORE_CTX *ctx);
     /* get issuers cert from ctx */
     int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
     /* check issued */
     int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
     /* Check revocation status of chain */
     int (*check_revocation) (X509_STORE_CTX *ctx);
     /* retrieve CRL */
     int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x);
     /* Check CRL validity */
     int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl);
     /* Check certificate against CRL */
     int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x);
     int (*check_policy) (X509_STORE_CTX *ctx);
     STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm);
     STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm);
     int (*cleanup) (X509_STORE_CTX *ctx);
     /* The following is built up */
     /* if 0, rebuild chain */
     int valid;
     /* index of last untrusted cert */
     int last_untrusted;
     /* chain of X509s - built up and trusted */
     STACK_OF(X509) *chain;
     /* Valid policy tree */
     X509_POLICY_TREE *tree;
     /* Require explicit policy value */
     int explicit_policy;
     /* When something goes wrong, this is why */
     int error_depth;
     int error;
     X509 *current_cert;
     /* cert currently being tested as valid issuer */
     X509 *current_issuer;
     /* current CRL */
     X509_CRL *current_crl;
     /* score of current CRL */
     int current_crl_score;
     /* Reason mask */
     unsigned int current_reasons;
     /* For CRL path validation: parent context */
     X509_STORE_CTX *parent;
     CRYPTO_EX_DATA ex_data;
 } /* X509_STORE_CTX */ ;
 
 void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
 
 # define X509_STORE_CTX_set_app_data(ctx,data) \
         X509_STORE_CTX_set_ex_data(ctx,0,data)
 # define X509_STORE_CTX_get_app_data(ctx) \
         X509_STORE_CTX_get_ex_data(ctx,0)
 
 # define X509_L_FILE_LOAD        1
 # define X509_L_ADD_DIR          2
 
 # define X509_LOOKUP_load_file(x,name,type) \
                 X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL)
 
 # define X509_LOOKUP_add_dir(x,name,type) \
                 X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL)
 
 # define         X509_V_OK                                       0
 # define         X509_V_ERR_UNSPECIFIED                          1
 
 # define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT            2
 # define         X509_V_ERR_UNABLE_TO_GET_CRL                    3
 # define         X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE     4
 # define         X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE      5
 # define         X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY   6
 # define         X509_V_ERR_CERT_SIGNATURE_FAILURE               7
 # define         X509_V_ERR_CRL_SIGNATURE_FAILURE                8
 # define         X509_V_ERR_CERT_NOT_YET_VALID                   9
 # define         X509_V_ERR_CERT_HAS_EXPIRED                     10
 # define         X509_V_ERR_CRL_NOT_YET_VALID                    11
 # define         X509_V_ERR_CRL_HAS_EXPIRED                      12
 # define         X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD       13
 # define         X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD        14
 # define         X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD       15
 # define         X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD       16
 # define         X509_V_ERR_OUT_OF_MEM                           17
 # define         X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT          18
 # define         X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN            19
 # define         X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY    20
 # define         X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE      21
 # define         X509_V_ERR_CERT_CHAIN_TOO_LONG                  22
 # define         X509_V_ERR_CERT_REVOKED                         23
 # define         X509_V_ERR_INVALID_CA                           24
 # define         X509_V_ERR_PATH_LENGTH_EXCEEDED                 25
 # define         X509_V_ERR_INVALID_PURPOSE                      26
 # define         X509_V_ERR_CERT_UNTRUSTED                       27
 # define         X509_V_ERR_CERT_REJECTED                        28
 /* These are 'informational' when looking for issuer cert */
 # define         X509_V_ERR_SUBJECT_ISSUER_MISMATCH              29
 # define         X509_V_ERR_AKID_SKID_MISMATCH                   30
 # define         X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH          31
 # define         X509_V_ERR_KEYUSAGE_NO_CERTSIGN                 32
 
 # define         X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER             33
 # define         X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION         34
 # define         X509_V_ERR_KEYUSAGE_NO_CRL_SIGN                 35
 # define         X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION     36
 # define         X509_V_ERR_INVALID_NON_CA                       37
 # define         X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED           38
 # define         X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE        39
 # define         X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED       40
 
 # define         X509_V_ERR_INVALID_EXTENSION                    41
 # define         X509_V_ERR_INVALID_POLICY_EXTENSION             42
 # define         X509_V_ERR_NO_EXPLICIT_POLICY                   43
 # define         X509_V_ERR_DIFFERENT_CRL_SCOPE                  44
 # define         X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE        45
 
 # define         X509_V_ERR_UNNESTED_RESOURCE                    46
 
 # define         X509_V_ERR_PERMITTED_VIOLATION                  47
 # define         X509_V_ERR_EXCLUDED_VIOLATION                   48
 # define         X509_V_ERR_SUBTREE_MINMAX                       49
+# define         X509_V_ERR_APPLICATION_VERIFICATION             50
 # define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE          51
 # define         X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX        52
 # define         X509_V_ERR_UNSUPPORTED_NAME_SYNTAX              53
 # define         X509_V_ERR_CRL_PATH_VALIDATION_ERROR            54
 
-/* The application is not happy */
-# define         X509_V_ERR_APPLICATION_VERIFICATION             50
+# if 0 /* Reserved for compatibility 1.0.2 */
+/* Suite B mode algorithm violation */
+#  define         X509_V_ERR_SUITE_B_INVALID_VERSION              56
+#  define         X509_V_ERR_SUITE_B_INVALID_ALGORITHM            57
+#  define         X509_V_ERR_SUITE_B_INVALID_CURVE                58
+#  define         X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM  59
+#  define         X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED              60
+#  define         X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+
+/* Host, email and IP check errors */
+#  define         X509_V_ERR_HOSTNAME_MISMATCH                    62
+#  define         X509_V_ERR_EMAIL_MISMATCH                       63
+#  define         X509_V_ERR_IP_ADDRESS_MISMATCH                  64
+# endif
+
+/* Caller error */
+# define         X509_V_ERR_INVALID_CALL                         65
+/* Issuer lookup error */
+# define         X509_V_ERR_STORE_LOOKUP                         66
+
+# define         X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION         67
 
 /* Certificate verify flags */
 
 /* Send issuer+subject checks to verify_cb */
 # define X509_V_FLAG_CB_ISSUER_CHECK             0x1
 /* Use check time instead of current time */
 # define X509_V_FLAG_USE_CHECK_TIME              0x2
 /* Lookup CRLs */
 # define X509_V_FLAG_CRL_CHECK                   0x4
 /* Lookup CRLs for whole chain */
 # define X509_V_FLAG_CRL_CHECK_ALL               0x8
 /* Ignore unhandled critical extensions */
 # define X509_V_FLAG_IGNORE_CRITICAL             0x10
 /* Disable workarounds for broken certificates */
 # define X509_V_FLAG_X509_STRICT                 0x20
 /* Enable proxy certificate validation */
 # define X509_V_FLAG_ALLOW_PROXY_CERTS           0x40
 /* Enable policy checking */
 # define X509_V_FLAG_POLICY_CHECK                0x80
 /* Policy variable require-explicit-policy */
 # define X509_V_FLAG_EXPLICIT_POLICY             0x100
 /* Policy variable inhibit-any-policy */
 # define X509_V_FLAG_INHIBIT_ANY                 0x200
 /* Policy variable inhibit-policy-mapping */
 # define X509_V_FLAG_INHIBIT_MAP                 0x400
 /* Notify callback that policy is OK */
 # define X509_V_FLAG_NOTIFY_POLICY               0x800
 /* Extended CRL features such as indirect CRLs, alternate CRL signing keys */
 # define X509_V_FLAG_EXTENDED_CRL_SUPPORT        0x1000
 /* Delta CRL support */
 # define X509_V_FLAG_USE_DELTAS                  0x2000
 /* Check selfsigned CA signature */
 # define X509_V_FLAG_CHECK_SS_SIGNATURE          0x4000
 /*
  * If the initial chain is not trusted, do not attempt to build an alternative
  * chain. Alternate chain checking was introduced in 1.0.1n/1.0.2b. Setting
  * this flag will force the behaviour to match that of previous versions.
  */
 # define X509_V_FLAG_NO_ALT_CHAINS               0x100000
 
 # define X509_VP_FLAG_DEFAULT                    0x1
 # define X509_VP_FLAG_OVERWRITE                  0x2
 # define X509_VP_FLAG_RESET_FLAGS                0x4
 # define X509_VP_FLAG_LOCKED                     0x8
 # define X509_VP_FLAG_ONCE                       0x10
 
 /* Internal use: mask of policy related options */
 # define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \
                                 | X509_V_FLAG_EXPLICIT_POLICY \
                                 | X509_V_FLAG_INHIBIT_ANY \
                                 | X509_V_FLAG_INHIBIT_MAP)
 
 int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type,
                                X509_NAME *name);
 X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,
                                              int type, X509_NAME *name);
 X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h,
                                         X509_OBJECT *x);
 void X509_OBJECT_up_ref_count(X509_OBJECT *a);
 void X509_OBJECT_free_contents(X509_OBJECT *a);
 X509_STORE *X509_STORE_new(void);
 void X509_STORE_free(X509_STORE *v);
 
 STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm);
 STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm);
 int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags);
 int X509_STORE_set_purpose(X509_STORE *ctx, int purpose);
 int X509_STORE_set_trust(X509_STORE *ctx, int trust);
 int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm);
 
 void X509_STORE_set_verify_cb(X509_STORE *ctx,
                               int (*verify_cb) (int, X509_STORE_CTX *));
 
 X509_STORE_CTX *X509_STORE_CTX_new(void);
 
 int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x);
 
 void X509_STORE_CTX_free(X509_STORE_CTX *ctx);
 int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store,
                         X509 *x509, STACK_OF(X509) *chain);
 void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk);
 void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx);
 
 X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m);
 
 X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void);
 X509_LOOKUP_METHOD *X509_LOOKUP_file(void);
 
 int X509_STORE_add_cert(X509_STORE *ctx, X509 *x);
 int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x);
 
 int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name,
                               X509_OBJECT *ret);
 
 int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc,
                      long argl, char **ret);
 
 # ifndef OPENSSL_NO_STDIO
 int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type);
 int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type);
 int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type);
 # endif
 
 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method);
 void X509_LOOKUP_free(X509_LOOKUP *ctx);
 int X509_LOOKUP_init(X509_LOOKUP *ctx);
 int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name,
                            X509_OBJECT *ret);
 int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name,
                                  ASN1_INTEGER *serial, X509_OBJECT *ret);
 int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type,
                                unsigned char *bytes, int len,
                                X509_OBJECT *ret);
 int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len,
                          X509_OBJECT *ret);
 int X509_LOOKUP_shutdown(X509_LOOKUP *ctx);
 
 # ifndef OPENSSL_NO_STDIO
 int X509_STORE_load_locations(X509_STORE *ctx,
                               const char *file, const char *dir);
 int X509_STORE_set_default_paths(X509_STORE *ctx);
 # endif
 
 int X509_STORE_CTX_get_ex_new_index(long argl, void *argp,
                                     CRYPTO_EX_new *new_func,
                                     CRYPTO_EX_dup *dup_func,
                                     CRYPTO_EX_free *free_func);
 int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data);
 void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx);
 int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx);
 void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s);
 int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx);
 X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx);
 X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx);
 X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx);
 X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
 STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx);
 void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x);
 void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk);
 void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk);
 int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose);
 int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust);
 int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
                                    int purpose, int trust);
 void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags);
 void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags,
                              time_t t);
 void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx,
                                   int (*verify_cb) (int, X509_STORE_CTX *));
 
 X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx);
 int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx);
 
 X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx);
 void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param);
 int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name);
 
 /* X509_VERIFY_PARAM functions */
 
 X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void);
 void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param);
 int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to,
                               const X509_VERIFY_PARAM *from);
 int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
                            const X509_VERIFY_PARAM *from);
 int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name);
 int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param,
                                 unsigned long flags);
 int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param,
                                   unsigned long flags);
 unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param);
 int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose);
 int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust);
 void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth);
 void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t);
 int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
                                   ASN1_OBJECT *policy);
 int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
                                     STACK_OF(ASN1_OBJECT) *policies);
 int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);
 
 int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
 const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name);
 void X509_VERIFY_PARAM_table_cleanup(void);
 
 int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy,
                       STACK_OF(X509) *certs,
                       STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags);
 
 void X509_policy_tree_free(X509_POLICY_TREE *tree);
 
 int X509_policy_tree_level_count(const X509_POLICY_TREE *tree);
 X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree,
                                                int i);
 
 STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const
                                                            X509_POLICY_TREE
                                                            *tree);
 
 STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const
                                                                 X509_POLICY_TREE
                                                                 *tree);
 
 int X509_policy_level_node_count(X509_POLICY_LEVEL *level);
 
 X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level,
                                               int i);
 
 const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node);
 
 STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const
                                                            X509_POLICY_NODE
                                                            *node);
 const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE
                                                      *node);
 
 #ifdef  __cplusplus
 }
 #endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/crypto/x509v3/v3_addr.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/crypto/x509v3/v3_addr.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/crypto/x509v3/v3_addr.c	(revision 306191)
@@ -1,1344 +1,1350 @@
 /*
  * 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 int addr_expand(unsigned char *addr,
                        const ASN1_BIT_STRING *bs,
                        const int length, const unsigned char fill)
 {
     if (bs->length < 0 || bs->length > length)
         return 0;
     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);
     return 1;
 }
 
 /*
  * 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 (!addr_expand(addr, bs, 4, fill))
             return 0;
         BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
         break;
     case IANA_AFI_IPV6:
         if (!addr_expand(addr, bs, 16, fill))
             return 0;
         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.
  *
  * There's no sane answer we can give if addr_expand() fails, and an
  * assertion failure on externally supplied data is seriously uncool,
  * so we just arbitrarily declare that if given invalid inputs this
  * function returns -1.  If this messes up your preferred sort order
  * for garbage input, tough noogies.
  */
 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:
         if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00))
             return -1;
         prefixlen_a = addr_prefixlen(a->u.addressPrefix);
         break;
     case IPAddressOrRange_addressRange:
         if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00))
             return -1;
         prefixlen_a = length * 8;
         break;
     }
 
     switch (b->type) {
     case IPAddressOrRange_addressPrefix:
         if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00))
             return -1;
         prefixlen_b = addr_prefixlen(b->u.addressPrefix);
         break;
     case IPAddressOrRange_addressRange:
         if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00))
             return -1;
         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;
 
     OPENSSL_assert(memcmp(min, max, length) <= 0);
     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:
         (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp);
         break;
     case IANA_AFI_IPV6:
         (void)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 int extract_min_max(IPAddressOrRange *aor,
                            unsigned char *min, unsigned char *max, int length)
 {
     if (aor == NULL || min == NULL || max == NULL)
         return 0;
     switch (aor->type) {
     case IPAddressOrRange_addressPrefix:
         return (addr_expand(min, aor->u.addressPrefix, length, 0x00) &&
                 addr_expand(max, aor->u.addressPrefix, length, 0xFF));
     case IPAddressOrRange_addressRange:
         return (addr_expand(min, aor->u.addressRange->min, length, 0x00) &&
                 addr_expand(max, aor->u.addressRange->max, length, 0xFF));
     }
     return 0;
 }
 
 /*
  * 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) ||
         !extract_min_max(aor, min, max, afi_length))
         return 0;
 
     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);
 
             if (!extract_min_max(a, a_min, a_max, length) ||
                 !extract_min_max(b, b_min, b_max, length))
                 return 0;
 
             /*
              * 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 range to see if it's inverted or should be a
          * prefix.
          */
         j = sk_IPAddressOrRange_num(aors) - 1;
         {
             IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
             if (a != NULL && a->type == IPAddressOrRange_addressRange) {
                 if (!extract_min_max(a, a_min, a_max, length))
                     return 0;
                 if (memcmp(a_min, a_max, length) > 0 ||
                     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];
 
         if (!extract_min_max(a, a_min, a_max, length) ||
             !extract_min_max(b, b_min, b_max, length))
             return 0;
 
         /*
          * Punt inverted ranges.
          */
         if (memcmp(a_min, a_max, length) > 0 ||
             memcmp(b_min, b_max, length) > 0)
             return 0;
 
         /*
          * 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;
             (void)sk_IPAddressOrRange_set(aors, i, merged);
             (void)sk_IPAddressOrRange_delete(aors, i + 1);
             IPAddressOrRange_free(a);
             IPAddressOrRange_free(b);
             --i;
             continue;
         }
     }
 
     /*
      * Check for inverted final range.
      */
     j = sk_IPAddressOrRange_num(aors) - 1;
     {
         IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j);
         if (a != NULL && a->type == IPAddressOrRange_addressRange) {
             unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN];
             extract_min_max(a, a_min, a_max, length);
             if (memcmp(a_min, a_max, length) > 0)
                 return 0;
         }
     }
 
     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;
     }
     (void)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 (memcmp(min, max, length_from_afi(afi)) > 0) {
                 X509V3err(X509V3_F_V2I_IPADDRBLOCKS,
                           X509V3_R_EXTENSION_VALUE_ERROR);
                 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++) {
         if (!extract_min_max(sk_IPAddressOrRange_value(child, c),
                              c_min, c_max, length))
             return -1;
         for (;; p++) {
             if (p >= sk_IPAddressOrRange_num(parent))
                 return 0;
             if (!extract_min_max(sk_IPAddressOrRange_value(parent, p),
                                  p_min, p_max, length))
                 return 0;
             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;
     (void)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.
+ *
+ * Returns 1 for success, 0 on error.
+ *
+ * When returning 0, ctx->error MUST be set to an appropriate value other than
+ * X509_V_OK.
  */
 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);
     (void)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);
+        ctx->error = X509_V_ERR_OUT_OF_MEM;
         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;
         }
         (void)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 */
Index: vendor-crypto/openssl/dist-1.0.1/doc/apps/cms.pod
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/doc/apps/cms.pod	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/doc/apps/cms.pod	(revision 306191)
@@ -1,620 +1,623 @@
 =pod
 
 =head1 NAME
 
 cms - CMS utility
 
 =head1 SYNOPSIS
 
 B<openssl> B<cms>
 [B<-encrypt>]
 [B<-decrypt>]
 [B<-sign>]
 [B<-verify>]
 [B<-cmsout>]
 [B<-resign>]
 [B<-data_create>]
 [B<-data_out>]
 [B<-digest_create>]
 [B<-digest_verify>]
 [B<-compress>]
 [B<-uncompress>]
 [B<-EncryptedData_encrypt>]
 [B<-sign_receipt>]
 [B<-verify_receipt receipt>]
 [B<-in filename>]
 [B<-inform SMIME|PEM|DER>]
 [B<-rctform SMIME|PEM|DER>]
 [B<-out filename>]
 [B<-outform SMIME|PEM|DER>]
 [B<-stream -indef -noindef>]
 [B<-noindef>]
 [B<-content filename>]
 [B<-text>]
 [B<-noout>]
 [B<-print>]
 [B<-CAfile file>]
 [B<-CApath dir>]
 [B<-no_alt_chains>]
 [B<-md digest>]
 [B<-[cipher]>]
 [B<-nointern>]
 [B<-no_signer_cert_verify>]
 [B<-nocerts>]
 [B<-noattr>]
 [B<-nosmimecap>]
 [B<-binary>]
 [B<-nodetach>]
 [B<-certfile file>]
 [B<-certsout file>]
 [B<-signer file>]
 [B<-recip file>]
 [B<-keyid>]
 [B<-receipt_request_all -receipt_request_first>]
 [B<-receipt_request_from emailaddress>]
 [B<-receipt_request_to emailaddress>]
 [B<-receipt_request_print>]
 [B<-secretkey key>]
 [B<-secretkeyid id>]
 [B<-econtent_type type>]
 [B<-inkey file>]
 [B<-passin arg>]
 [B<-rand file(s)>]
 [B<cert.pem...>]
 [B<-to addr>]
 [B<-from addr>]
 [B<-subject subj>]
 [cert.pem]...
 
 =head1 DESCRIPTION
 
 The B<cms> command handles S/MIME v3.1 mail. It can encrypt, decrypt, sign and
 verify, compress and uncompress S/MIME messages.
 
 =head1 COMMAND OPTIONS
 
 There are fourteen operation options that set the type of operation to be
 performed. The meaning of the other options varies according to the operation
 type.
 
 =over 4
 
 =item B<-encrypt>
 
 encrypt mail for the given recipient certificates. Input file is the message
 to be encrypted. The output file is the encrypted mail in MIME format. The
 actual CMS type is <B>EnvelopedData<B>.
 
+Note that no revocation check is done for the recipient cert, so if that
+key has been compromised, others may be able to decrypt the text.
+
 =item B<-decrypt>
 
 decrypt mail using the supplied certificate and private key. Expects an
 encrypted mail message in MIME format for the input file. The decrypted mail
 is written to the output file.
 
 =item B<-debug_decrypt>
 
 this option sets the B<CMS_DEBUG_DECRYPT> flag. This option should be used
 with caution: see the notes section below.
 
 =item B<-sign>
 
 sign mail using the supplied certificate and private key. Input file is
 the message to be signed. The signed message in MIME format is written
 to the output file.
 
 =item B<-verify>
 
 verify signed mail. Expects a signed mail message on input and outputs
 the signed data. Both clear text and opaque signing is supported.
 
 =item B<-cmsout>
 
 takes an input message and writes out a PEM encoded CMS structure.
 
 =item B<-resign>
 
 resign a message: take an existing message and one or more new signers.
 
 =item B<-data_create>
 
 Create a CMS B<Data> type.
 
 =item B<-data_out>
 
 B<Data> type and output the content.
 
 =item B<-digest_create>
 
 Create a CMS B<DigestedData> type.
 
 =item B<-digest_verify>
 
 Verify a CMS B<DigestedData> type and output the content.
 
 =item B<-compress>
 
 Create a CMS B<CompressedData> type. OpenSSL must be compiled with B<zlib>
 support for this option to work, otherwise it will output an error.
 
 =item B<-uncompress>
 
 Uncompress a CMS B<CompressedData> type and output the content. OpenSSL must be
 compiled with B<zlib> support for this option to work, otherwise it will
 output an error.
 
 =item B<-EncryptedData_encrypt>
 
 Encrypt content using supplied symmetric key and algorithm using a CMS
 B<EncrytedData> type and output the content.
 
 =item B<-sign_receipt>
 
 Generate and output a signed receipt for the supplied message. The input 
 message B<must> contain a signed receipt request. Functionality is otherwise
 similar to the B<-sign> operation.
 
 =item B<-verify_receipt receipt>
 
 Verify a signed receipt in filename B<receipt>. The input message B<must> 
 contain the original receipt request. Functionality is otherwise similar
 to the B<-verify> operation.
 
 =item B<-in filename>
 
 the input message to be encrypted or signed or the message to be decrypted
 or verified.
 
 =item B<-inform SMIME|PEM|DER>
 
 this specifies the input format for the CMS structure. The default
 is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
 format change this to expect PEM and DER format CMS structures
 instead. This currently only affects the input format of the CMS
 structure, if no CMS structure is being input (for example with
 B<-encrypt> or B<-sign>) this option has no effect.
 
 =item B<-rctform SMIME|PEM|DER>
 
 specify the format for a signed receipt for use with the B<-receipt_verify>
 operation.
 
 =item B<-out filename>
 
 the message text that has been decrypted or verified or the output MIME
 format message that has been signed or verified.
 
 =item B<-outform SMIME|PEM|DER>
 
 this specifies the output format for the CMS structure. The default
 is B<SMIME> which writes an S/MIME format message. B<PEM> and B<DER>
 format change this to write PEM and DER format CMS structures
 instead. This currently only affects the output format of the CMS
 structure, if no CMS structure is being output (for example with
 B<-verify> or B<-decrypt>) this option has no effect.
 
 =item B<-stream -indef -noindef>
 
 the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
 for encoding operations. This permits single pass processing of data without
 the need to hold the entire contents in memory, potentially supporting very
 large files. Streaming is automatically set for S/MIME signing with detached
 data if the output format is B<SMIME> it is currently off by default for all
 other operations.
 
 =item B<-noindef>
 
 disable streaming I/O where it would produce and indefinite length constructed
 encoding. This option currently has no effect. In future streaming will be
 enabled by default on all relevant operations and this option will disable it.
 
 =item B<-content filename>
 
 This specifies a file containing the detached content, this is only
 useful with the B<-verify> command. This is only usable if the CMS
 structure is using the detached signature form where the content is
 not included. This option will override any content if the input format
 is S/MIME and it uses the multipart/signed MIME content type.
 
 =item B<-text>
 
 this option adds plain text (text/plain) MIME headers to the supplied
 message if encrypting or signing. If decrypting or verifying it strips
 off text headers: if the decrypted or verified message is not of MIME 
 type text/plain then an error occurs.
 
 =item B<-noout>
 
 for the B<-cmsout> operation do not output the parsed CMS structure. This
 is useful when combined with the B<-print> option or if the syntax of the CMS
 structure is being checked.
 
 =item B<-print>
 
 for the B<-cmsout> operation print out all fields of the CMS structure. This
 is mainly useful for testing purposes.
 
 =item B<-CAfile file>
 
 a file containing trusted CA certificates, only used with B<-verify>.
 
 =item B<-CApath dir>
 
 a directory containing trusted CA certificates, only used with
 B<-verify>. This directory must be a standard certificate directory: that
 is a hash of each subject name (using B<x509 -hash>) should be linked
 to each certificate.
 
 =item B<-md digest>
 
 digest algorithm to use when signing or resigning. If not present then the
 default digest algorithm for the signing key will be used (usually SHA1).
 
 =item B<-[cipher]>
 
 the encryption algorithm to use. For example triple DES (168 bits) - B<-des3>
 or 256 bit AES - B<-aes256>. Any standard algorithm name (as used by the
 EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
 example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for a list of ciphers
 supported by your version of OpenSSL.
 
 If not specified triple DES is used. Only used with B<-encrypt> and 
 B<-EncryptedData_create> commands.
 
 =item B<-nointern>
 
 when verifying a message normally certificates (if any) included in
 the message are searched for the signing certificate. With this option
 only the certificates specified in the B<-certfile> option are used.
 The supplied certificates can still be used as untrusted CAs however.
 
 =item B<-no_signer_cert_verify>
 
 do not verify the signers certificate of a signed message.
 
 =item B<-nocerts>
 
 when signing a message the signer's certificate is normally included
 with this option it is excluded. This will reduce the size of the
 signed message but the verifier must have a copy of the signers certificate
 available locally (passed using the B<-certfile> option for example).
 
 =item B<-noattr>
 
 normally when a message is signed a set of attributes are included which
 include the signing time and supported symmetric algorithms. With this
 option they are not included.
 
 =item B<-nosmimecap>
 
 exclude the list of supported algorithms from signed attributes, other options
 such as signing time and content type are still included.
 
 =item B<-binary>
 
 normally the input message is converted to "canonical" format which is
 effectively using CR and LF as end of line: as required by the S/MIME
 specification. When this option is present no translation occurs. This
 is useful when handling binary data which may not be in MIME format.
 
 =item B<-nodetach>
 
 when signing a message use opaque signing: this form is more resistant
 to translation by mail relays but it cannot be read by mail agents that
 do not support S/MIME.  Without this option cleartext signing with
 the MIME type multipart/signed is used.
 
 =item B<-certfile file>
 
 allows additional certificates to be specified. When signing these will
 be included with the message. When verifying these will be searched for
 the signers certificates. The certificates should be in PEM format.
 
 =item B<-certsout file>
 
 any certificates contained in the message are written to B<file>.
 
 =item B<-signer file>
 
 a signing certificate when signing or resigning a message, this option can be
 used multiple times if more than one signer is required. If a message is being
 verified then the signers certificates will be written to this file if the
 verification was successful.
 
 =item B<-recip file>
 
 the recipients certificate when decrypting a message. This certificate
 must match one of the recipients of the message or an error occurs.
 
 =item B<-keyid>
 
 use subject key identifier to identify certificates instead of issuer name and
 serial number. The supplied certificate B<must> include a subject key
 identifier extension. Supported by B<-sign> and B<-encrypt> options.
 
 =item B<-receipt_request_all -receipt_request_first>
 
 for B<-sign> option include a signed receipt request. Indicate requests should
 be provided by all receipient or first tier recipients (those mailed directly
 and not from a mailing list). Ignored it B<-receipt_request_from> is included.
 
 =item B<-receipt_request_from emailaddress>
 
 for B<-sign> option include a signed receipt request. Add an explicit email
 address where receipts should be supplied.
 
 =item B<-receipt_request_to emailaddress>
 
 Add an explicit email address where signed receipts should be sent to. This 
 option B<must> but supplied if a signed receipt it requested.
 
 =item B<-receipt_request_print>
 
 For the B<-verify> operation print out the contents of any signed receipt
 requests.
 
 =item B<-secretkey key>
 
 specify symmetric key to use. The key must be supplied in hex format and be
 consistent with the algorithm used. Supported by the B<-EncryptedData_encrypt>
 B<-EncrryptedData_decrypt>, B<-encrypt> and B<-decrypt> options. When used
 with B<-encrypt> or B<-decrypt> the supplied key is used to wrap or unwrap the
 content encryption key using an AES key in the B<KEKRecipientInfo> type.
 
 =item B<-secretkeyid id>
 
 the key identifier for the supplied symmetric key for B<KEKRecipientInfo> type.
 This option B<must> be present if the B<-secretkey> option is used with
 B<-encrypt>. With B<-decrypt> operations the B<id> is used to locate the
 relevant key if it is not supplied then an attempt is used to decrypt any
 B<KEKRecipientInfo> structures.
 
 =item B<-econtent_type type>
 
 set the encapsulated content type to B<type> if not supplied the B<Data> type
 is used. The B<type> argument can be any valid OID name in either text or
 numerical format. 
 
 =item B<-inkey file>
 
 the private key to use when signing or decrypting. This must match the
 corresponding certificate. If this option is not specified then the
 private key must be included in the certificate file specified with
 the B<-recip> or B<-signer> file. When signing this option can be used
 multiple times to specify successive keys.
 
 =item B<-passin arg>
 
 the private key password source. For more information about the format of B<arg>
 see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
 
 =item B<-rand file(s)>
 
 a file or files containing random data used to seed the random number
 generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
 Multiple files can be specified separated by a OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
 =item B<cert.pem...>
 
 one or more certificates of message recipients: used when encrypting
 a message. 
 
 =item B<-to, -from, -subject>
 
 the relevant mail headers. These are included outside the signed
 portion of a message so they may be included manually. If signing
 then many S/MIME mail clients check the signers certificate's email
 address matches that specified in the From: address.
 
 =item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
 
 Set various certificate chain valiadition option. See the
 L<B<verify>|verify(1)> manual page for details.
 
 =back
 
 =head1 NOTES
 
 The MIME message must be sent without any blank lines between the
 headers and the output. Some mail programs will automatically add
 a blank line. Piping the mail directly to sendmail is one way to
 achieve the correct format.
 
 The supplied message to be signed or encrypted must include the
 necessary MIME headers or many S/MIME clients wont display it
 properly (if at all). You can use the B<-text> option to automatically
 add plain text headers.
 
 A "signed and encrypted" message is one where a signed message is
 then encrypted. This can be produced by encrypting an already signed
 message: see the examples section.
 
 This version of the program only allows one signer per message but it
 will verify multiple signers on received messages. Some S/MIME clients
 choke if a message contains multiple signers. It is possible to sign
 messages "in parallel" by signing an already signed message.
 
 The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
 clients. Strictly speaking these process CMS enveloped data: CMS
 encrypted data is used for other purposes.
 
 The B<-resign> option uses an existing message digest when adding a new
 signer. This means that attributes must be present in at least one existing
 signer using the same message digest or this operation will fail.
 
 The B<-stream> and B<-indef> options enable experimental streaming I/O support.
 As a result the encoding is BER using indefinite length constructed encoding
 and no longer DER. Streaming is supported for the B<-encrypt> operation and the
 B<-sign> operation if the content is not detached.
 
 Streaming is always used for the B<-sign> operation with detached data but
 since the content is no longer part of the CMS structure the encoding
 remains DER.
 
 If the B<-decrypt> option is used without a recipient certificate then an
 attempt is made to locate the recipient by trying each potential recipient
 in turn using the supplied private key. To thwart the MMA attack
 (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) all recipients are
 tried whether they succeed or not and if no recipients match the message
 is "decrypted" using a random key which will typically output garbage. 
 The B<-debug_decrypt> option can be used to disable the MMA attack protection
 and return an error if no recipient can be found: this option should be used
 with caution. For a fuller description see L<CMS_decrypt(3)|CMS_decrypt(3)>).
 
 =head1 EXIT CODES
 
 =over 4
 
 =item Z<>0
 
 the operation was completely successfully.
 
 =item Z<>1
 
 an error occurred parsing the command options.
 
 =item Z<>2
 
 one of the input files could not be read.
 
 =item Z<>3
 
 an error occurred creating the CMS file or when reading the MIME
 message.
 
 =item Z<>4
 
 an error occurred decrypting or verifying the message.
 
 =item Z<>5
 
 the message was verified correctly but an error occurred writing out
 the signers certificates.
 
 =back
 
 =head1 COMPATIBILITY WITH PKCS#7 format.
 
 The B<smime> utility can only process the older B<PKCS#7> format. The B<cms>
 utility supports Cryptographic Message Syntax format. Use of some features
 will result in messages which cannot be processed by applications which only
 support the older format. These are detailed below.
 
 The use of the B<-keyid> option with B<-sign> or B<-encrypt>.
 
 The B<-outform PEM> option uses different headers.
 
 The B<-compress> option.
 
 The B<-secretkey> option when used with B<-encrypt>.
 
 Additionally the B<-EncryptedData_create> and B<-data_create> type cannot
 be processed by the older B<smime> command.
 
 =head1 EXAMPLES
 
 Create a cleartext signed message:
 
  openssl cms -sign -in message.txt -text -out mail.msg \
 	-signer mycert.pem
 
 Create an opaque signed message
 
  openssl cms -sign -in message.txt -text -out mail.msg -nodetach \
 	-signer mycert.pem
 
 Create a signed message, include some additional certificates and
 read the private key from another file:
 
  openssl cms -sign -in in.txt -text -out mail.msg \
 	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
 
 Create a signed message with two signers, use key identifier:
 
  openssl cms -sign -in message.txt -text -out mail.msg \
 	-signer mycert.pem -signer othercert.pem -keyid
 
 Send a signed message under Unix directly to sendmail, including headers:
 
  openssl cms -sign -in in.txt -text -signer mycert.pem \
 	-from steve@openssl.org -to someone@somewhere \
 	-subject "Signed message" | sendmail someone@somewhere
 
 Verify a message and extract the signer's certificate if successful:
 
  openssl cms -verify -in mail.msg -signer user.pem -out signedtext.txt
 
 Send encrypted mail using triple DES:
 
  openssl cms -encrypt -in in.txt -from steve@openssl.org \
 	-to someone@somewhere -subject "Encrypted message" \
 	-des3 user.pem -out mail.msg
 
 Sign and encrypt mail:
 
  openssl cms -sign -in ml.txt -signer my.pem -text \
 	| openssl cms -encrypt -out mail.msg \
 	-from steve@openssl.org -to someone@somewhere \
 	-subject "Signed and Encrypted message" -des3 user.pem
 
 Note: the encryption command does not include the B<-text> option because the
 message being encrypted already has MIME headers.
 
 Decrypt mail:
 
  openssl cms -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
 
 The output from Netscape form signing is a PKCS#7 structure with the
 detached signature format. You can use this program to verify the
 signature by line wrapping the base64 encoded structure and surrounding
 it with:
 
  -----BEGIN PKCS7-----
  -----END PKCS7-----
 
 and using the command, 
 
  openssl cms -verify -inform PEM -in signature.pem -content content.txt
 
 alternatively you can base64 decode the signature and use
 
  openssl cms -verify -inform DER -in signature.der -content content.txt
 
 Create an encrypted message using 128 bit Camellia:
 
  openssl cms -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
 
 Add a signer to an existing message:
 
  openssl cms -resign -in mail.msg -signer newsign.pem -out mail2.msg
 
 =head1 BUGS
 
 The MIME parser isn't very clever: it seems to handle most messages that I've
 thrown at it but it may choke on others.
 
 The code currently will only write out the signer's certificate to a file: if
 the signer has a separate encryption certificate this must be manually
 extracted. There should be some heuristic that determines the correct
 encryption certificate.
 
 Ideally a database should be maintained of a certificates for each email
 address.
 
 The code doesn't currently take note of the permitted symmetric encryption
 algorithms as supplied in the SMIMECapabilities signed attribute. this means the
 user has to manually include the correct encryption algorithm. It should store
 the list of permitted ciphers in a database and only use those.
 
 No revocation checking is done on the signer's certificate.
 
 =head1 HISTORY
 
 The use of multiple B<-signer> options and the B<-resign> command were first
 added in OpenSSL 1.0.0
 
 
 The -no_alt_chains options was first added to OpenSSL 1.0.1n and 1.0.2b.
 
 =cut
Index: vendor-crypto/openssl/dist-1.0.1/doc/apps/smime.pod
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/doc/apps/smime.pod	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/doc/apps/smime.pod	(revision 306191)
@@ -1,447 +1,450 @@
 =pod
 
 =head1 NAME
 
 smime - S/MIME utility
 
 =head1 SYNOPSIS
 
 B<openssl> B<smime>
 [B<-encrypt>]
 [B<-decrypt>]
 [B<-sign>]
 [B<-resign>]
 [B<-verify>]
 [B<-pk7out>]
 [B<-[cipher]>]
 [B<-in file>]
 [B<-no_alt_chains>]
 [B<-certfile file>]
 [B<-signer file>]
 [B<-recip  file>]
 [B<-inform SMIME|PEM|DER>]
 [B<-passin arg>]
 [B<-inkey file>]
 [B<-out file>]
 [B<-outform SMIME|PEM|DER>]
 [B<-content file>]
 [B<-to addr>]
 [B<-from ad>]
 [B<-subject s>]
 [B<-text>]
 [B<-indef>]
 [B<-noindef>]
 [B<-stream>]
 [B<-rand file(s)>]
 [B<-md digest>]
 [cert.pem]...
 
 =head1 DESCRIPTION
 
 The B<smime> command handles S/MIME mail. It can encrypt, decrypt, sign and
 verify S/MIME messages.
 
 =head1 COMMAND OPTIONS
 
 There are six operation options that set the type of operation to be performed.
 The meaning of the other options varies according to the operation type.
 
 =over 4
 
 =item B<-encrypt>
 
 encrypt mail for the given recipient certificates. Input file is the message
 to be encrypted. The output file is the encrypted mail in MIME format.
 
+Note that no revocation check is done for the recipient cert, so if that
+key has been compromised, others may be able to decrypt the text.
+
 =item B<-decrypt>
 
 decrypt mail using the supplied certificate and private key. Expects an
 encrypted mail message in MIME format for the input file. The decrypted mail
 is written to the output file.
 
 =item B<-sign>
 
 sign mail using the supplied certificate and private key. Input file is
 the message to be signed. The signed message in MIME format is written
 to the output file.
 
 =item B<-verify>
 
 verify signed mail. Expects a signed mail message on input and outputs
 the signed data. Both clear text and opaque signing is supported.
 
 =item B<-pk7out>
 
 takes an input message and writes out a PEM encoded PKCS#7 structure.
 
 =item B<-resign>
 
 resign a message: take an existing message and one or more new signers.
 
 =item B<-in filename>
 
 the input message to be encrypted or signed or the MIME message to
 be decrypted or verified.
 
 =item B<-inform SMIME|PEM|DER>
 
 this specifies the input format for the PKCS#7 structure. The default
 is B<SMIME> which reads an S/MIME format message. B<PEM> and B<DER>
 format change this to expect PEM and DER format PKCS#7 structures
 instead. This currently only affects the input format of the PKCS#7
 structure, if no PKCS#7 structure is being input (for example with
 B<-encrypt> or B<-sign>) this option has no effect.
 
 =item B<-out filename>
 
 the message text that has been decrypted or verified or the output MIME
 format message that has been signed or verified.
 
 =item B<-outform SMIME|PEM|DER>
 
 this specifies the output format for the PKCS#7 structure. The default
 is B<SMIME> which write an S/MIME format message. B<PEM> and B<DER>
 format change this to write PEM and DER format PKCS#7 structures
 instead. This currently only affects the output format of the PKCS#7
 structure, if no PKCS#7 structure is being output (for example with
 B<-verify> or B<-decrypt>) this option has no effect.
 
 =item B<-stream -indef -noindef>
 
 the B<-stream> and B<-indef> options are equivalent and enable streaming I/O
 for encoding operations. This permits single pass processing of data without
 the need to hold the entire contents in memory, potentially supporting very
 large files. Streaming is automatically set for S/MIME signing with detached
 data if the output format is B<SMIME> it is currently off by default for all
 other operations.
 
 =item B<-noindef>
 
 disable streaming I/O where it would produce and indefinite length constructed
 encoding. This option currently has no effect. In future streaming will be
 enabled by default on all relevant operations and this option will disable it.
 
 =item B<-content filename>
 
 This specifies a file containing the detached content, this is only
 useful with the B<-verify> command. This is only usable if the PKCS#7
 structure is using the detached signature form where the content is
 not included. This option will override any content if the input format
 is S/MIME and it uses the multipart/signed MIME content type.
 
 =item B<-text>
 
 this option adds plain text (text/plain) MIME headers to the supplied
 message if encrypting or signing. If decrypting or verifying it strips
 off text headers: if the decrypted or verified message is not of MIME 
 type text/plain then an error occurs.
 
 =item B<-CAfile file>
 
 a file containing trusted CA certificates, only used with B<-verify>.
 
 =item B<-CApath dir>
 
 a directory containing trusted CA certificates, only used with
 B<-verify>. This directory must be a standard certificate directory: that
 is a hash of each subject name (using B<x509 -hash>) should be linked
 to each certificate.
 
 =item B<-md digest>
 
 digest algorithm to use when signing or resigning. If not present then the
 default digest algorithm for the signing key will be used (usually SHA1).
 
 =item B<-[cipher]>
 
 the encryption algorithm to use. For example DES  (56 bits) - B<-des>,
 triple DES (168 bits) - B<-des3>,
 EVP_get_cipherbyname() function) can also be used preceded by a dash, for 
 example B<-aes_128_cbc>. See L<B<enc>|enc(1)> for list of ciphers
 supported by your version of OpenSSL.
 
 If not specified triple DES is used. Only used with B<-encrypt>.
 
 =item B<-nointern>
 
 when verifying a message normally certificates (if any) included in
 the message are searched for the signing certificate. With this option
 only the certificates specified in the B<-certfile> option are used.
 The supplied certificates can still be used as untrusted CAs however.
 
 =item B<-noverify>
 
 do not verify the signers certificate of a signed message.
 
 =item B<-nochain>
 
 do not do chain verification of signers certificates: that is don't
 use the certificates in the signed message as untrusted CAs.
 
 =item B<-nosigs>
 
 don't try to verify the signatures on the message.
 
 =item B<-nocerts>
 
 when signing a message the signer's certificate is normally included
 with this option it is excluded. This will reduce the size of the
 signed message but the verifier must have a copy of the signers certificate
 available locally (passed using the B<-certfile> option for example).
 
 =item B<-noattr>
 
 normally when a message is signed a set of attributes are included which
 include the signing time and supported symmetric algorithms. With this
 option they are not included.
 
 =item B<-binary>
 
 normally the input message is converted to "canonical" format which is
 effectively using CR and LF as end of line: as required by the S/MIME
 specification. When this option is present no translation occurs. This
 is useful when handling binary data which may not be in MIME format.
 
 =item B<-nodetach>
 
 when signing a message use opaque signing: this form is more resistant
 to translation by mail relays but it cannot be read by mail agents that
 do not support S/MIME.  Without this option cleartext signing with
 the MIME type multipart/signed is used.
 
 =item B<-certfile file>
 
 allows additional certificates to be specified. When signing these will
 be included with the message. When verifying these will be searched for
 the signers certificates. The certificates should be in PEM format.
 
 =item B<-signer file>
 
 a signing certificate when signing or resigning a message, this option can be
 used multiple times if more than one signer is required. If a message is being
 verified then the signers certificates will be written to this file if the
 verification was successful.
 
 =item B<-recip file>
 
 the recipients certificate when decrypting a message. This certificate
 must match one of the recipients of the message or an error occurs.
 
 =item B<-inkey file>
 
 the private key to use when signing or decrypting. This must match the
 corresponding certificate. If this option is not specified then the
 private key must be included in the certificate file specified with
 the B<-recip> or B<-signer> file. When signing this option can be used
 multiple times to specify successive keys.
 
 =item B<-passin arg>
 
 the private key password source. For more information about the format of B<arg>
 see the B<PASS PHRASE ARGUMENTS> section in L<openssl(1)|openssl(1)>.
 
 =item B<-rand file(s)>
 
 a file or files containing random data used to seed the random number
 generator, or an EGD socket (see L<RAND_egd(3)|RAND_egd(3)>).
 Multiple files can be specified separated by a OS-dependent character.
 The separator is B<;> for MS-Windows, B<,> for OpenVMS, and B<:> for
 all others.
 
 =item B<cert.pem...>
 
 one or more certificates of message recipients: used when encrypting
 a message. 
 
 =item B<-to, -from, -subject>
 
 the relevant mail headers. These are included outside the signed
 portion of a message so they may be included manually. If signing
 then many S/MIME mail clients check the signers certificate's email
 address matches that specified in the From: address.
 
 =item B<-purpose, -ignore_critical, -issuer_checks, -crl_check, -crl_check_all, -policy_check, -extended_crl, -x509_strict, -policy -check_ss_sig -no_alt_chains>
 
 Set various options of certificate chain verification. See
 L<B<verify>|verify(1)> manual page for details.
 
 =back
 
 =head1 NOTES
 
 The MIME message must be sent without any blank lines between the
 headers and the output. Some mail programs will automatically add
 a blank line. Piping the mail directly to sendmail is one way to
 achieve the correct format.
 
 The supplied message to be signed or encrypted must include the
 necessary MIME headers or many S/MIME clients wont display it
 properly (if at all). You can use the B<-text> option to automatically
 add plain text headers.
 
 A "signed and encrypted" message is one where a signed message is
 then encrypted. This can be produced by encrypting an already signed
 message: see the examples section.
 
 This version of the program only allows one signer per message but it
 will verify multiple signers on received messages. Some S/MIME clients
 choke if a message contains multiple signers. It is possible to sign
 messages "in parallel" by signing an already signed message.
 
 The options B<-encrypt> and B<-decrypt> reflect common usage in S/MIME
 clients. Strictly speaking these process PKCS#7 enveloped data: PKCS#7
 encrypted data is used for other purposes.
 
 The B<-resign> option uses an existing message digest when adding a new
 signer. This means that attributes must be present in at least one existing
 signer using the same message digest or this operation will fail.
 
 The B<-stream> and B<-indef> options enable experimental streaming I/O support.
 As a result the encoding is BER using indefinite length constructed encoding
 and no longer DER. Streaming is supported for the B<-encrypt> operation and the
 B<-sign> operation if the content is not detached.
 
 Streaming is always used for the B<-sign> operation with detached data but
 since the content is no longer part of the PKCS#7 structure the encoding
 remains DER.
 
 =head1 EXIT CODES
 
 =over 4
 
 =item Z<>0
 
 the operation was completely successfully.
 
 =item Z<>1
 
 an error occurred parsing the command options.
 
 =item Z<>2
 
 one of the input files could not be read.
 
 =item Z<>3
 
 an error occurred creating the PKCS#7 file or when reading the MIME
 message.
 
 =item Z<>4
 
 an error occurred decrypting or verifying the message.
 
 =item Z<>5
 
 the message was verified correctly but an error occurred writing out
 the signers certificates.
 
 =back
 
 =head1 EXAMPLES
 
 Create a cleartext signed message:
 
  openssl smime -sign -in message.txt -text -out mail.msg \
 	-signer mycert.pem
 
 Create an opaque signed message:
 
  openssl smime -sign -in message.txt -text -out mail.msg -nodetach \
 	-signer mycert.pem
 
 Create a signed message, include some additional certificates and
 read the private key from another file:
 
  openssl smime -sign -in in.txt -text -out mail.msg \
 	-signer mycert.pem -inkey mykey.pem -certfile mycerts.pem
 
 Create a signed message with two signers:
 
  openssl smime -sign -in message.txt -text -out mail.msg \
 	-signer mycert.pem -signer othercert.pem
 
 Send a signed message under Unix directly to sendmail, including headers:
 
  openssl smime -sign -in in.txt -text -signer mycert.pem \
 	-from steve@openssl.org -to someone@somewhere \
 	-subject "Signed message" | sendmail someone@somewhere
 
 Verify a message and extract the signer's certificate if successful:
 
  openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt
 
 Send encrypted mail using triple DES:
 
  openssl smime -encrypt -in in.txt -from steve@openssl.org \
 	-to someone@somewhere -subject "Encrypted message" \
 	-des3 user.pem -out mail.msg
 
 Sign and encrypt mail:
 
  openssl smime -sign -in ml.txt -signer my.pem -text \
 	| openssl smime -encrypt -out mail.msg \
 	-from steve@openssl.org -to someone@somewhere \
 	-subject "Signed and Encrypted message" -des3 user.pem
 
 Note: the encryption command does not include the B<-text> option because the
 message being encrypted already has MIME headers.
 
 Decrypt mail:
 
  openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey key.pem
 
 The output from Netscape form signing is a PKCS#7 structure with the
 detached signature format. You can use this program to verify the
 signature by line wrapping the base64 encoded structure and surrounding
 it with:
 
  -----BEGIN PKCS7-----
  -----END PKCS7-----
 
 and using the command: 
 
  openssl smime -verify -inform PEM -in signature.pem -content content.txt
 
 Alternatively you can base64 decode the signature and use:
 
  openssl smime -verify -inform DER -in signature.der -content content.txt
 
 Create an encrypted message using 128 bit Camellia:
 
  openssl smime -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem
 
 Add a signer to an existing message:
 
  openssl smime -resign -in mail.msg -signer newsign.pem -out mail2.msg
 
 =head1 BUGS
 
 The MIME parser isn't very clever: it seems to handle most messages that I've
 thrown at it but it may choke on others.
 
 The code currently will only write out the signer's certificate to a file: if
 the signer has a separate encryption certificate this must be manually
 extracted. There should be some heuristic that determines the correct
 encryption certificate.
 
 Ideally a database should be maintained of a certificates for each email
 address.
 
 The code doesn't currently take note of the permitted symmetric encryption
 algorithms as supplied in the SMIMECapabilities signed attribute. This means the
 user has to manually include the correct encryption algorithm. It should store
 the list of permitted ciphers in a database and only use those.
 
 No revocation checking is done on the signer's certificate.
 
 The current code can only handle S/MIME v2 messages, the more complex S/MIME v3
 structures may cause parsing errors.
 
 =head1 HISTORY
 
 The use of multiple B<-signer> options and the B<-resign> command were first
 added in OpenSSL 1.0.0
 
 The -no_alt_chains options was first added to OpenSSL 1.0.1n and 1.0.2b.
 
 =cut
Index: vendor-crypto/openssl/dist-1.0.1/doc/apps/verify.pod
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/doc/apps/verify.pod	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/doc/apps/verify.pod	(revision 306191)
@@ -1,425 +1,430 @@
 =pod
 
 =head1 NAME
 
 verify - Utility to verify certificates.
 
 =head1 SYNOPSIS
 
 B<openssl> B<verify>
 [B<-CApath directory>]
 [B<-CAfile file>]
 [B<-purpose purpose>]
 [B<-policy arg>]
 [B<-ignore_critical>]
 [B<-crl_check>]
 [B<-crl_check_all>]
 [B<-policy_check>]
 [B<-explicit_policy>]
 [B<-inhibit_any>]
 [B<-inhibit_map>]
 [B<-x509_strict>]
 [B<-extended_crl>]
 [B<-use_deltas>]
 [B<-policy_print>]
 [B<-no_alt_chains>]
+[B<-allow_proxy_certs>]
 [B<-untrusted file>]
 [B<-help>]
 [B<-issuer_checks>]
 [B<-attime timestamp>]
 [B<-verbose>]
 [B<->]
 [certificates]
 
 
 =head1 DESCRIPTION
 
 The B<verify> command verifies certificate chains.
 
 =head1 COMMAND OPTIONS
 
 =over 4
 
 =item B<-CApath directory>
 
 A directory of trusted certificates. The certificates should have names
 of the form: hash.0 or have symbolic links to them of this
 form ("hash" is the hashed certificate subject name: see the B<-hash> option
 of the B<x509> utility). Under Unix the B<c_rehash> script will automatically
 create symbolic links to a directory of certificates.
 
 =item B<-CAfile file>
 A file of trusted certificates. The file should contain multiple certificates
 in PEM format concatenated together.
 
 =item B<-untrusted file>
 
 A file of untrusted certificates. The file should contain multiple certificates
 in PEM format concatenated together.
 
 =item B<-purpose purpose>
 
 The intended use for the certificate. If this option is not specified,
 B<verify> will not consider certificate purpose during chain verification.
 Currently accepted uses are B<sslclient>, B<sslserver>, B<nssslserver>,
 B<smimesign>, B<smimeencrypt>. See the B<VERIFY OPERATION> section for more
 information.
 
 =item B<-help>
 
 Print out a usage message.
 
 =item B<-verbose>
 
 Print extra information about the operations being performed.
 
 =item B<-issuer_checks>
 
 Print out diagnostics relating to searches for the issuer certificate of the
 current certificate. This shows why each candidate issuer certificate was
 rejected. The presence of rejection messages does not itself imply that
 anything is wrong; during the normal verification process, several
 rejections may take place.
 
 =item B<-attime timestamp>
 
 Perform validation checks using time specified by B<timestamp> and not
 current system time. B<timestamp> is the number of seconds since
 01.01.1970 (UNIX time).
 
 =item B<-policy arg>
 
 Enable policy processing and add B<arg> to the user-initial-policy-set (see
 RFC5280). The policy B<arg> can be an object name an OID in numeric form.
 This argument can appear more than once.
 
 =item B<-policy_check>
 
 Enables certificate policy processing.
 
 =item B<-explicit_policy>
 
 Set policy variable require-explicit-policy (see RFC5280).
 
 =item B<-inhibit_any>
 
 Set policy variable inhibit-any-policy (see RFC5280).
 
 =item B<-inhibit_map>
 
 Set policy variable inhibit-policy-mapping (see RFC5280).
 
 =item B<-no_alt_chains>
 
 When building a certificate chain, if the first certificate chain found is not
 trusted, then OpenSSL will continue to check to see if an alternative chain can
 be found that is trusted. With this option that behaviour is suppressed so that
 only the first chain found is ever used. Using this option will force the
 behaviour to match that of previous OpenSSL versions.
+
+=item B<-allow_proxy_certs>
+
+Allow the verification of proxy certificates.
 
 =item B<-policy_print>
 
 Print out diagnostics related to policy processing.
 
 =item B<-crl_check>
 
 Checks end entity certificate validity by attempting to look up a valid CRL.
 If a valid CRL cannot be found an error occurs. 
 
 =item B<-crl_check_all>
 
 Checks the validity of B<all> certificates in the chain by attempting
 to look up valid CRLs.
 
 =item B<-ignore_critical>
 
 Normally if an unhandled critical extension is present which is not
 supported by OpenSSL the certificate is rejected (as required by RFC5280).
 If this option is set critical extensions are ignored.
 
 =item B<-x509_strict>
 
 For strict X.509 compliance, disable non-compliant workarounds for broken
 certificates.
 
 =item B<-extended_crl>
 
 Enable extended CRL features such as indirect CRLs and alternate CRL
 signing keys.
 
 =item B<-use_deltas>
 
 Enable support for delta CRLs.
 
 =item B<-check_ss_sig>
 
 Verify the signature on the self-signed root CA. This is disabled by default
 because it doesn't add any security.
 
 =item B<->
 
 Indicates the last option. All arguments following this are assumed to be
 certificate files. This is useful if the first certificate filename begins
 with a B<->.
 
 =item B<certificates>
 
 One or more certificates to verify. If no certificates are given, B<verify>
 will attempt to read a certificate from standard input. Certificates must be
 in PEM format.
 
 =back
 
 =head1 VERIFY OPERATION
 
 The B<verify> program uses the same functions as the internal SSL and S/MIME
 verification, therefore this description applies to these verify operations
 too.
 
 There is one crucial difference between the verify operations performed
 by the B<verify> program: wherever possible an attempt is made to continue
 after an error whereas normally the verify operation would halt on the
 first error. This allows all the problems with a certificate chain to be
 determined.
 
 The verify operation consists of a number of separate steps.
 
 Firstly a certificate chain is built up starting from the supplied certificate
 and ending in the root CA. It is an error if the whole chain cannot be built
 up. The chain is built up by looking up the issuers certificate of the current
 certificate. If a certificate is found which is its own issuer it is assumed 
 to be the root CA.
 
 The process of 'looking up the issuers certificate' itself involves a number
 of steps. In versions of OpenSSL before 0.9.5a the first certificate whose
 subject name matched the issuer of the current certificate was assumed to be
 the issuers certificate. In OpenSSL 0.9.6 and later all certificates
 whose subject name matches the issuer name of the current certificate are 
 subject to further tests. The relevant authority key identifier components
 of the current certificate (if present) must match the subject key identifier
 (if present) and issuer and serial number of the candidate issuer, in addition
 the keyUsage extension of the candidate issuer (if present) must permit
 certificate signing.
 
 The lookup first looks in the list of untrusted certificates and if no match
 is found the remaining lookups are from the trusted certificates. The root CA
 is always looked up in the trusted certificate list: if the certificate to
 verify is a root certificate then an exact match must be found in the trusted
 list.
 
 The second operation is to check every untrusted certificate's extensions for
 consistency with the supplied purpose. If the B<-purpose> option is not included
 then no checks are done. The supplied or "leaf" certificate must have extensions
 compatible with the supplied purpose and all other certificates must also be valid
 CA certificates. The precise extensions required are described in more detail in
 the B<CERTIFICATE EXTENSIONS> section of the B<x509> utility.
 
 The third operation is to check the trust settings on the root CA. The root
 CA should be trusted for the supplied purpose. For compatibility with previous
 versions of SSLeay and OpenSSL a certificate with no trust settings is considered
 to be valid for all purposes. 
 
 The final operation is to check the validity of the certificate chain. The validity
 period is checked against the current system time and the notBefore and notAfter
 dates in the certificate. The certificate signatures are also checked at this
 point.
 
 If all operations complete successfully then certificate is considered valid. If
 any operation fails then the certificate is not valid.
 
 =head1 DIAGNOSTICS
 
 When a verify operation fails the output messages can be somewhat cryptic. The
 general form of the error message is:
 
  server.pem: /C=AU/ST=Queensland/O=CryptSoft Pty Ltd/CN=Test CA (1024 bit)
  error 24 at 1 depth lookup:invalid CA certificate
 
 The first line contains the name of the certificate being verified followed by
 the subject name of the certificate. The second line contains the error number
 and the depth. The depth is number of the certificate being verified when a
 problem was detected starting with zero for the certificate being verified itself
 then 1 for the CA that signed the certificate and so on. Finally a text version
 of the error number is presented.
 
 An exhaustive list of the error codes and messages is shown below, this also
 includes the name of the error code as defined in the header file x509_vfy.h
 Some of the error codes are defined but never returned: these are described
 as "unused".
 
 =over 4
 
 =item B<0 X509_V_OK: ok>
 
 the operation was successful.
 
 =item B<2 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: unable to get issuer certificate>
 
 the issuer certificate of a looked up certificate could not be found. This
 normally means the list of trusted certificates is not complete.
 
 =item B<3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
 
 the CRL of a certificate could not be found.
 
 =item B<4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
 
 the certificate signature could not be decrypted. This means that the actual signature value
 could not be determined rather than it not matching the expected value, this is only
 meaningful for RSA keys.
 
 =item B<5 X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: unable to decrypt CRL's signature>
 
 the CRL signature could not be decrypted: this means that the actual signature value
 could not be determined rather than it not matching the expected value. Unused.
 
 =item B<6 X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: unable to decode issuer public key>
 
 the public key in the certificate SubjectPublicKeyInfo could not be read.
 
 =item B<7 X509_V_ERR_CERT_SIGNATURE_FAILURE: certificate signature failure>
 
 the signature of the certificate is invalid.
 
 =item B<8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
 
 the signature of the certificate is invalid.
 
 =item B<9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
 
 the certificate is not yet valid: the notBefore date is after the current time.
 
 =item B<10 X509_V_ERR_CERT_HAS_EXPIRED: certificate has expired>
 
 the certificate has expired: that is the notAfter date is before the current time.
 
 =item B<11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
 
 the CRL is not yet valid.
 
 =item B<12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
 
 the CRL has expired.
 
 =item B<13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
 
 the certificate notBefore field contains an invalid time.
 
 =item B<14 X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: format error in certificate's notAfter field>
 
 the certificate notAfter field contains an invalid time.
 
 =item B<15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
 
 the CRL lastUpdate field contains an invalid time.
 
 =item B<16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
 
 the CRL nextUpdate field contains an invalid time.
 
 =item B<17 X509_V_ERR_OUT_OF_MEM: out of memory>
 
 an error occurred trying to allocate memory. This should never happen.
 
 =item B<18 X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: self signed certificate>
 
 the passed certificate is self signed and the same certificate cannot be found in the list of
 trusted certificates.
 
 =item B<19 X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: self signed certificate in certificate chain>
 
 the certificate chain could be built up using the untrusted certificates but the root could not
 be found locally.
 
 =item B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate>
 
 the issuer certificate could not be found: this occurs if the issuer
 certificate of an untrusted certificate cannot be found.
 
 =item B<21 X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: unable to verify the first certificate>
 
 no signatures could be verified because the chain contains only one certificate and it is not
 self signed.
 
 =item B<22 X509_V_ERR_CERT_CHAIN_TOO_LONG: certificate chain too long>
 
 the certificate chain length is greater than the supplied maximum depth. Unused.
 
 =item B<23 X509_V_ERR_CERT_REVOKED: certificate revoked>
 
 the certificate has been revoked.
 
 =item B<24 X509_V_ERR_INVALID_CA: invalid CA certificate>
 
 a CA certificate is invalid. Either it is not a CA or its extensions are not consistent
 with the supplied purpose.
 
 =item B<25 X509_V_ERR_PATH_LENGTH_EXCEEDED: path length constraint exceeded>
 
 the basicConstraints pathlength parameter has been exceeded.
 
 =item B<26 X509_V_ERR_INVALID_PURPOSE: unsupported certificate purpose>
 
 the supplied certificate cannot be used for the specified purpose.
 
 =item B<27 X509_V_ERR_CERT_UNTRUSTED: certificate not trusted>
 
 the root CA is not marked as trusted for the specified purpose.
 
 =item B<28 X509_V_ERR_CERT_REJECTED: certificate rejected>
 
 the root CA is marked to reject the specified purpose.
 
 =item B<29 X509_V_ERR_SUBJECT_ISSUER_MISMATCH: subject issuer mismatch>
 
 the current candidate issuer certificate was rejected because its subject name
 did not match the issuer name of the current certificate. Only displayed when
 the B<-issuer_checks> option is set.
 
 =item B<30 X509_V_ERR_AKID_SKID_MISMATCH: authority and subject key identifier mismatch>
 
 the current candidate issuer certificate was rejected because its subject key
 identifier was present and did not match the authority key identifier current
 certificate. Only displayed when the B<-issuer_checks> option is set.
 
 =item B<31 X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: authority and issuer serial number mismatch>
 
 the current candidate issuer certificate was rejected because its issuer name
 and serial number was present and did not match the authority key identifier
 of the current certificate. Only displayed when the B<-issuer_checks> option is set.
 
 =item B<32 X509_V_ERR_KEYUSAGE_NO_CERTSIGN:key usage does not include certificate signing>
 
 the current candidate issuer certificate was rejected because its keyUsage extension
 does not permit certificate signing.
 
 =item B<50 X509_V_ERR_APPLICATION_VERIFICATION: application verification failure>
 
 an application specific error. Unused.
 
 =back
 
 =head1 BUGS
 
 Although the issuer checks are a considerable improvement over the old technique they still
 suffer from limitations in the underlying X509_LOOKUP API. One consequence of this is that
 trusted certificates with matching subject name must either appear in a file (as specified by the
 B<-CAfile> option) or a directory (as specified by B<-CApath>. If they occur in both then only
 the certificates in the file will be recognised.
 
 Previous versions of OpenSSL assume certificates with matching subject name are identical and
 mishandled them.
 
 Previous versions of this documentation swapped the meaning of the
 B<X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT> and
 B<20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY> error codes.
 
 =head1 SEE ALSO
 
 L<x509(1)|x509(1)>
 
 =head1 HISTORY
 
 The -no_alt_chains options was first added to OpenSSL 1.0.1n and 1.0.2b.
 
 =cut
Index: vendor-crypto/openssl/dist-1.0.1/doc/crypto/X509_verify_cert.pod
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/doc/crypto/X509_verify_cert.pod	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/doc/crypto/X509_verify_cert.pod	(revision 306191)
@@ -1,54 +1,55 @@
 =pod
 
 =head1 NAME
 
 X509_verify_cert - discover and verify X509 certificte chain
 
 =head1 SYNOPSIS
 
  #include <openssl/x509.h>
 
  int X509_verify_cert(X509_STORE_CTX *ctx);
 
 =head1 DESCRIPTION
 
 The X509_verify_cert() function attempts to discover and validate a
 certificate chain based on parameters in B<ctx>. A complete description of
 the process is contained in the L<verify(1)|verify(1)> manual page.
 
 =head1 RETURN VALUES
 
 If a complete chain can be built and validated this function returns 1,
 otherwise it return zero, in exceptional circumstances it can also
 return a negative code.
 
 If the function fails additional error information can be obtained by
 examining B<ctx> using, for example X509_STORE_CTX_get_error().
 
 =head1 NOTES
 
 Applications rarely call this function directly but it is used by
 OpenSSL internally for certificate validation, in both the S/MIME and
 SSL/TLS code.
 
-The negative return value from X509_verify_cert() can only occur if no
-certificate is set in B<ctx> (due to a programming error); if X509_verify_cert()
-twice without reinitialising B<ctx> in between; or if a retry
-operation is requested during internal lookups (which never happens with
-standard lookup methods). It is however recommended that application check
-for <= 0 return value on error.
+A negative return value from X509_verify_cert() can occur if it is invoked
+incorrectly, such as with no certificate set in B<ctx>, or when it is called
+twice in succession without reinitialising B<ctx> for the second call.
+A negative return value can also happen due to internal resource problems or if
+a retry operation is requested during internal lookups (which never happens
+with standard lookup methods).
+Applications must check for <= 0 return value on error.
 
 =head1 BUGS
 
 This function uses the header B<x509.h> as opposed to most chain verification
 functiosn which use B<x509_vfy.h>.
 
 =head1 SEE ALSO
 
 L<X509_STORE_CTX_get_error(3)|X509_STORE_CTX_get_error(3)>
 
 =head1 HISTORY
 
 X509_verify_cert() is available in all versions of SSLeay and OpenSSL.
 
 =cut
Index: vendor-crypto/openssl/dist-1.0.1/doc/crypto/d2i_PrivateKey.pod
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/doc/crypto/d2i_PrivateKey.pod	(nonexistent)
+++ vendor-crypto/openssl/dist-1.0.1/doc/crypto/d2i_PrivateKey.pod	(revision 306191)
@@ -0,0 +1,59 @@
+=pod
+
+=head1 NAME
+
+d2i_Private_key, d2i_AutoPrivateKey, i2d_PrivateKey - decode and encode
+functions for reading and saving EVP_PKEY structures.
+
+=head1 SYNOPSIS
+
+ #include <openssl/evp.h>
+
+ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
+                          long length);
+ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
+                              long length);
+ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp);
+
+=head1 DESCRIPTION
+
+d2i_PrivateKey() decodes a private key using algorithm B<type>. It attempts to
+use any key specific format or PKCS#8 unencrypted PrivateKeyInfo format. The
+B<type> parameter should be a public key algorithm constant such as
+B<EVP_PKEY_RSA>. An error occurs if the decoded key does not match B<type>.
+
+d2i_AutoPrivateKey() is similar to d2i_PrivateKey() except it attempts to
+automatically detect the private key format.
+
+i2d_PrivateKey() encodes B<key>. It uses a key specific format or, if none is
+defined for that key type, PKCS#8 unencrypted PrivateKeyInfo format.
+
+These functions are similar to the d2i_X509() functions, and you should refer to
+that page for a detailed description (see L<d2i_X509(3)>).
+
+=head1 NOTES
+
+All these functions use DER format and unencrypted keys. Applications wishing
+to encrypt or decrypt private keys should use other functions such as
+d2i_PKC8PrivateKey() instead.
+
+If the B<*a> is not NULL when calling d2i_PrivateKey() or d2i_AutoPrivateKey()
+(i.e. an existing structure is being reused) and the key format is PKCS#8
+then B<*a> will be freed and replaced on a successful call.
+
+=head1 RETURN VALUES
+
+d2i_PrivateKey() and d2i_AutoPrivateKey() return a valid B<EVP_KEY> structure
+or B<NULL> if an error occurs. The error code can be obtained by calling
+L<ERR_get_error(3)>.
+
+i2d_PrivateKey() returns the number of bytes successfully encoded or a
+negative value if an error occurs. The error code can be obtained by calling
+L<ERR_get_error(3)>.
+
+=head1 SEE ALSO
+
+L<crypto(3)>,
+L<d2i_PKCS8PrivateKey(3)>
+
+=cut
Index: vendor-crypto/openssl/dist-1.0.1/ssl/d1_both.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/d1_both.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/d1_both.c	(revision 306191)
@@ -1,1700 +1,1703 @@
 /* ssl/d1_both.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 <limits.h>
 #include <string.h>
 #include <stdio.h>
 #include "ssl_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
 #define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8)
 
 #define RSMBLY_BITMASK_MARK(bitmask, start, end) { \
                         if ((end) - (start) <= 8) { \
                                 long ii; \
                                 for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \
                         } else { \
                                 long ii; \
                                 bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \
                                 for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \
                                 bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \
                         } }
 
 #define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \
                         long ii; \
                         OPENSSL_assert((msg_len) > 0); \
                         is_complete = 1; \
                         if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \
                         if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \
                                 if (bitmask[ii] != 0xff) { is_complete = 0; break; } }
 
 #if 0
 # define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \
                         long ii; \
                         printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \
                         printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \
                         printf("\n"); }
 #endif
 
 static unsigned char bitmask_start_values[] =
     { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 };
 static unsigned char bitmask_end_values[] =
     { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f };
 
 /* XDTLS:  figure out the right values */
 static const unsigned int g_probable_mtu[] = { 1500, 512, 256 };
 
 static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                                      unsigned long frag_len);
 static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
 static void dtls1_set_message_header_int(SSL *s, unsigned char mt,
                                          unsigned long len,
                                          unsigned short seq_num,
                                          unsigned long frag_off,
                                          unsigned long frag_len);
 static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max,
                                        int *ok);
 
 static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
                                           int reassembly)
 {
     hm_fragment *frag = NULL;
     unsigned char *buf = NULL;
     unsigned char *bitmask = NULL;
 
     frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
     if (frag == NULL)
         return NULL;
 
     if (frag_len) {
         buf = (unsigned char *)OPENSSL_malloc(frag_len);
         if (buf == NULL) {
             OPENSSL_free(frag);
             return NULL;
         }
     }
 
     /* zero length fragment gets zero frag->fragment */
     frag->fragment = buf;
 
     /* Initialize reassembly bitmask if necessary */
     if (reassembly) {
         bitmask =
             (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len));
         if (bitmask == NULL) {
             if (buf != NULL)
                 OPENSSL_free(buf);
             OPENSSL_free(frag);
             return NULL;
         }
         memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len));
     }
 
     frag->reassembly = bitmask;
 
     return frag;
 }
 
 void dtls1_hm_fragment_free(hm_fragment *frag)
 {
 
     if (frag->msg_header.is_ccs) {
         EVP_CIPHER_CTX_free(frag->msg_header.
                             saved_retransmit_state.enc_write_ctx);
         EVP_MD_CTX_destroy(frag->msg_header.
                            saved_retransmit_state.write_hash);
     }
     if (frag->fragment)
         OPENSSL_free(frag->fragment);
     if (frag->reassembly)
         OPENSSL_free(frag->reassembly);
     OPENSSL_free(frag);
 }
 
 static int dtls1_query_mtu(SSL *s)
 {
     if (s->d1->link_mtu) {
         s->d1->mtu =
             s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
         s->d1->link_mtu = 0;
     }
 
     /* AHA!  Figure out the MTU, and stick to the right size */
     if (s->d1->mtu < dtls1_min_mtu(s)) {
         if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
             s->d1->mtu =
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
 
             /*
              * I've seen the kernel return bogus numbers when it doesn't know
              * (initial write), so just make sure we have a reasonable number
              */
             if (s->d1->mtu < dtls1_min_mtu(s)) {
                 /* Set to min mtu */
                 s->d1->mtu = dtls1_min_mtu(s);
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU,
                          s->d1->mtu, NULL);
             }
         } else
             return 0;
     }
     return 1;
 }
 
 /*
  * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
  * SSL3_RT_CHANGE_CIPHER_SPEC)
  */
 int dtls1_do_write(SSL *s, int type)
 {
     int ret;
     unsigned int curr_mtu;
     int retry = 1;
     unsigned int len, frag_off, mac_size, blocksize, used_len;
 
     if (!dtls1_query_mtu(s))
         return -1;
 
     OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something
                                                      * reasonable now */
 
     if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE)
         OPENSSL_assert(s->init_num ==
                        (int)s->d1->w_msg_hdr.msg_len +
                        DTLS1_HM_HEADER_LENGTH);
 
     if (s->write_hash)
         mac_size = EVP_MD_CTX_size(s->write_hash);
     else
         mac_size = 0;
 
     if (s->enc_write_ctx &&
         (EVP_CIPHER_mode(s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE))
         blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher);
     else
         blocksize = 0;
 
     frag_off = 0;
     s->rwstate = SSL_NOTHING;
 
     /* s->init_num shouldn't ever be < 0...but just in case */
     while (s->init_num > 0) {
         if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) {
             /* We must be writing a fragment other than the first one */
 
             if (frag_off > 0) {
                 /* This is the first attempt at writing out this fragment */
 
                 if (s->init_off <= DTLS1_HM_HEADER_LENGTH) {
                     /*
                      * Each fragment that was already sent must at least have
                      * contained the message header plus one other byte.
                      * Therefore |init_off| must have progressed by at least
                      * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went
                      * wrong.
                      */
                     return -1;
                 }
 
                 /*
                  * Adjust |init_off| and |init_num| to allow room for a new
                  * message header for this fragment.
                  */
                 s->init_off -= DTLS1_HM_HEADER_LENGTH;
                 s->init_num += DTLS1_HM_HEADER_LENGTH;
             } else {
                 /*
                  * We must have been called again after a retry so use the
                  * fragment offset from our last attempt. We do not need
                  * to adjust |init_off| and |init_num| as above, because
                  * that should already have been done before the retry.
                  */
                 frag_off = s->d1->w_msg_hdr.frag_off;
             }
         }
 
         used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH
             + mac_size + blocksize;
         if (s->d1->mtu > used_len)
             curr_mtu = s->d1->mtu - used_len;
         else
             curr_mtu = 0;
 
         if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
             /*
              * grr.. we could get an error if MTU picked was wrong
              */
             ret = BIO_flush(SSL_get_wbio(s));
             if (ret <= 0) {
                 s->rwstate = SSL_WRITING;
                 return ret;
             }
             used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize;
             if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) {
                 curr_mtu = s->d1->mtu - used_len;
             } else {
                 /* Shouldn't happen */
                 return -1;
             }
         }
 
         /*
          * We just checked that s->init_num > 0 so this cast should be safe
          */
         if (((unsigned int)s->init_num) > curr_mtu)
             len = curr_mtu;
         else
             len = s->init_num;
 
         /* Shouldn't ever happen */
         if (len > INT_MAX)
             len = INT_MAX;
 
         /*
          * XDTLS: this function is too long.  split out the CCS part
          */
         if (type == SSL3_RT_HANDSHAKE) {
             if (len < DTLS1_HM_HEADER_LENGTH) {
                 /*
                  * len is so small that we really can't do anything sensible
                  * so fail
                  */
                 return -1;
             }
             dtls1_fix_message_header(s, frag_off,
                                      len - DTLS1_HM_HEADER_LENGTH);
 
             dtls1_write_message_header(s,
                                        (unsigned char *)&s->init_buf->
                                        data[s->init_off]);
         }
 
         ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off],
                                 len);
         if (ret < 0) {
             /*
              * might need to update MTU here, but we don't know which
              * previous packet caused the failure -- so can't really
              * retransmit anything.  continue as if everything is fine and
              * wait for an alert to handle the retransmit
              */
             if (retry && BIO_ctrl(SSL_get_wbio(s),
                                   BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) {
                 if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
                     if (!dtls1_query_mtu(s))
                         return -1;
                     /* Have one more go */
                     retry = 0;
                 } else
                     return -1;
             } else {
                 return (-1);
             }
         } else {
 
             /*
              * bad if this assert fails, only part of the handshake message
              * got sent.  but why would this happen?
              */
             OPENSSL_assert(len == (unsigned int)ret);
 
             if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) {
                 /*
                  * should not be done for 'Hello Request's, but in that case
                  * we'll ignore the result anyway
                  */
                 unsigned char *p =
                     (unsigned char *)&s->init_buf->data[s->init_off];
                 const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
                 int xlen;
 
                 if (frag_off == 0 && s->version != DTLS1_BAD_VER) {
                     /*
                      * reconstruct message header is if it is being sent in
                      * single fragment
                      */
                     *p++ = msg_hdr->type;
                     l2n3(msg_hdr->msg_len, p);
                     s2n(msg_hdr->seq, p);
                     l2n3(0, p);
                     l2n3(msg_hdr->msg_len, p);
                     p -= DTLS1_HM_HEADER_LENGTH;
                     xlen = ret;
                 } else {
                     p += DTLS1_HM_HEADER_LENGTH;
                     xlen = ret - DTLS1_HM_HEADER_LENGTH;
                 }
 
                 ssl3_finish_mac(s, p, xlen);
             }
 
             if (ret == s->init_num) {
                 if (s->msg_callback)
                     s->msg_callback(1, s->version, type, s->init_buf->data,
                                     (size_t)(s->init_off + s->init_num), s,
                                     s->msg_callback_arg);
 
                 s->init_off = 0; /* done writing this message */
                 s->init_num = 0;
 
                 return (1);
             }
             s->init_off += ret;
             s->init_num -= ret;
             ret -= DTLS1_HM_HEADER_LENGTH;
             frag_off += ret;
 
             /*
              * We save the fragment offset for the next fragment so we have it
              * available in case of an IO retry. We don't know the length of the
              * next fragment yet so just set that to 0 for now. It will be
              * updated again later.
              */
             dtls1_fix_message_header(s, frag_off, 0);
         }
     }
     return (0);
 }
 
 /*
  * Obtain handshake message of message type 'mt' (any if mt == -1), maximum
  * acceptable body length 'max'. Read an entire handshake message.  Handshake
  * messages arrive in fragments.
  */
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 {
     int i, al;
     struct hm_header_st *msg_hdr;
     unsigned char *p;
     unsigned long msg_len;
 
     /*
      * s3->tmp is used to store messages that are unexpected, caused by the
      * absence of an optional handshake message
      */
     if (s->s3->tmp.reuse_message) {
         s->s3->tmp.reuse_message = 0;
         if ((mt >= 0) && (s->s3->tmp.message_type != mt)) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
         *ok = 1;
         s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
         s->init_num = (int)s->s3->tmp.message_size;
         return s->init_num;
     }
 
     msg_hdr = &s->d1->r_msg_hdr;
     memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
 
  again:
     i = dtls1_get_message_fragment(s, st1, stn, max, ok);
     if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) {
         /* bad fragment received */
         goto again;
     } else if (i <= 0 && !*ok) {
         return i;
     }
 
     if (mt >= 0 && s->s3->tmp.message_type != mt) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
         goto f_err;
     }
 
     p = (unsigned char *)s->init_buf->data;
     msg_len = msg_hdr->msg_len;
 
     /* reconstruct message header */
     *(p++) = msg_hdr->type;
     l2n3(msg_len, p);
     s2n(msg_hdr->seq, p);
     l2n3(0, p);
     l2n3(msg_len, p);
     if (s->version != DTLS1_BAD_VER) {
         p -= DTLS1_HM_HEADER_LENGTH;
         msg_len += DTLS1_HM_HEADER_LENGTH;
     }
 
     ssl3_finish_mac(s, p, msg_len);
     if (s->msg_callback)
         s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                         p, msg_len, s, s->msg_callback_arg);
 
     memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
 
     /* Don't change sequence numbers while listening */
     if (!s->d1->listen)
         s->d1->handshake_read_seq++;
 
     s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
     return s->init_num;
 
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
     *ok = 0;
     return -1;
 }
 
 static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr,
                                      int max)
 {
     size_t frag_off, frag_len, msg_len;
 
     msg_len = msg_hdr->msg_len;
     frag_off = msg_hdr->frag_off;
     frag_len = msg_hdr->frag_len;
 
     /* sanity checking */
     if ((frag_off + frag_len) > msg_len) {
         SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
         return SSL_AD_ILLEGAL_PARAMETER;
     }
 
     if ((frag_off + frag_len) > (unsigned long)max) {
         SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
         return SSL_AD_ILLEGAL_PARAMETER;
     }
 
     if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */
         /*
          * msg_len is limited to 2^24, but is effectively checked against max
          * above
+         *
+         * Make buffer slightly larger than message length as a precaution
+         * against small OOB reads e.g. CVE-2016-6306
          */
         if (!BUF_MEM_grow_clean
-            (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
+            (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) {
             SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
             return SSL_AD_INTERNAL_ERROR;
         }
 
         s->s3->tmp.message_size = msg_len;
         s->d1->r_msg_hdr.msg_len = msg_len;
         s->s3->tmp.message_type = msg_hdr->type;
         s->d1->r_msg_hdr.type = msg_hdr->type;
         s->d1->r_msg_hdr.seq = msg_hdr->seq;
     } else if (msg_len != s->d1->r_msg_hdr.msg_len) {
         /*
          * They must be playing with us! BTW, failure to enforce upper limit
          * would open possibility for buffer overrun.
          */
         SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE);
         return SSL_AD_ILLEGAL_PARAMETER;
     }
 
     return 0;                   /* no error */
 }
 
 static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
 {
     /*-
      * (0) check whether the desired fragment is available
      * if so:
      * (1) copy over the fragment to s->init_buf->data[]
      * (2) update s->init_num
      */
     pitem *item;
     hm_fragment *frag;
     int al;
 
     *ok = 0;
-    item = pqueue_peek(s->d1->buffered_messages);
-    if (item == NULL)
-        return 0;
+    do {
+        item = pqueue_peek(s->d1->buffered_messages);
+        if (item == NULL)
+            return 0;
 
-    frag = (hm_fragment *)item->data;
+        frag = (hm_fragment *)item->data;
 
+        if (frag->msg_header.seq < s->d1->handshake_read_seq) {
+            /* This is a stale message that has been buffered so clear it */
+            pqueue_pop(s->d1->buffered_messages);
+            dtls1_hm_fragment_free(frag);
+            pitem_free(item);
+            item = NULL;
+            frag = NULL;
+        }
+    } while (item == NULL);
+
+
     /* Don't return if reassembly still in progress */
     if (frag->reassembly != NULL)
         return 0;
 
     if (s->d1->handshake_read_seq == frag->msg_header.seq) {
         unsigned long frag_len = frag->msg_header.frag_len;
         pqueue_pop(s->d1->buffered_messages);
 
         al = dtls1_preprocess_fragment(s, &frag->msg_header, max);
 
         if (al == 0) {          /* no alert */
             unsigned char *p =
                 (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
             memcpy(&p[frag->msg_header.frag_off], frag->fragment,
                    frag->msg_header.frag_len);
         }
 
         dtls1_hm_fragment_free(frag);
         pitem_free(item);
 
         if (al == 0) {
             *ok = 1;
             return frag_len;
         }
 
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
         s->init_num = 0;
         *ok = 0;
         return -1;
     } else
         return 0;
 }
 
 /*
  * dtls1_max_handshake_message_len returns the maximum number of bytes
  * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but
  * may be greater if the maximum certificate list size requires it.
  */
 static unsigned long dtls1_max_handshake_message_len(const SSL *s)
 {
     unsigned long max_len =
         DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
     if (max_len < (unsigned long)s->max_cert_list)
         return s->max_cert_list;
     return max_len;
 }
 
 static int
 dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok)
 {
     hm_fragment *frag = NULL;
     pitem *item = NULL;
     int i = -1, is_complete;
     unsigned char seq64be[8];
     unsigned long frag_len = msg_hdr->frag_len;
 
     if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len ||
         msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
         goto err;
 
     if (frag_len == 0)
         return DTLS1_HM_FRAGMENT_RETRY;
 
     /* Try to find item in queue */
     memset(seq64be, 0, sizeof(seq64be));
     seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
     seq64be[7] = (unsigned char)msg_hdr->seq;
     item = pqueue_find(s->d1->buffered_messages, seq64be);
 
     if (item == NULL) {
         frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1);
         if (frag == NULL)
             goto err;
         memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
         frag->msg_header.frag_len = frag->msg_header.msg_len;
         frag->msg_header.frag_off = 0;
     } else {
         frag = (hm_fragment *)item->data;
         if (frag->msg_header.msg_len != msg_hdr->msg_len) {
             item = NULL;
             frag = NULL;
             goto err;
         }
     }
 
     /*
      * If message is already reassembled, this must be a retransmit and can
      * be dropped. In this case item != NULL and so frag does not need to be
      * freed.
      */
     if (frag->reassembly == NULL) {
         unsigned char devnull[256];
 
         while (frag_len) {
             i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                           devnull,
                                           frag_len >
                                           sizeof(devnull) ? sizeof(devnull) :
                                           frag_len, 0);
             if (i <= 0)
                 goto err;
             frag_len -= i;
         }
         return DTLS1_HM_FRAGMENT_RETRY;
     }
 
     /* read the body of the fragment (header has already been read */
     i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                   frag->fragment + msg_hdr->frag_off,
                                   frag_len, 0);
     if ((unsigned long)i != frag_len)
         i = -1;
     if (i <= 0)
         goto err;
 
     RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
                         (long)(msg_hdr->frag_off + frag_len));
 
     RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len,
                                is_complete);
 
     if (is_complete) {
         OPENSSL_free(frag->reassembly);
         frag->reassembly = NULL;
     }
 
     if (item == NULL) {
         item = pitem_new(seq64be, frag);
         if (item == NULL) {
             i = -1;
             goto err;
         }
 
         item = pqueue_insert(s->d1->buffered_messages, item);
         /*
          * pqueue_insert fails iff a duplicate item is inserted. However,
          * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
          * would have returned it and control would never have reached this
          * branch.
          */
         OPENSSL_assert(item != NULL);
     }
 
     return DTLS1_HM_FRAGMENT_RETRY;
 
  err:
     if (frag != NULL && item == NULL)
         dtls1_hm_fragment_free(frag);
     *ok = 0;
     return i;
 }
 
 static int
 dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr,
                                  int *ok)
 {
     int i = -1;
     hm_fragment *frag = NULL;
     pitem *item = NULL;
     unsigned char seq64be[8];
     unsigned long frag_len = msg_hdr->frag_len;
 
     if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len)
         goto err;
 
     /* Try to find item in queue, to prevent duplicate entries */
     memset(seq64be, 0, sizeof(seq64be));
     seq64be[6] = (unsigned char)(msg_hdr->seq >> 8);
     seq64be[7] = (unsigned char)msg_hdr->seq;
     item = pqueue_find(s->d1->buffered_messages, seq64be);
 
     /*
      * If we already have an entry and this one is a fragment, don't discard
      * it and rather try to reassemble it.
      */
     if (item != NULL && frag_len != msg_hdr->msg_len)
         item = NULL;
 
     /*
      * Discard the message if sequence number was already there, is too far
      * in the future, already in the queue or if we received a FINISHED
      * before the SERVER_HELLO, which then must be a stale retransmit.
      */
     if (msg_hdr->seq <= s->d1->handshake_read_seq ||
         msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL ||
         (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED))
     {
         unsigned char devnull[256];
 
         while (frag_len) {
             i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                           devnull,
                                           frag_len >
                                           sizeof(devnull) ? sizeof(devnull) :
                                           frag_len, 0);
             if (i <= 0)
                 goto err;
             frag_len -= i;
         }
     } else {
         if (frag_len != msg_hdr->msg_len)
             return dtls1_reassemble_fragment(s, msg_hdr, ok);
 
         if (frag_len > dtls1_max_handshake_message_len(s))
             goto err;
 
         frag = dtls1_hm_fragment_new(frag_len, 0);
         if (frag == NULL)
             goto err;
 
         memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr));
 
         if (frag_len) {
             /*
              * read the body of the fragment (header has already been read
              */
             i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                           frag->fragment, frag_len, 0);
             if ((unsigned long)i != frag_len)
                 i = -1;
             if (i <= 0)
                 goto err;
         }
 
         item = pitem_new(seq64be, frag);
         if (item == NULL)
             goto err;
 
         item = pqueue_insert(s->d1->buffered_messages, item);
         /*
          * pqueue_insert fails iff a duplicate item is inserted. However,
          * |item| cannot be a duplicate. If it were, |pqueue_find|, above,
          * would have returned it. Then, either |frag_len| !=
          * |msg_hdr->msg_len| in which case |item| is set to NULL and it will
          * have been processed with |dtls1_reassemble_fragment|, above, or
          * the record will have been discarded.
          */
         OPENSSL_assert(item != NULL);
     }
 
     return DTLS1_HM_FRAGMENT_RETRY;
 
  err:
     if (frag != NULL && item == NULL)
         dtls1_hm_fragment_free(frag);
     *ok = 0;
     return i;
 }
 
 static long
 dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok)
 {
     unsigned char wire[DTLS1_HM_HEADER_LENGTH];
     unsigned long len, frag_off, frag_len;
     int i, al;
     struct hm_header_st msg_hdr;
 
  redo:
     /* see if we have the required fragment already */
     if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) {
         if (*ok)
             s->init_num = frag_len;
         return frag_len;
     }
 
     /* read handshake message header */
     i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire,
                                   DTLS1_HM_HEADER_LENGTH, 0);
     if (i <= 0) {               /* nbio, or an error */
         s->rwstate = SSL_READING;
         *ok = 0;
         return i;
     }
     /* Handshake fails if message header is incomplete */
     if (i != DTLS1_HM_HEADER_LENGTH) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_UNEXPECTED_MESSAGE);
         goto f_err;
     }
 
     /* parse the message fragment header */
     dtls1_get_message_header(wire, &msg_hdr);
 
     len = msg_hdr.msg_len;
     frag_off = msg_hdr.frag_off;
     frag_len = msg_hdr.frag_len;
 
     /*
      * We must have at least frag_len bytes left in the record to be read.
      * Fragments must not span records.
      */
     if (frag_len > s->s3->rrec.length) {
         al = SSL3_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH);
         goto f_err;
     }
 
     /*
      * if this is a future (or stale) message it gets buffered
      * (or dropped)--no further processing at this time
      * While listening, we accept seq 1 (ClientHello with cookie)
      * although we're still expecting seq 0 (ClientHello)
      */
     if (msg_hdr.seq != s->d1->handshake_read_seq
         && !(s->d1->listen && msg_hdr.seq == 1))
         return dtls1_process_out_of_seq_message(s, &msg_hdr, ok);
 
     if (frag_len && frag_len < len)
         return dtls1_reassemble_fragment(s, &msg_hdr, ok);
 
     if (!s->server && s->d1->r_msg_hdr.frag_off == 0 &&
         wire[0] == SSL3_MT_HELLO_REQUEST) {
         /*
          * The server may always send 'Hello Request' messages -- we are
          * doing a handshake anyway now, so ignore them if their format is
          * correct. Does not count for 'Finished' MAC.
          */
         if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) {
             if (s->msg_callback)
                 s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
                                 wire, DTLS1_HM_HEADER_LENGTH, s,
                                 s->msg_callback_arg);
 
             s->init_num = 0;
             goto redo;
         } else {                /* Incorrectly formated Hello request */
 
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT,
                    SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
     }
 
     if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max)))
         goto f_err;
 
     if (frag_len > 0) {
         unsigned char *p =
             (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
 
         i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                       &p[frag_off], frag_len, 0);
 
         /*
          * This shouldn't ever fail due to NBIO because we already checked
          * that we have enough data in the record
          */
         if (i <= 0) {
             s->rwstate = SSL_READING;
             *ok = 0;
             return i;
         }
     } else
         i = 0;
 
     /*
      * XDTLS: an incorrectly formatted fragment should cause the handshake
      * to fail
      */
     if (i != (int)frag_len) {
         al = SSL3_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL3_AD_ILLEGAL_PARAMETER);
         goto f_err;
     }
 
     *ok = 1;
     s->state = stn;
 
     /*
      * Note that s->init_num is *not* used as current offset in
      * s->init_buf->data, but as a counter summing up fragments' lengths: as
      * soon as they sum up to handshake packet length, we assume we have got
      * all the fragments.
      */
     s->init_num = frag_len;
     return frag_len;
 
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
     s->init_num = 0;
 
     *ok = 0;
     return (-1);
 }
 
 int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 {
     unsigned char *p, *d;
     int i;
     unsigned long l;
 
     if (s->state == a) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[DTLS1_HM_HEADER_LENGTH]);
 
         i = s->method->ssl3_enc->final_finish_mac(s,
                                                   sender, slen,
                                                   s->s3->tmp.finish_md);
         s->s3->tmp.finish_md_len = i;
         memcpy(p, s->s3->tmp.finish_md, i);
         p += i;
         l = i;
 
         /*
          * Copy the finished so we can use it for renegotiation checks
          */
         if (s->type == SSL_ST_CONNECT) {
             OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
             memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i);
             s->s3->previous_client_finished_len = i;
         } else {
             OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
             memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i);
             s->s3->previous_server_finished_len = i;
         }
 
 #ifdef OPENSSL_SYS_WIN16
         /*
          * MSVC 1.5 does not clear the top bytes of the word unless I do
          * this.
          */
         l &= 0xffff;
 #endif
 
         d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l);
         s->init_num = (int)l + DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
 
         s->state = b;
     }
 
     /* SSL3_ST_SEND_xxxxxx_HELLO_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 /*-
  * for these 2 messages, we need to
  * ssl->enc_read_ctx                    re-init
  * ssl->s3->read_sequence               zero
  * ssl->s3->read_mac_secret             re-init
  * ssl->session->read_sym_enc           assign
  * ssl->session->read_compression       assign
  * ssl->session->read_hash              assign
  */
 int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
 {
     unsigned char *p;
 
     if (s->state == a) {
         p = (unsigned char *)s->init_buf->data;
         *p++ = SSL3_MT_CCS;
         s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
         s->init_num = DTLS1_CCS_HEADER_LENGTH;
 
         if (s->version == DTLS1_BAD_VER) {
             s->d1->next_handshake_write_seq++;
             s2n(s->d1->handshake_write_seq, p);
             s->init_num += 2;
         }
 
         s->init_off = 0;
 
         dtls1_set_message_header_int(s, SSL3_MT_CCS, 0,
                                      s->d1->handshake_write_seq, 0, 0);
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 1);
 
         s->state = b;
     }
 
     /* SSL3_ST_CW_CHANGE_B */
     return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
 }
 
 static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 {
     int n;
     unsigned char *p;
 
     n = i2d_X509(x, NULL);
     if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
         SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
         return 0;
     }
     p = (unsigned char *)&(buf->data[*l]);
     l2n3(n, p);
     i2d_X509(x, &p);
     *l += n + 3;
 
     return 1;
 }
 
 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
 {
     unsigned char *p;
     int i;
     unsigned long l = 3 + DTLS1_HM_HEADER_LENGTH;
     BUF_MEM *buf;
 
     /* TLSv1 sends a chain with nothing in it, instead of an alert */
     buf = s->init_buf;
     if (!BUF_MEM_grow_clean(buf, 10)) {
         SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB);
         return (0);
     }
     if (x != NULL) {
         X509_STORE_CTX xs_ctx;
 
         if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, x, NULL)) {
             SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_X509_LIB);
             return (0);
         }
 
         X509_verify_cert(&xs_ctx);
         /* Don't leave errors in the queue */
         ERR_clear_error();
         for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
             x = sk_X509_value(xs_ctx.chain, i);
 
             if (!dtls1_add_cert_to_buf(buf, &l, x)) {
                 X509_STORE_CTX_cleanup(&xs_ctx);
                 return 0;
             }
         }
         X509_STORE_CTX_cleanup(&xs_ctx);
     }
     /* Thawte special :-) */
     for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) {
         x = sk_X509_value(s->ctx->extra_certs, i);
         if (!dtls1_add_cert_to_buf(buf, &l, x))
             return 0;
     }
 
     l -= (3 + DTLS1_HM_HEADER_LENGTH);
 
     p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
     l2n3(l, p);
     l += 3;
     p = (unsigned char *)&(buf->data[0]);
     p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l);
 
     l += DTLS1_HM_HEADER_LENGTH;
     return (l);
 }
 
 int dtls1_read_failed(SSL *s, int code)
 {
     if (code > 0) {
         fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
         return 1;
     }
 
     if (!dtls1_is_timer_expired(s)) {
         /*
          * not a timeout, none of our business, let higher layers handle
          * this.  in fact it's probably an error
          */
         return code;
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     /* done, no need to send a retransmit */
     if (!SSL_in_init(s) && !s->tlsext_hb_pending)
 #else
     /* done, no need to send a retransmit */
     if (!SSL_in_init(s))
 #endif
     {
         BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ);
         return code;
     }
 #if 0                           /* for now, each alert contains only one
                                  * record number */
     item = pqueue_peek(state->rcvd_records);
     if (item) {
         /* send an alert immediately for all the missing records */
     } else
 #endif
 
 #if 0                           /* no more alert sending, just retransmit the
                                  * last set of messages */
     if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
         ssl3_send_alert(s, SSL3_AL_WARNING,
                         DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
 #endif
 
     return dtls1_handle_timeout(s);
 }
 
 int dtls1_get_queue_priority(unsigned short seq, int is_ccs)
 {
     /*
      * The index of the retransmission queue actually is the message sequence
      * number, since the queue only contains messages of a single handshake.
      * However, the ChangeCipherSpec has no message sequence number and so
      * using only the sequence will result in the CCS and Finished having the
      * same index. To prevent this, the sequence number is multiplied by 2.
      * In case of a CCS 1 is subtracted. This does not only differ CSS and
      * Finished, it also maintains the order of the index (important for
      * priority queues) and fits in the unsigned short variable.
      */
     return seq * 2 - is_ccs;
 }
 
 int dtls1_retransmit_buffered_messages(SSL *s)
 {
     pqueue sent = s->d1->sent_messages;
     piterator iter;
     pitem *item;
     hm_fragment *frag;
     int found = 0;
 
     iter = pqueue_iterator(sent);
 
     for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) {
         frag = (hm_fragment *)item->data;
         if (dtls1_retransmit_message(s, (unsigned short)
                                      dtls1_get_queue_priority
                                      (frag->msg_header.seq,
                                       frag->msg_header.is_ccs), 0,
                                      &found) <= 0 && found) {
             fprintf(stderr, "dtls1_retransmit_message() failed\n");
             return -1;
         }
     }
 
     return 1;
 }
 
 int dtls1_buffer_message(SSL *s, int is_ccs)
 {
     pitem *item;
     hm_fragment *frag;
     unsigned char seq64be[8];
 
     /*
      * this function is called immediately after a message has been
      * serialized
      */
     OPENSSL_assert(s->init_off == 0);
 
     frag = dtls1_hm_fragment_new(s->init_num, 0);
     if (!frag)
         return 0;
 
     memcpy(frag->fragment, s->init_buf->data, s->init_num);
 
     if (is_ccs) {
         OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
                        ((s->version ==
                          DTLS1_VERSION) ? DTLS1_CCS_HEADER_LENGTH : 3) ==
                        (unsigned int)s->init_num);
     } else {
         OPENSSL_assert(s->d1->w_msg_hdr.msg_len +
                        DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num);
     }
 
     frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len;
     frag->msg_header.seq = s->d1->w_msg_hdr.seq;
     frag->msg_header.type = s->d1->w_msg_hdr.type;
     frag->msg_header.frag_off = 0;
     frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len;
     frag->msg_header.is_ccs = is_ccs;
 
     /* save current state */
     frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx;
     frag->msg_header.saved_retransmit_state.write_hash = s->write_hash;
     frag->msg_header.saved_retransmit_state.compress = s->compress;
     frag->msg_header.saved_retransmit_state.session = s->session;
     frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch;
 
     memset(seq64be, 0, sizeof(seq64be));
     seq64be[6] =
         (unsigned
          char)(dtls1_get_queue_priority(frag->msg_header.seq,
                                         frag->msg_header.is_ccs) >> 8);
     seq64be[7] =
         (unsigned
          char)(dtls1_get_queue_priority(frag->msg_header.seq,
                                         frag->msg_header.is_ccs));
 
     item = pitem_new(seq64be, frag);
     if (item == NULL) {
         dtls1_hm_fragment_free(frag);
         return 0;
     }
 #if 0
     fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type);
     fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len);
     fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num);
 #endif
 
     pqueue_insert(s->d1->sent_messages, item);
     return 1;
 }
 
 int
 dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
                          int *found)
 {
     int ret;
     /* XDTLS: for now assuming that read/writes are blocking */
     pitem *item;
     hm_fragment *frag;
     unsigned long header_length;
     unsigned char seq64be[8];
     struct dtls1_retransmit_state saved_state;
     unsigned char save_write_sequence[8];
 
     /*-
       OPENSSL_assert(s->init_num == 0);
       OPENSSL_assert(s->init_off == 0);
      */
 
     /* XDTLS:  the requested message ought to be found, otherwise error */
     memset(seq64be, 0, sizeof(seq64be));
     seq64be[6] = (unsigned char)(seq >> 8);
     seq64be[7] = (unsigned char)seq;
 
     item = pqueue_find(s->d1->sent_messages, seq64be);
     if (item == NULL) {
         fprintf(stderr, "retransmit:  message %d non-existant\n", seq);
         *found = 0;
         return 0;
     }
 
     *found = 1;
     frag = (hm_fragment *)item->data;
 
     if (frag->msg_header.is_ccs)
         header_length = DTLS1_CCS_HEADER_LENGTH;
     else
         header_length = DTLS1_HM_HEADER_LENGTH;
 
     memcpy(s->init_buf->data, frag->fragment,
            frag->msg_header.msg_len + header_length);
     s->init_num = frag->msg_header.msg_len + header_length;
 
     dtls1_set_message_header_int(s, frag->msg_header.type,
                                  frag->msg_header.msg_len,
                                  frag->msg_header.seq, 0,
                                  frag->msg_header.frag_len);
 
     /* save current state */
     saved_state.enc_write_ctx = s->enc_write_ctx;
     saved_state.write_hash = s->write_hash;
     saved_state.compress = s->compress;
     saved_state.session = s->session;
     saved_state.epoch = s->d1->w_epoch;
     saved_state.epoch = s->d1->w_epoch;
 
     s->d1->retransmitting = 1;
 
     /* restore state in which the message was originally sent */
     s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx;
     s->write_hash = frag->msg_header.saved_retransmit_state.write_hash;
     s->compress = frag->msg_header.saved_retransmit_state.compress;
     s->session = frag->msg_header.saved_retransmit_state.session;
     s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch;
 
     if (frag->msg_header.saved_retransmit_state.epoch ==
         saved_state.epoch - 1) {
         memcpy(save_write_sequence, s->s3->write_sequence,
                sizeof(s->s3->write_sequence));
         memcpy(s->s3->write_sequence, s->d1->last_write_sequence,
                sizeof(s->s3->write_sequence));
     }
 
     ret = dtls1_do_write(s, frag->msg_header.is_ccs ?
                          SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE);
 
     /* restore current state */
     s->enc_write_ctx = saved_state.enc_write_ctx;
     s->write_hash = saved_state.write_hash;
     s->compress = saved_state.compress;
     s->session = saved_state.session;
     s->d1->w_epoch = saved_state.epoch;
 
     if (frag->msg_header.saved_retransmit_state.epoch ==
         saved_state.epoch - 1) {
         memcpy(s->d1->last_write_sequence, s->s3->write_sequence,
                sizeof(s->s3->write_sequence));
         memcpy(s->s3->write_sequence, save_write_sequence,
                sizeof(s->s3->write_sequence));
     }
 
     s->d1->retransmitting = 0;
 
     (void)BIO_flush(SSL_get_wbio(s));
     return ret;
 }
 
-/* call this function when the buffered messages are no longer needed */
-void dtls1_clear_record_buffer(SSL *s)
-{
-    pitem *item;
-
-    for (item = pqueue_pop(s->d1->sent_messages);
-         item != NULL; item = pqueue_pop(s->d1->sent_messages)) {
-        dtls1_hm_fragment_free((hm_fragment *)item->data);
-        pitem_free(item);
-    }
-}
-
 unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p,
                                         unsigned char mt, unsigned long len,
                                         unsigned long frag_off,
                                         unsigned long frag_len)
 {
     /* Don't change sequence numbers while listening */
     if (frag_off == 0 && !s->d1->listen) {
         s->d1->handshake_write_seq = s->d1->next_handshake_write_seq;
         s->d1->next_handshake_write_seq++;
     }
 
     dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq,
                                  frag_off, frag_len);
 
     return p += DTLS1_HM_HEADER_LENGTH;
 }
 
 /* don't actually do the writing, wait till the MTU has been retrieved */
 static void
 dtls1_set_message_header_int(SSL *s, unsigned char mt,
                              unsigned long len, unsigned short seq_num,
                              unsigned long frag_off, unsigned long frag_len)
 {
     struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
 
     msg_hdr->type = mt;
     msg_hdr->msg_len = len;
     msg_hdr->seq = seq_num;
     msg_hdr->frag_off = frag_off;
     msg_hdr->frag_len = frag_len;
 }
 
 static void
 dtls1_fix_message_header(SSL *s, unsigned long frag_off,
                          unsigned long frag_len)
 {
     struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
 
     msg_hdr->frag_off = frag_off;
     msg_hdr->frag_len = frag_len;
 }
 
 static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p)
 {
     struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr;
 
     *p++ = msg_hdr->type;
     l2n3(msg_hdr->msg_len, p);
 
     s2n(msg_hdr->seq, p);
     l2n3(msg_hdr->frag_off, p);
     l2n3(msg_hdr->frag_len, p);
 
     return p;
 }
 
 unsigned int dtls1_link_min_mtu(void)
 {
     return (g_probable_mtu[(sizeof(g_probable_mtu) /
                             sizeof(g_probable_mtu[0])) - 1]);
 }
 
 unsigned int dtls1_min_mtu(SSL *s)
 {
     return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s));
 }
 
 void
 dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr)
 {
     memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
     msg_hdr->type = *(data++);
     n2l3(data, msg_hdr->msg_len);
 
     n2s(data, msg_hdr->seq);
     n2l3(data, msg_hdr->frag_off);
     n2l3(data, msg_hdr->frag_len);
 }
 
 void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr)
 {
     memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st));
 
     ccs_hdr->type = *(data++);
 }
 
 int dtls1_shutdown(SSL *s)
 {
     int ret;
 #ifndef OPENSSL_NO_SCTP
     BIO *wbio;
 
     wbio = SSL_get_wbio(s);
     if (wbio != NULL && BIO_dgram_is_sctp(wbio) &&
         !(s->shutdown & SSL_SENT_SHUTDOWN)) {
         ret = BIO_dgram_sctp_wait_for_dry(wbio);
         if (ret < 0)
             return -1;
 
         if (ret == 0)
             BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1,
                      NULL);
     }
 #endif
     ret = ssl3_shutdown(s);
 #ifndef OPENSSL_NO_SCTP
     BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL);
 #endif
     return ret;
 }
 
 #ifndef OPENSSL_NO_HEARTBEATS
 int dtls1_process_heartbeat(SSL *s)
 {
     unsigned char *p = &s->s3->rrec.data[0], *pl;
     unsigned short hbtype;
     unsigned int payload;
     unsigned int padding = 16;  /* Use minimum padding */
 
     if (s->msg_callback)
         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                         &s->s3->rrec.data[0], s->s3->rrec.length,
                         s, s->msg_callback_arg);
 
     /* Read type and payload length first */
     if (1 + 2 + 16 > s->s3->rrec.length)
         return 0;               /* silently discard */
     if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH)
         return 0;               /* silently discard per RFC 6520 sec. 4 */
 
     hbtype = *p++;
     n2s(p, payload);
     if (1 + 2 + payload + 16 > s->s3->rrec.length)
         return 0;               /* silently discard per RFC 6520 sec. 4 */
     pl = p;
 
     if (hbtype == TLS1_HB_REQUEST) {
         unsigned char *buffer, *bp;
         unsigned int write_length = 1 /* heartbeat type */  +
             2 /* heartbeat length */  +
             payload + padding;
         int r;
 
         if (write_length > SSL3_RT_MAX_PLAIN_LENGTH)
             return 0;
 
         /*
          * Allocate memory for the response, size is 1 byte message type,
          * plus 2 bytes payload length, plus payload, plus padding
          */
         buffer = OPENSSL_malloc(write_length);
         if (buffer == NULL)
             return -1;
         bp = buffer;
 
         /* Enter response type, length and copy payload */
         *bp++ = TLS1_HB_RESPONSE;
         s2n(payload, bp);
         memcpy(bp, pl, payload);
         bp += payload;
         /* Random padding */
-        if (RAND_pseudo_bytes(bp, padding) < 0) {
+        if (RAND_bytes(bp, padding) <= 0) {
             OPENSSL_free(buffer);
             return -1;
         }
 
         r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length);
 
         if (r >= 0 && s->msg_callback)
             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
                             buffer, write_length, s, s->msg_callback_arg);
 
         OPENSSL_free(buffer);
 
         if (r < 0)
             return r;
     } else if (hbtype == TLS1_HB_RESPONSE) {
         unsigned int seq;
 
         /*
          * We only send sequence numbers (2 bytes unsigned int), and 16
          * random bytes, so we just try to read the sequence number
          */
         n2s(pl, seq);
 
         if (payload == 18 && seq == s->tlsext_hb_seq) {
             dtls1_stop_timer(s);
             s->tlsext_hb_seq++;
             s->tlsext_hb_pending = 0;
         }
     }
 
     return 0;
 }
 
 int dtls1_heartbeat(SSL *s)
 {
     unsigned char *buf, *p;
     int ret = -1;
     unsigned int payload = 18;  /* Sequence number + random bytes */
     unsigned int padding = 16;  /* Use minimum padding */
 
     /* Only send if peer supports and accepts HB requests... */
     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
         SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
         return -1;
     }
 
     /* ...and there is none in flight yet... */
     if (s->tlsext_hb_pending) {
         SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
         return -1;
     }
 
     /* ...and no handshake in progress. */
     if (SSL_in_init(s) || s->in_handshake) {
         SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
         return -1;
     }
 
     /*
      * Check if padding is too long, payload and padding must not exceed 2^14
      * - 3 = 16381 bytes in total.
      */
     OPENSSL_assert(payload + padding <= 16381);
 
     /*-
      * Create HeartBeat message, we just use a sequence number
      * as payload to distuingish different messages and add
      * some random stuff.
      *  - Message Type, 1 byte
      *  - Payload Length, 2 bytes (unsigned int)
      *  - Payload, the sequence number (2 bytes uint)
      *  - Payload, random bytes (16 bytes uint)
      *  - Padding
      */
     buf = OPENSSL_malloc(1 + 2 + payload + padding);
     p = buf;
     /* Message Type */
     *p++ = TLS1_HB_REQUEST;
     /* Payload length (18 bytes here) */
     s2n(payload, p);
     /* Sequence number */
     s2n(s->tlsext_hb_seq, p);
     /* 16 random bytes */
-    if (RAND_pseudo_bytes(p, 16) < 0)
+    if (RAND_bytes(p, 16) <= 0)
         goto err;
     p += 16;
     /* Random padding */
-    if (RAND_pseudo_bytes(p, padding) < 0)
+    if (RAND_bytes(p, padding) <= 0)
         goto err;
 
     ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
     if (ret >= 0) {
         if (s->msg_callback)
             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
                             buf, 3 + payload + padding,
                             s, s->msg_callback_arg);
 
         dtls1_start_timer(s);
         s->tlsext_hb_pending = 1;
     }
 
 err:
     OPENSSL_free(buf);
 
     return ret;
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/d1_clnt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/d1_clnt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/d1_clnt.c	(revision 306191)
@@ -1,1713 +1,1714 @@
 /* ssl/d1_clnt.c */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
  */
 /* ====================================================================
  * Copyright (c) 1999-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).
  *
  */
 /* 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_KRB5
 # include "kssl_lcl.h"
 #endif
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 
 static const SSL_METHOD *dtls1_get_client_method(int ver);
 static int dtls1_get_hello_verify(SSL *s);
 
 static const SSL_METHOD *dtls1_get_client_method(int ver)
 {
     if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER)
         return (DTLSv1_client_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_dtls1_meth_func(DTLSv1_client_method,
                           ssl_undefined_function,
                           dtls1_connect, dtls1_get_client_method)
 
 int dtls1_connect(SSL *s)
 {
     BUF_MEM *buf = NULL;
     unsigned long Time = (unsigned long)time(NULL);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
     int ret = -1;
     int new_state, state, skip = 0;
 #ifndef OPENSSL_NO_SCTP
     unsigned char sctpauthkey[64];
     char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
 #endif
 
     RAND_add(&Time, sizeof(Time), 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;
 
     s->in_handshake++;
     if (!SSL_in_init(s) || SSL_in_before(s))
         SSL_clear(s);
 
 #ifndef OPENSSL_NO_SCTP
     /*
      * Notify SCTP BIO socket to enter handshake mode and prevent stream
      * identifier other than 0. Will be ignored if no SCTP is used.
      */
     BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
              s->in_handshake, NULL);
 #endif
 
 #ifndef OPENSSL_NO_HEARTBEATS
     /*
      * If we're awaiting a HeartbeatResponse, pretend we already got and
      * don't await it anymore, because Heartbeats don't make sense during
      * handshakes anyway.
      */
     if (s->tlsext_hb_pending) {
         dtls1_stop_timer(s);
         s->tlsext_hb_pending = 0;
         s->tlsext_hb_seq++;
     }
 #endif
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_RENEGOTIATE:
             s->renegotiate = 1;
             s->state = SSL_ST_CONNECT;
             s->ctx->stats.sess_connect_renegotiate++;
             /* break */
         case SSL_ST_BEFORE:
         case SSL_ST_CONNECT:
         case SSL_ST_BEFORE | SSL_ST_CONNECT:
         case SSL_ST_OK | SSL_ST_CONNECT:
 
             s->server = 0;
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
             if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) &&
                 (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) {
                 SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR);
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             /* s->version=SSL3_VERSION; */
             s->type = SSL_ST_CONNECT;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
                 buf = NULL;
             }
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             /* setup buffing BIO */
             if (!ssl_init_wbio_buffer(s, 0)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             /* don't push the buffering BIO quite yet */
 
             s->state = SSL3_ST_CW_CLNT_HELLO_A;
             s->ctx->stats.sess_connect++;
             s->init_num = 0;
             /* mark client_random uninitialized */
             memset(s->s3->client_random, 0, sizeof(s->s3->client_random));
             s->d1->send_cookie = 0;
             s->hit = 0;
             s->d1->change_cipher_spec_ok = 0;
             /*
              * Should have been reset by ssl3_get_finished, too.
              */
             s->s3->change_cipher_spec = 0;
             break;
 
 #ifndef OPENSSL_NO_SCTP
         case DTLS1_SCTP_ST_CR_READ_SOCK:
 
             if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
                 s->s3->in_read_app_data = 2;
                 s->rwstate = SSL_READING;
                 BIO_clear_retry_flags(SSL_get_rbio(s));
                 BIO_set_retry_read(SSL_get_rbio(s));
                 ret = -1;
                 goto end;
             }
 
             s->state = s->s3->tmp.next_state;
             break;
 
         case DTLS1_SCTP_ST_CW_WRITE_SOCK:
             /* read app data until dry event */
 
             ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
             if (ret < 0)
                 goto end;
 
             if (ret == 0) {
                 s->s3->in_read_app_data = 2;
                 s->rwstate = SSL_READING;
                 BIO_clear_retry_flags(SSL_get_rbio(s));
                 BIO_set_retry_read(SSL_get_rbio(s));
                 ret = -1;
                 goto end;
             }
 
             s->state = s->d1->next_state;
             break;
 #endif
 
         case SSL3_ST_CW_CLNT_HELLO_A:
             s->shutdown = 0;
 
             /* every DTLS ClientHello resets Finished MAC */
             ssl3_init_finished_mac(s);
 
         case SSL3_ST_CW_CLNT_HELLO_B:
             dtls1_start_timer(s);
             ret = dtls1_client_hello(s);
             if (ret <= 0)
                 goto end;
 
             if (s->d1->send_cookie) {
                 s->state = SSL3_ST_CW_FLUSH;
                 s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A;
             } else
                 s->state = SSL3_ST_CR_SRVR_HELLO_A;
 
             s->init_num = 0;
 
 #ifndef OPENSSL_NO_SCTP
             /* Disable buffering for SCTP */
             if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) {
 #endif
                 /*
                  * turn on buffering for the next lot of output
                  */
                 if (s->bbio != s->wbio)
                     s->wbio = BIO_push(s->bbio, s->wbio);
 #ifndef OPENSSL_NO_SCTP
             }
 #endif
 
             break;
 
         case SSL3_ST_CR_SRVR_HELLO_A:
         case SSL3_ST_CR_SRVR_HELLO_B:
             ret = ssl3_get_server_hello(s);
             if (ret <= 0)
                 goto end;
             else {
                 if (s->hit) {
 #ifndef OPENSSL_NO_SCTP
                     /*
                      * Add new shared key for SCTP-Auth, will be ignored if
                      * no SCTP used.
                      */
                     snprintf((char *)labelbuffer,
                              sizeof(DTLS1_SCTP_AUTH_LABEL),
                              DTLS1_SCTP_AUTH_LABEL);
 
                     if (SSL_export_keying_material(s, sctpauthkey,
                                                sizeof(sctpauthkey),
                                                labelbuffer,
                                                sizeof(labelbuffer), NULL, 0,
                                                0) <= 0) {
                         ret = -1;
                         s->state = SSL_ST_ERR;
                         goto end;
                     }
 
                     BIO_ctrl(SSL_get_wbio(s),
                              BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
                              sizeof(sctpauthkey), sctpauthkey);
 #endif
 
                     s->state = SSL3_ST_CR_FINISHED_A;
                     if (s->tlsext_ticket_expected) {
                         /* receive renewed session ticket */
                         s->state = SSL3_ST_CR_SESSION_TICKET_A;
                     }
                 } else
                     s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A;
             }
             s->init_num = 0;
             break;
 
         case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
         case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B:
 
             ret = dtls1_get_hello_verify(s);
             if (ret <= 0)
                 goto end;
             dtls1_stop_timer(s);
             if (s->d1->send_cookie) /* start again, with a cookie */
                 s->state = SSL3_ST_CW_CLNT_HELLO_A;
             else
                 s->state = SSL3_ST_CR_CERT_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_CERT_A:
         case SSL3_ST_CR_CERT_B:
             /* Check if it is anon DH or PSK */
             if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                 !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 ret = ssl3_get_server_certificate(s);
                 if (ret <= 0)
                     goto end;
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_status_expected)
                     s->state = SSL3_ST_CR_CERT_STATUS_A;
                 else
                     s->state = SSL3_ST_CR_KEY_EXCH_A;
             } else {
                 skip = 1;
                 s->state = SSL3_ST_CR_KEY_EXCH_A;
             }
 #else
             } else
                 skip = 1;
 
             s->state = SSL3_ST_CR_KEY_EXCH_A;
 #endif
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_KEY_EXCH_A:
         case SSL3_ST_CR_KEY_EXCH_B:
             ret = ssl3_get_key_exchange(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_CERT_REQ_A;
             s->init_num = 0;
 
             /*
              * at this point we check that we have the required stuff from
              * the server
              */
             if (!ssl3_check_cert_and_algorithm(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
             break;
 
         case SSL3_ST_CR_CERT_REQ_A:
         case SSL3_ST_CR_CERT_REQ_B:
             ret = ssl3_get_certificate_request(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_SRVR_DONE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_SRVR_DONE_A:
         case SSL3_ST_CR_SRVR_DONE_B:
             ret = ssl3_get_server_done(s);
             if (ret <= 0)
                 goto end;
             dtls1_stop_timer(s);
             if (s->s3->tmp.cert_req)
                 s->s3->tmp.next_state = SSL3_ST_CW_CERT_A;
             else
                 s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A;
             s->init_num = 0;
 
 #ifndef OPENSSL_NO_SCTP
             if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
                 state == SSL_ST_RENEGOTIATE)
                 s->state = DTLS1_SCTP_ST_CR_READ_SOCK;
             else
 #endif
                 s->state = s->s3->tmp.next_state;
             break;
 
         case SSL3_ST_CW_CERT_A:
         case SSL3_ST_CW_CERT_B:
         case SSL3_ST_CW_CERT_C:
         case SSL3_ST_CW_CERT_D:
             dtls1_start_timer(s);
             ret = dtls1_send_client_certificate(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_KEY_EXCH_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_KEY_EXCH_A:
         case SSL3_ST_CW_KEY_EXCH_B:
             dtls1_start_timer(s);
             ret = dtls1_send_client_key_exchange(s);
             if (ret <= 0)
                 goto end;
 
 #ifndef OPENSSL_NO_SCTP
             /*
              * Add new shared key for SCTP-Auth, will be ignored if no SCTP
              * used.
              */
             snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
                      DTLS1_SCTP_AUTH_LABEL);
 
             if (SSL_export_keying_material(s, sctpauthkey,
                                        sizeof(sctpauthkey), labelbuffer,
                                        sizeof(labelbuffer), NULL, 0, 0) <= 0) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
                      sizeof(sctpauthkey), sctpauthkey);
 #endif
 
             /*
              * EAY EAY EAY need to check for DH fix cert sent back
              */
             /*
              * For TLS, cert_req is set to 2, so a cert chain of nothing is
              * sent, but no verify packet is sent
              */
             if (s->s3->tmp.cert_req == 1) {
                 s->state = SSL3_ST_CW_CERT_VRFY_A;
             } else {
 #ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = SSL3_ST_CW_CHANGE_A;
                     s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
                 } else
 #endif
                     s->state = SSL3_ST_CW_CHANGE_A;
             }
 
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_CERT_VRFY_A:
         case SSL3_ST_CW_CERT_VRFY_B:
             dtls1_start_timer(s);
             ret = dtls1_send_client_verify(s);
             if (ret <= 0)
                 goto end;
 #ifndef OPENSSL_NO_SCTP
             if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                 s->d1->next_state = SSL3_ST_CW_CHANGE_A;
                 s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
             } else
 #endif
                 s->state = SSL3_ST_CW_CHANGE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_CHANGE_A:
         case SSL3_ST_CW_CHANGE_B:
             if (!s->hit)
                 dtls1_start_timer(s);
             ret = dtls1_send_change_cipher_spec(s,
                                                 SSL3_ST_CW_CHANGE_A,
                                                 SSL3_ST_CW_CHANGE_B);
             if (ret <= 0)
                 goto end;
 
             s->state = SSL3_ST_CW_FINISHED_A;
             s->init_num = 0;
 
             s->session->cipher = s->s3->tmp.new_cipher;
 #ifdef OPENSSL_NO_COMP
             s->session->compress_meth = 0;
 #else
             if (s->s3->tmp.new_compression == NULL)
                 s->session->compress_meth = 0;
             else
                 s->session->compress_meth = s->s3->tmp.new_compression->id;
 #endif
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             if (!s->method->ssl3_enc->change_cipher_state(s,
                                                           SSL3_CHANGE_CIPHER_CLIENT_WRITE))
             {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 #ifndef OPENSSL_NO_SCTP
             if (s->hit) {
                 /*
                  * Change to new shared key of SCTP-Auth, will be ignored if
                  * no SCTP used.
                  */
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
                          0, NULL);
             }
 #endif
 
             dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
             break;
 
         case SSL3_ST_CW_FINISHED_A:
         case SSL3_ST_CW_FINISHED_B:
             if (!s->hit)
                 dtls1_start_timer(s);
             ret = dtls1_send_finished(s,
                                       SSL3_ST_CW_FINISHED_A,
                                       SSL3_ST_CW_FINISHED_B,
                                       s->method->
                                       ssl3_enc->client_finished_label,
                                       s->method->
                                       ssl3_enc->client_finished_label_len);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_FLUSH;
 
             /* clear flags */
             s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
             if (s->hit) {
                 s->s3->tmp.next_state = SSL_ST_OK;
 #ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = s->s3->tmp.next_state;
                     s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
                 }
 #endif
                 if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) {
                     s->state = SSL_ST_OK;
 #ifndef OPENSSL_NO_SCTP
                     if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                         s->d1->next_state = SSL_ST_OK;
                         s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
                     }
 #endif
                     s->s3->flags |= SSL3_FLAGS_POP_BUFFER;
                     s->s3->delay_buf_pop_ret = 0;
                 }
             } else {
 #ifndef OPENSSL_NO_SCTP
                 /*
                  * Change to new shared key of SCTP-Auth, will be ignored if
                  * no SCTP used.
                  */
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
                          0, NULL);
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
                 /*
                  * Allow NewSessionTicket if ticket expected
                  */
                 if (s->tlsext_ticket_expected)
                     s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
                 else
 #endif
 
                     s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A;
             }
             s->init_num = 0;
             break;
 
 #ifndef OPENSSL_NO_TLSEXT
         case SSL3_ST_CR_SESSION_TICKET_A:
         case SSL3_ST_CR_SESSION_TICKET_B:
             ret = ssl3_get_new_session_ticket(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_FINISHED_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_CERT_STATUS_A:
         case SSL3_ST_CR_CERT_STATUS_B:
             ret = ssl3_get_cert_status(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_KEY_EXCH_A;
             s->init_num = 0;
             break;
 #endif
 
         case SSL3_ST_CR_FINISHED_A:
         case SSL3_ST_CR_FINISHED_B:
             s->d1->change_cipher_spec_ok = 1;
             ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
                                     SSL3_ST_CR_FINISHED_B);
             if (ret <= 0)
                 goto end;
             dtls1_stop_timer(s);
 
             if (s->hit)
                 s->state = SSL3_ST_CW_CHANGE_A;
             else
                 s->state = SSL_ST_OK;
 
 #ifndef OPENSSL_NO_SCTP
             if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
                 state == SSL_ST_RENEGOTIATE) {
                 s->d1->next_state = s->state;
                 s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK;
             }
 #endif
 
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_FLUSH:
             s->rwstate = SSL_WRITING;
             if (BIO_flush(s->wbio) <= 0) {
                 /*
                  * If the write error was fatal, stop trying
                  */
                 if (!BIO_should_retry(s->wbio)) {
                     s->rwstate = SSL_NOTHING;
                     s->state = s->s3->tmp.next_state;
                 }
 
                 ret = -1;
                 goto end;
             }
             s->rwstate = SSL_NOTHING;
             s->state = s->s3->tmp.next_state;
             break;
 
         case SSL_ST_OK:
             /* clean a few things up */
             ssl3_cleanup_key_block(s);
 
 #if 0
             if (s->init_buf != NULL) {
                 BUF_MEM_free(s->init_buf);
                 s->init_buf = NULL;
             }
 #endif
 
             /*
              * If we are not 'joining' the last two packets, remove the
              * buffering now
              */
             if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
                 ssl_free_wbio_buffer(s);
             /* else do it later in ssl3_write */
 
             s->init_num = 0;
             s->renegotiate = 0;
             s->new_session = 0;
 
             ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
             if (s->hit)
                 s->ctx->stats.sess_hit++;
 
             ret = 1;
             /* s->server=0; */
             s->handshake_func = dtls1_connect;
             s->ctx->stats.sess_connect_good++;
 
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_DONE, 1);
 
             /* done with handshaking */
             s->d1->handshake_read_seq = 0;
             s->d1->next_handshake_write_seq = 0;
+            dtls1_clear_received_buffer(s);
             goto end;
             /* break; */
 
         case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
             goto end;
             /* break; */
         }
 
         /* did we do anything */
         if (!s->s3->tmp.reuse_message && !skip) {
             if (s->debug) {
                 if ((ret = BIO_flush(s->wbio)) <= 0)
                     goto end;
             }
 
             if ((cb != NULL) && (s->state != state)) {
                 new_state = s->state;
                 s->state = state;
                 cb(s, SSL_CB_CONNECT_LOOP, 1);
                 s->state = new_state;
             }
         }
         skip = 0;
     }
  end:
     s->in_handshake--;
 
 #ifndef OPENSSL_NO_SCTP
     /*
      * Notify SCTP BIO socket to leave handshake mode and allow stream
      * identifier other than 0. Will be ignored if no SCTP is used.
      */
     BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
              s->in_handshake, NULL);
 #endif
 
     if (buf != NULL)
         BUF_MEM_free(buf);
     if (cb != NULL)
         cb(s, SSL_CB_CONNECT_EXIT, ret);
     return (ret);
 }
 
 int dtls1_client_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     unsigned int i, j;
     unsigned long l;
     SSL_COMP *comp;
 
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
         SSL_SESSION *sess = s->session;
         if ((s->session == NULL) || (s->session->ssl_version != s->version) ||
 #ifdef OPENSSL_NO_TLSEXT
             !sess->session_id_length ||
 #else
             (!sess->session_id_length && !sess->tlsext_tick) ||
 #endif
             (s->session->not_resumable)) {
             if (!ssl_get_new_session(s, 0))
                 goto err;
         }
         /* else use the pre-loaded session */
 
         p = s->s3->client_random;
 
         /*
          * if client_random is initialized, reuse it, we are required to use
          * same upon reply to HelloVerify
          */
         for (i = 0; p[i] == '\0' && i < sizeof(s->s3->client_random); i++) ;
         if (i == sizeof(s->s3->client_random))
             ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random));
 
         /* Do the message type and length last */
         d = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
 
         *(p++) = s->version >> 8;
         *(p++) = s->version & 0xff;
         s->client_version = s->version;
 
         /* Random stuff */
         memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
         p += SSL3_RANDOM_SIZE;
 
         /* Session ID */
         if (s->new_session)
             i = 0;
         else
             i = s->session->session_id_length;
         *(p++) = i;
         if (i != 0) {
             if (i > sizeof s->session->session_id) {
                 SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             memcpy(p, s->session->session_id, i);
             p += i;
         }
 
         /* cookie stuff */
         if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
             SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto err;
         }
         *(p++) = s->d1->cookie_len;
         memcpy(p, s->d1->cookie, s->d1->cookie_len);
         p += s->d1->cookie_len;
 
         /* Ciphers supported */
         i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0);
         if (i == 0) {
             SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
             goto err;
         }
         s2n(i, p);
         p += i;
 
         /* COMPRESSION */
         if (s->ctx->comp_methods == NULL)
             j = 0;
         else
             j = sk_SSL_COMP_num(s->ctx->comp_methods);
         *(p++) = 1 + j;
         for (i = 0; i < j; i++) {
             comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
             *(p++) = comp->id;
         }
         *(p++) = 0;             /* Add the NULL method */
 
 #ifndef OPENSSL_NO_TLSEXT
         /* TLS extensions */
         if (ssl_prepare_clienthello_tlsext(s) <= 0) {
             SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
             goto err;
         }
         if ((p =
              ssl_add_clienthello_tlsext(s, p,
                                         buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
             NULL) {
             SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 #endif
 
         l = (p - d);
         d = buf;
 
         d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l);
 
         s->state = SSL3_ST_CW_CLNT_HELLO_B;
         /* number of bytes to write */
         s->init_num = p - buf;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_CW_CLNT_HELLO_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     return (-1);
 }
 
 static int dtls1_get_hello_verify(SSL *s)
 {
     int n, al, ok = 0;
     unsigned char *data;
     unsigned int cookie_len;
 
     n = s->method->ssl_get_message(s,
                                    DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A,
                                    DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B,
                                    -1, s->max_cert_list, &ok);
 
     if (!ok)
         return ((int)n);
 
     if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) {
         s->d1->send_cookie = 0;
         s->s3->tmp.reuse_message = 1;
         return (1);
     }
 
     data = (unsigned char *)s->init_msg;
 
     if ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff))) {
         SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION);
         s->version = (s->version & 0xff00) | data[1];
         al = SSL_AD_PROTOCOL_VERSION;
         goto f_err;
     }
     data += 2;
 
     cookie_len = *(data++);
     if (cookie_len > sizeof(s->d1->cookie)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         goto f_err;
     }
 
     memcpy(s->d1->cookie, data, cookie_len);
     s->d1->cookie_len = cookie_len;
 
     s->d1->send_cookie = 1;
     return 1;
 
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
     s->state = SSL_ST_ERR;
     return -1;
 }
 
 int dtls1_send_client_key_exchange(SSL *s)
 {
     unsigned char *p, *d;
     int n;
     unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
     unsigned char *q;
     EVP_PKEY *pkey = NULL;
 #endif
 #ifndef OPENSSL_NO_KRB5
     KSSL_ERR kssl_err;
 #endif                          /* OPENSSL_NO_KRB5 */
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *clnt_ecdh = NULL;
     const EC_POINT *srvr_ecpoint = NULL;
     EVP_PKEY *srvr_pub_pkey = NULL;
     unsigned char *encodedPoint = NULL;
     int encoded_pt_len = 0;
     BN_CTX *bn_ctx = NULL;
 #endif
 
     if (s->state == SSL3_ST_CW_KEY_EXCH_A) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[DTLS1_HM_HEADER_LENGTH]);
 
         alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
         /* Fool emacs indentation */
         if (0) {
         }
 #ifndef OPENSSL_NO_RSA
         else if (alg_k & SSL_kRSA) {
             RSA *rsa;
             unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 
             if (s->session->sess_cert == NULL) {
                 /*
                  * We should always have a server certificate with SSL_kRSA.
                  */
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if (s->session->sess_cert->peer_rsa_tmp != NULL)
                 rsa = s->session->sess_cert->peer_rsa_tmp;
             else {
                 pkey =
                     X509_get_pubkey(s->session->
                                     sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].
                                     x509);
                 if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA)
                     || (pkey->pkey.rsa == NULL)) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_INTERNAL_ERROR);
                     goto err;
                 }
                 rsa = pkey->pkey.rsa;
                 EVP_PKEY_free(pkey);
             }
 
             tmp_buf[0] = s->client_version >> 8;
             tmp_buf[1] = s->client_version & 0xff;
             if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0)
                 goto err;
 
             s->session->master_key_length = sizeof tmp_buf;
 
             q = p;
             /* Fix buf for TLS and [incidentally] DTLS */
             if (s->version > SSL3_VERSION)
                 p += 2;
             n = RSA_public_encrypt(sizeof tmp_buf,
                                    tmp_buf, p, rsa, RSA_PKCS1_PADDING);
 # ifdef PKCS1_CHECK
             if (s->options & SSL_OP_PKCS1_CHECK_1)
                 p[1]++;
             if (s->options & SSL_OP_PKCS1_CHECK_2)
                 tmp_buf[0] = 0x70;
 # endif
             if (n <= 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_BAD_RSA_ENCRYPT);
                 goto err;
             }
 
             /* Fix buf for TLS and [incidentally] DTLS */
             if (s->version > SSL3_VERSION) {
                 s2n(n, q);
                 n += 2;
             }
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             tmp_buf,
                                                             sizeof tmp_buf);
             OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
         }
 #endif
 #ifndef OPENSSL_NO_KRB5
         else if (alg_k & SSL_kKRB5) {
             krb5_error_code krb5rc;
             KSSL_CTX *kssl_ctx = s->kssl_ctx;
             /*  krb5_data   krb5_ap_req;  */
             krb5_data *enc_ticket;
             krb5_data authenticator, *authp = NULL;
             EVP_CIPHER_CTX ciph_ctx;
             const EVP_CIPHER *enc = NULL;
             unsigned char iv[EVP_MAX_IV_LENGTH];
             unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
             unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH];
             int padl, outl = sizeof(epms);
 
             EVP_CIPHER_CTX_init(&ciph_ctx);
 
 # ifdef KSSL_DEBUG
             printf("ssl3_send_client_key_exchange(%lx & %lx)\n",
                    alg_k, SSL_kKRB5);
 # endif                         /* KSSL_DEBUG */
 
             authp = NULL;
 # ifdef KRB5SENDAUTH
             if (KRB5SENDAUTH)
                 authp = &authenticator;
 # endif                         /* KRB5SENDAUTH */
 
             krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err);
             enc = kssl_map_enc(kssl_ctx->enctype);
             if (enc == NULL)
                 goto err;
 # ifdef KSSL_DEBUG
             {
                 printf("kssl_cget_tkt rtn %d\n", krb5rc);
                 if (krb5rc && kssl_err.text)
                     printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text);
             }
 # endif                         /* KSSL_DEBUG */
 
             if (krb5rc) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason);
                 goto err;
             }
 
             /*-
              *   20010406 VRS - Earlier versions used KRB5 AP_REQ
             **  in place of RFC 2712 KerberosWrapper, as in:
             **
             **  Send ticket (copy to *p, set n = length)
             **  n = krb5_ap_req.length;
             **  memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
             **  if (krb5_ap_req.data)
             **    kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
             **
             **  Now using real RFC 2712 KerberosWrapper
             **  (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
             **  Note: 2712 "opaque" types are here replaced
             **  with a 2-byte length followed by the value.
             **  Example:
             **  KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
             **  Where "xx xx" = length bytes.  Shown here with
             **  optional authenticator omitted.
             */
 
             /*  KerberosWrapper.Ticket              */
             s2n(enc_ticket->length, p);
             memcpy(p, enc_ticket->data, enc_ticket->length);
             p += enc_ticket->length;
             n = enc_ticket->length + 2;
 
             /*  KerberosWrapper.Authenticator       */
             if (authp && authp->length) {
                 s2n(authp->length, p);
                 memcpy(p, authp->data, authp->length);
                 p += authp->length;
                 n += authp->length + 2;
 
                 free(authp->data);
                 authp->data = NULL;
                 authp->length = 0;
             } else {
                 s2n(0, p);      /* null authenticator length */
                 n += 2;
             }
 
             if (RAND_bytes(tmp_buf, sizeof tmp_buf) <= 0)
                 goto err;
 
             /*-
              *  20010420 VRS.  Tried it this way; failed.
              *      EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
              *      EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
              *                              kssl_ctx->length);
              *      EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
              */
 
             memset(iv, 0, sizeof iv); /* per RFC 1510 */
             EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv);
             EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf,
                               sizeof tmp_buf);
             EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl);
             outl += padl;
             if (outl > (int)sizeof epms) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
             /*  KerberosWrapper.EncryptedPreMasterSecret    */
             s2n(outl, p);
             memcpy(p, epms, outl);
             p += outl;
             n += outl + 2;
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             tmp_buf,
                                                             sizeof tmp_buf);
 
             OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
             OPENSSL_cleanse(epms, outl);
         }
 #endif
 #ifndef OPENSSL_NO_DH
         else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) {
             DH *dh_srvr, *dh_clnt;
 
             if (s->session->sess_cert == NULL) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNEXPECTED_MESSAGE);
                 goto err;
             }
 
             if (s->session->sess_cert->peer_dh_tmp != NULL)
                 dh_srvr = s->session->sess_cert->peer_dh_tmp;
             else {
                 /* we get them from the cert */
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
                 goto err;
             }
 
             /* generate a new random key */
             if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
             if (!DH_generate_key(dh_clnt)) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
 
             /*
              * use the 'p' output buffer for the DH key, but make sure to
              * clear it out afterwards
              */
 
             n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt);
 
             if (n <= 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
 
             /* generate master key from the result */
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             p, n);
             /* clean up */
             memset(p, 0, n);
 
             /* send off the data */
             n = BN_num_bytes(dh_clnt->pub_key);
             s2n(n, p);
             BN_bn2bin(dh_clnt->pub_key, p);
             n += 2;
 
             DH_free(dh_clnt);
 
             /* perhaps clean things up a bit EAY EAY EAY EAY */
         }
 #endif
 #ifndef OPENSSL_NO_ECDH
         else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) {
             const EC_GROUP *srvr_group = NULL;
             EC_KEY *tkey;
             int ecdh_clnt_cert = 0;
             int field_size = 0;
 
             if (s->session->sess_cert == NULL) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNEXPECTED_MESSAGE);
                 goto err;
             }
 
             /*
              * Did we send out the client's ECDH share for use in premaster
              * computation as part of client certificate? If so, set
              * ecdh_clnt_cert to 1.
              */
             if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) {
                 /*
                  * XXX: For now, we do not support client authentication
                  * using ECDH certificates. To add such support, one needs to
                  * add code that checks for appropriate conditions and sets
                  * ecdh_clnt_cert to 1. For example, the cert have an ECC key
                  * on the same curve as the server's and the key should be
                  * authorized for key agreement. One also needs to add code
                  * in ssl3_connect to skip sending the certificate verify
                  * message. if ((s->cert->key->privatekey != NULL) &&
                  * (s->cert->key->privatekey->type == EVP_PKEY_EC) && ...)
                  * ecdh_clnt_cert = 1;
                  */
             }
 
             if (s->session->sess_cert->peer_ecdh_tmp != NULL) {
                 tkey = s->session->sess_cert->peer_ecdh_tmp;
             } else {
                 /* Get the Server Public Key from Cert */
                 srvr_pub_pkey =
                     X509_get_pubkey(s->session->
                                     sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
                 if ((srvr_pub_pkey == NULL)
                     || (srvr_pub_pkey->type != EVP_PKEY_EC)
                     || (srvr_pub_pkey->pkey.ec == NULL)) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_INTERNAL_ERROR);
                     goto err;
                 }
 
                 tkey = srvr_pub_pkey->pkey.ec;
             }
 
             srvr_group = EC_KEY_get0_group(tkey);
             srvr_ecpoint = EC_KEY_get0_public_key(tkey);
 
             if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if ((clnt_ecdh = EC_KEY_new()) == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
             if (ecdh_clnt_cert) {
                 /*
                  * Reuse key info from our certificate We only need our
                  * private key to perform the ECDH computation.
                  */
                 const BIGNUM *priv_key;
                 tkey = s->cert->key->privatekey->pkey.ec;
                 priv_key = EC_KEY_get0_private_key(tkey);
                 if (priv_key == NULL) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
                     goto err;
                 }
                 if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_EC_LIB);
                     goto err;
                 }
             } else {
                 /* Generate a new ECDH key pair */
                 if (!(EC_KEY_generate_key(clnt_ecdh))) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_ECDH_LIB);
                     goto err;
                 }
             }
 
             /*
              * use the 'p' output buffer for the ECDH key, but make sure to
              * clear it out afterwards
              */
 
             field_size = EC_GROUP_get_degree(srvr_group);
             if (field_size <= 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
             n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint,
                                  clnt_ecdh, NULL);
             if (n <= 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             /* generate master key from the result */
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             p, n);
 
             memset(p, 0, n);    /* clean up */
 
             if (ecdh_clnt_cert) {
                 /* Send empty client key exch message */
                 n = 0;
             } else {
                 /*
                  * First check the size of encoding and allocate memory
                  * accordingly.
                  */
                 encoded_pt_len =
                     EC_POINT_point2oct(srvr_group,
                                        EC_KEY_get0_public_key(clnt_ecdh),
                                        POINT_CONVERSION_UNCOMPRESSED,
                                        NULL, 0, NULL);
 
                 encodedPoint = (unsigned char *)
                     OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char));
                 bn_ctx = BN_CTX_new();
                 if ((encodedPoint == NULL) || (bn_ctx == NULL)) {
                     SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
                     goto err;
                 }
 
                 /* Encode the public key */
                 n = EC_POINT_point2oct(srvr_group,
                                        EC_KEY_get0_public_key(clnt_ecdh),
                                        POINT_CONVERSION_UNCOMPRESSED,
                                        encodedPoint, encoded_pt_len, bn_ctx);
 
                 *p = n;         /* length of encoded point */
                 /* Encoded point will be copied here */
                 p += 1;
                 /* copy the point */
                 memcpy((unsigned char *)p, encodedPoint, n);
                 /* increment n to account for length field */
                 n += 1;
             }
 
             /* Free allocated memory */
             BN_CTX_free(bn_ctx);
             if (encodedPoint != NULL)
                 OPENSSL_free(encodedPoint);
             if (clnt_ecdh != NULL)
                 EC_KEY_free(clnt_ecdh);
             EVP_PKEY_free(srvr_pub_pkey);
         }
 #endif                          /* !OPENSSL_NO_ECDH */
 
 #ifndef OPENSSL_NO_PSK
         else if (alg_k & SSL_kPSK) {
             char identity[PSK_MAX_IDENTITY_LEN];
             unsigned char *t = NULL;
             unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4];
             unsigned int pre_ms_len = 0, psk_len = 0;
             int psk_err = 1;
 
             n = 0;
             if (s->psk_client_callback == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_PSK_NO_CLIENT_CB);
                 goto err;
             }
 
             psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint,
                                              identity, PSK_MAX_IDENTITY_LEN,
                                              psk_or_pre_ms,
                                              sizeof(psk_or_pre_ms));
             if (psk_len > PSK_MAX_PSK_LEN) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto psk_err;
             } else if (psk_len == 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_PSK_IDENTITY_NOT_FOUND);
                 goto psk_err;
             }
 
             /* create PSK pre_master_secret */
             pre_ms_len = 2 + psk_len + 2 + psk_len;
             t = psk_or_pre_ms;
             memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len);
             s2n(psk_len, t);
             memset(t, 0, psk_len);
             t += psk_len;
             s2n(psk_len, t);
 
             if (s->session->psk_identity_hint != NULL)
                 OPENSSL_free(s->session->psk_identity_hint);
             s->session->psk_identity_hint =
                 BUF_strdup(s->ctx->psk_identity_hint);
             if (s->ctx->psk_identity_hint != NULL
                 && s->session->psk_identity_hint == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto psk_err;
             }
 
             if (s->session->psk_identity != NULL)
                 OPENSSL_free(s->session->psk_identity);
             s->session->psk_identity = BUF_strdup(identity);
             if (s->session->psk_identity == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto psk_err;
             }
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             psk_or_pre_ms,
                                                             pre_ms_len);
             n = strlen(identity);
             s2n(n, p);
             memcpy(p, identity, n);
             n += 2;
             psk_err = 0;
  psk_err:
             OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN);
             OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
             if (psk_err != 0) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 goto err;
             }
         }
 #endif
         else {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
             SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,
                    ERR_R_INTERNAL_ERROR);
             goto err;
         }
 
         d = dtls1_set_message_header(s, d,
                                      SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n);
         /*-
          *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE;
          l2n3(n,d);
          l2n(s->d1->handshake_write_seq,d);
          s->d1->handshake_write_seq++;
         */
 
         s->state = SSL3_ST_CW_KEY_EXCH_B;
         /* number of bytes to write */
         s->init_num = n + DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_CW_KEY_EXCH_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
  err:
 #ifndef OPENSSL_NO_ECDH
     BN_CTX_free(bn_ctx);
     if (encodedPoint != NULL)
         OPENSSL_free(encodedPoint);
     if (clnt_ecdh != NULL)
         EC_KEY_free(clnt_ecdh);
     EVP_PKEY_free(srvr_pub_pkey);
 #endif
     return (-1);
 }
 
 int dtls1_send_client_verify(SSL *s)
 {
     unsigned char *p, *d;
     unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
     EVP_PKEY *pkey;
 #ifndef OPENSSL_NO_RSA
     unsigned u = 0;
 #endif
     unsigned long n;
 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA)
     int j;
 #endif
 
     if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[DTLS1_HM_HEADER_LENGTH]);
         pkey = s->cert->key->privatekey;
 
         s->method->ssl3_enc->cert_verify_mac(s,
                                              NID_sha1,
                                              &(data[MD5_DIGEST_LENGTH]));
 
 #ifndef OPENSSL_NO_RSA
         if (pkey->type == EVP_PKEY_RSA) {
             s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0]));
             if (RSA_sign(NID_md5_sha1, data,
                          MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
                          &(p[2]), &u, pkey->pkey.rsa) <= 0) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB);
                 goto err;
             }
             s2n(u, p);
             n = u + 2;
         } else
 #endif
 #ifndef OPENSSL_NO_DSA
         if (pkey->type == EVP_PKEY_DSA) {
             if (!DSA_sign(pkey->save_type,
                           &(data[MD5_DIGEST_LENGTH]),
                           SHA_DIGEST_LENGTH, &(p[2]),
                           (unsigned int *)&j, pkey->pkey.dsa)) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB);
                 goto err;
             }
             s2n(j, p);
             n = j + 2;
         } else
 #endif
 #ifndef OPENSSL_NO_ECDSA
         if (pkey->type == EVP_PKEY_EC) {
             if (!ECDSA_sign(pkey->save_type,
                             &(data[MD5_DIGEST_LENGTH]),
                             SHA_DIGEST_LENGTH, &(p[2]),
                             (unsigned int *)&j, pkey->pkey.ec)) {
                 SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB);
                 goto err;
             }
             s2n(j, p);
             n = j + 2;
         } else
 #endif
         {
             SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 
         d = dtls1_set_message_header(s, d,
                                      SSL3_MT_CERTIFICATE_VERIFY, n, 0, n);
 
         s->init_num = (int)n + DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
 
         s->state = SSL3_ST_CW_CERT_VRFY_B;
     }
 
     /* s->state = SSL3_ST_CW_CERT_VRFY_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     return (-1);
 }
 
 int dtls1_send_client_certificate(SSL *s)
 {
     X509 *x509 = NULL;
     EVP_PKEY *pkey = NULL;
     int i;
     unsigned long l;
 
     if (s->state == SSL3_ST_CW_CERT_A) {
         if ((s->cert == NULL) ||
             (s->cert->key->x509 == NULL) ||
             (s->cert->key->privatekey == NULL))
             s->state = SSL3_ST_CW_CERT_B;
         else
             s->state = SSL3_ST_CW_CERT_C;
     }
 
     /* We need to get a client cert */
     if (s->state == SSL3_ST_CW_CERT_B) {
         /*
          * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
          * return(-1); We then get retied later
          */
         i = 0;
         i = ssl_do_client_cert_cb(s, &x509, &pkey);
         if (i < 0) {
             s->rwstate = SSL_X509_LOOKUP;
             return (-1);
         }
         s->rwstate = SSL_NOTHING;
         if ((i == 1) && (pkey != NULL) && (x509 != NULL)) {
             s->state = SSL3_ST_CW_CERT_B;
             if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey))
                 i = 0;
         } else if (i == 1) {
             i = 0;
             SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE,
                    SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
         }
 
         if (x509 != NULL)
             X509_free(x509);
         if (pkey != NULL)
             EVP_PKEY_free(pkey);
         if (i == 0) {
             if (s->version == SSL3_VERSION) {
                 s->s3->tmp.cert_req = 0;
                 ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
                 return (1);
             } else {
                 s->s3->tmp.cert_req = 2;
             }
         }
 
         /* Ok, we have a cert */
         s->state = SSL3_ST_CW_CERT_C;
     }
 
     if (s->state == SSL3_ST_CW_CERT_C) {
         s->state = SSL3_ST_CW_CERT_D;
         l = dtls1_output_cert_chain(s,
                                     (s->s3->tmp.cert_req ==
                                      2) ? NULL : s->cert->key->x509);
         if (!l) {
             SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
             return 0;
         }
         s->init_num = (int)l;
         s->init_off = 0;
 
         /* set header called by dtls1_output_cert_chain() */
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
     /* SSL3_ST_CW_CERT_D */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/d1_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/d1_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/d1_lib.c	(revision 306191)
@@ -1,511 +1,526 @@
 /* ssl/d1_lib.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).
  *
  */
 
 #include <stdio.h>
 #define USE_SOCKETS
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 
 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS)
 # include <sys/timeb.h>
 #endif
 
 static void get_current_time(struct timeval *t);
 const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT;
 int dtls1_listen(SSL *s, struct sockaddr *client);
 
 SSL3_ENC_METHOD DTLSv1_enc_data = {
     dtls1_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,
     tls1_export_keying_material,
 };
 
 long dtls1_default_timeout(void)
 {
     /*
      * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for
      * http, the cache would over fill
      */
     return (60 * 60 * 2);
 }
 
 int dtls1_new(SSL *s)
 {
     DTLS1_STATE *d1;
 
     if (!ssl3_new(s))
         return (0);
     if ((d1 = OPENSSL_malloc(sizeof *d1)) == NULL)
         return (0);
     memset(d1, 0, sizeof *d1);
 
     /* d1->handshake_epoch=0; */
 
     d1->unprocessed_rcds.q = pqueue_new();
     d1->processed_rcds.q = pqueue_new();
     d1->buffered_messages = pqueue_new();
     d1->sent_messages = pqueue_new();
     d1->buffered_app_data.q = pqueue_new();
 
     if (s->server) {
         d1->cookie_len = sizeof(s->d1->cookie);
     }
 
     d1->link_mtu = 0;
     d1->mtu = 0;
 
     if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q
         || !d1->buffered_messages || !d1->sent_messages
         || !d1->buffered_app_data.q) {
         if (d1->unprocessed_rcds.q)
             pqueue_free(d1->unprocessed_rcds.q);
         if (d1->processed_rcds.q)
             pqueue_free(d1->processed_rcds.q);
         if (d1->buffered_messages)
             pqueue_free(d1->buffered_messages);
         if (d1->sent_messages)
             pqueue_free(d1->sent_messages);
         if (d1->buffered_app_data.q)
             pqueue_free(d1->buffered_app_data.q);
         OPENSSL_free(d1);
         return (0);
     }
 
     s->d1 = d1;
     s->method->ssl_clear(s);
     return (1);
 }
 
 static void dtls1_clear_queues(SSL *s)
 {
     pitem *item = NULL;
-    hm_fragment *frag = NULL;
     DTLS1_RECORD_DATA *rdata;
 
     while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) {
         rdata = (DTLS1_RECORD_DATA *)item->data;
         if (rdata->rbuf.buf) {
             OPENSSL_free(rdata->rbuf.buf);
         }
         OPENSSL_free(item->data);
         pitem_free(item);
     }
 
     while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) {
         rdata = (DTLS1_RECORD_DATA *)item->data;
         if (rdata->rbuf.buf) {
             OPENSSL_free(rdata->rbuf.buf);
         }
         OPENSSL_free(item->data);
         pitem_free(item);
     }
 
+    while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
+        rdata = (DTLS1_RECORD_DATA *)item->data;
+        if (rdata->rbuf.buf) {
+            OPENSSL_free(rdata->rbuf.buf);
+        }
+        OPENSSL_free(item->data);
+        pitem_free(item);
+    }
+
+    dtls1_clear_received_buffer(s);
+    dtls1_clear_sent_buffer(s);
+}
+
+void dtls1_clear_received_buffer(SSL *s)
+{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
     while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
         frag = (hm_fragment *)item->data;
         dtls1_hm_fragment_free(frag);
         pitem_free(item);
     }
+}
 
+void dtls1_clear_sent_buffer(SSL *s)
+{
+    pitem *item = NULL;
+    hm_fragment *frag = NULL;
+
     while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
         frag = (hm_fragment *)item->data;
         dtls1_hm_fragment_free(frag);
         pitem_free(item);
     }
-
-    while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
-        rdata = (DTLS1_RECORD_DATA *)item->data;
-        if (rdata->rbuf.buf) {
-            OPENSSL_free(rdata->rbuf.buf);
-        }
-        OPENSSL_free(item->data);
-        pitem_free(item);
-    }
 }
 
+
 void dtls1_free(SSL *s)
 {
     ssl3_free(s);
 
     dtls1_clear_queues(s);
 
     pqueue_free(s->d1->unprocessed_rcds.q);
     pqueue_free(s->d1->processed_rcds.q);
     pqueue_free(s->d1->buffered_messages);
     pqueue_free(s->d1->sent_messages);
     pqueue_free(s->d1->buffered_app_data.q);
 
     OPENSSL_free(s->d1);
     s->d1 = NULL;
 }
 
 void dtls1_clear(SSL *s)
 {
     pqueue unprocessed_rcds;
     pqueue processed_rcds;
     pqueue buffered_messages;
     pqueue sent_messages;
     pqueue buffered_app_data;
     unsigned int mtu;
     unsigned int link_mtu;
 
     if (s->d1) {
         unprocessed_rcds = s->d1->unprocessed_rcds.q;
         processed_rcds = s->d1->processed_rcds.q;
         buffered_messages = s->d1->buffered_messages;
         sent_messages = s->d1->sent_messages;
         buffered_app_data = s->d1->buffered_app_data.q;
         mtu = s->d1->mtu;
         link_mtu = s->d1->link_mtu;
 
         dtls1_clear_queues(s);
 
         memset(s->d1, 0, sizeof(*(s->d1)));
 
         if (s->server) {
             s->d1->cookie_len = sizeof(s->d1->cookie);
         }
 
         if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) {
             s->d1->mtu = mtu;
             s->d1->link_mtu = link_mtu;
         }
 
         s->d1->unprocessed_rcds.q = unprocessed_rcds;
         s->d1->processed_rcds.q = processed_rcds;
         s->d1->buffered_messages = buffered_messages;
         s->d1->sent_messages = sent_messages;
         s->d1->buffered_app_data.q = buffered_app_data;
     }
 
     ssl3_clear(s);
     if (s->options & SSL_OP_CISCO_ANYCONNECT)
         s->version = DTLS1_BAD_VER;
     else
         s->version = DTLS1_VERSION;
 }
 
 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
     int ret = 0;
 
     switch (cmd) {
     case DTLS_CTRL_GET_TIMEOUT:
         if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) {
             ret = 1;
         }
         break;
     case DTLS_CTRL_HANDLE_TIMEOUT:
         ret = dtls1_handle_timeout(s);
         break;
     case DTLS_CTRL_LISTEN:
         ret = dtls1_listen(s, parg);
         break;
     case SSL_CTRL_CHECK_PROTO_VERSION:
         /*
          * For library-internal use; checks that the current protocol is the
          * highest enabled version (according to s->ctx->method, as version
          * negotiation may have changed s->method).
          */
 #if DTLS_MAX_VERSION != DTLS1_VERSION
 # error Code needs update for DTLS_method() support beyond DTLS1_VERSION.
 #endif
         /*
          * Just one protocol version is supported so far; fail closed if the
          * version is not as expected.
          */
         return s->version == DTLS_MAX_VERSION;
     case DTLS_CTRL_SET_LINK_MTU:
         if (larg < (long)dtls1_link_min_mtu())
             return 0;
         s->d1->link_mtu = larg;
         return 1;
     case DTLS_CTRL_GET_LINK_MIN_MTU:
         return (long)dtls1_link_min_mtu();
     case SSL_CTRL_SET_MTU:
         /*
          *  We may not have a BIO set yet so can't call dtls1_min_mtu()
          *  We'll have to make do with dtls1_link_min_mtu() and max overhead
          */
         if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD)
             return 0;
         s->d1->mtu = larg;
         return larg;
     default:
         ret = ssl3_ctrl(s, cmd, larg, parg);
         break;
     }
     return (ret);
 }
 
 /*
  * As it's impossible to use stream ciphers in "datagram" mode, this
  * simple filter is designed to disengage them in DTLS. Unfortunately
  * there is no universal way to identify stream SSL_CIPHER, so we have
  * to explicitly list their SSL_* codes. Currently RC4 is the only one
  * available, but if new ones emerge, they will have to be added...
  */
 const SSL_CIPHER *dtls1_get_cipher(unsigned int u)
 {
     const SSL_CIPHER *ciph = ssl3_get_cipher(u);
 
     if (ciph != NULL) {
         if (ciph->algorithm_enc == SSL_RC4)
             return NULL;
     }
 
     return ciph;
 }
 
 void dtls1_start_timer(SSL *s)
 {
 #ifndef OPENSSL_NO_SCTP
     /* Disable timer for SCTP */
     if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
         memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
         return;
     }
 #endif
 
     /* If timer is not set, initialize duration with 1 second */
     if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
         s->d1->timeout_duration = 1;
     }
 
     /* Set timeout to current time */
     get_current_time(&(s->d1->next_timeout));
 
     /* Add duration to current time */
     s->d1->next_timeout.tv_sec += s->d1->timeout_duration;
     BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
              &(s->d1->next_timeout));
 }
 
 struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft)
 {
     struct timeval timenow;
 
     /* If no timeout is set, just return NULL */
     if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) {
         return NULL;
     }
 
     /* Get current time */
     get_current_time(&timenow);
 
     /* If timer already expired, set remaining time to 0 */
     if (s->d1->next_timeout.tv_sec < timenow.tv_sec ||
         (s->d1->next_timeout.tv_sec == timenow.tv_sec &&
          s->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
         memset(timeleft, 0, sizeof(struct timeval));
         return timeleft;
     }
 
     /* Calculate time left until timer expires */
     memcpy(timeleft, &(s->d1->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 remaining time is less than 15 ms, set it to 0 to prevent issues
      * because of small devergences with socket timeouts.
      */
     if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) {
         memset(timeleft, 0, sizeof(struct timeval));
     }
 
     return timeleft;
 }
 
 int dtls1_is_timer_expired(SSL *s)
 {
     struct timeval timeleft;
 
     /* Get time left until timeout, return false if no timer running */
     if (dtls1_get_timeout(s, &timeleft) == NULL) {
         return 0;
     }
 
     /* Return false if timer is not expired yet */
     if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
         return 0;
     }
 
     /* Timer expired, so return true */
     return 1;
 }
 
 void dtls1_double_timeout(SSL *s)
 {
     s->d1->timeout_duration *= 2;
     if (s->d1->timeout_duration > 60)
         s->d1->timeout_duration = 60;
     dtls1_start_timer(s);
 }
 
 void dtls1_stop_timer(SSL *s)
 {
     /* Reset everything */
     memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
     memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
     s->d1->timeout_duration = 1;
     BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
              &(s->d1->next_timeout));
     /* Clear retransmission buffer */
-    dtls1_clear_record_buffer(s);
+    dtls1_clear_sent_buffer(s);
 }
 
 int dtls1_check_timeout_num(SSL *s)
 {
     unsigned int mtu;
 
     s->d1->timeout.num_alerts++;
 
     /* Reduce MTU after 2 unsuccessful retransmissions */
     if (s->d1->timeout.num_alerts > 2
         && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) {
         mtu =
             BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
                      NULL);
         if (mtu < s->d1->mtu)
             s->d1->mtu = mtu;
     }
 
     if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) {
         /* fail the connection, enough alerts have been sent */
         SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED);
         return -1;
     }
 
     return 0;
 }
 
 int dtls1_handle_timeout(SSL *s)
 {
     /* if no timer is expired, don't do anything */
     if (!dtls1_is_timer_expired(s)) {
         return 0;
     }
 
     dtls1_double_timeout(s);
 
     if (dtls1_check_timeout_num(s) < 0)
         return -1;
 
     s->d1->timeout.read_timeouts++;
     if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) {
         s->d1->timeout.read_timeouts = 1;
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     if (s->tlsext_hb_pending) {
         s->tlsext_hb_pending = 0;
         return dtls1_heartbeat(s);
     }
 #endif
 
     dtls1_start_timer(s);
     return dtls1_retransmit_buffered_messages(s);
 }
 
 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
 }
 
 int dtls1_listen(SSL *s, struct sockaddr *client)
 {
     int ret;
 
     /* Ensure there is no state left over from a previous invocation */
     SSL_clear(s);
 
     SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE);
     s->d1->listen = 1;
 
     ret = SSL_accept(s);
     if (ret <= 0)
         return ret;
 
     (void)BIO_dgram_get_peer(SSL_get_rbio(s), client);
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/d1_pkt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/d1_pkt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/d1_pkt.c	(revision 306191)
@@ -1,1905 +1,1967 @@
 /* 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 int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
 
 /* 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 -1;
     }
 
     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;
 
 #ifndef OPENSSL_NO_SCTP
     /* Store bio_dgram_sctp_rcvinfo struct */
     if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
         (s->state == SSL3_ST_SR_FINISHED_A
          || s->state == SSL3_ST_CR_FINISHED_A)) {
         BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO,
                  sizeof(rdata->recordinfo), &rdata->recordinfo);
     }
 #endif
 
     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);
         if (rdata->rbuf.buf != NULL)
             OPENSSL_free(rdata->rbuf.buf);
         OPENSSL_free(rdata);
         pitem_free(item);
         return (-1);
     }
 
     /* insert should not fail, since duplicates are dropped */
     if (pqueue_insert(queue->q, item) == NULL) {
         SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR);
         if (rdata->rbuf.buf != NULL)
             OPENSSL_free(rdata->rbuf.buf);
         OPENSSL_free(rdata);
         pitem_free(item);
         return (-1);
     }
 
     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;
+    SSL3_BUFFER *rb;
+    SSL3_RECORD *rr;
+    DTLS1_BITMAP *bitmap;
+    unsigned int is_next_epoch;
+    int replayok = 1;
 
     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. */
+            return 1;         /* Nothing to do. */
 
+        rr = &s->s3->rrec;
+        rb = &s->s3->rbuf;
+
+        if (rb->left > 0) {
+            /*
+             * We've still got data from the current packet to read. There could
+             * be a record from the new epoch in it - so don't overwrite it
+             * with the unprocessed records yet (we'll do it when we've
+             * finished reading the current packet).
+             */
+            return 1;
+        }
+
+
         /* Process all the records. */
         while (pqueue_peek(s->d1->unprocessed_rcds.q)) {
             dtls1_get_unprocessed_record(s);
-            if (!dtls1_process_record(s))
-                return (0);
+            bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+            if (bitmap == NULL) {
+                /*
+                 * Should not happen. This will only ever be NULL when the
+                 * current record is from a different epoch. But that cannot
+                 * be the case because we already checked the epoch above
+                 */
+                 SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS,
+                        ERR_R_INTERNAL_ERROR);
+                 return 0;
+            }
+#ifndef OPENSSL_NO_SCTP
+            /* Only do replay check if no SCTP bio */
+            if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
+#endif
+            {
+                /*
+                 * Check whether this is a repeat, or aged record. We did this
+                 * check once already when we first received the record - but
+                 * we might have updated the window since then due to
+                 * records we subsequently processed.
+                 */
+                replayok = dtls1_record_replay_check(s, bitmap);
+            }
+
+            if (!replayok || !dtls1_process_record(s, bitmap)) {
+                /* dump this record */
+                rr->length = 0;
+                s->packet_length = 0;
+                continue;
+            }
+
             if (dtls1_buffer_record(s, &(s->d1->processed_rcds),
                                     s->s3->rrec.seq_num) < 0)
-                return -1;
+                return 0;
         }
     }
 
     /*
      * 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);
+    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 we're not (re)negotiating, nothing buffered */
     if (!SSL_in_init(s))
         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)
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
 {
     int i, al;
     int enc_err;
     SSL_SESSION *sess;
     SSL3_RECORD *rr;
     unsigned int mac_size, orig_len;
     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);
     /*-
      * enc_err is:
      *    0: (in non-constant time) if the record is publically invalid.
      *    1: if the padding is valid
      *   -1: if the padding is invalid
      */
     if (enc_err == 0) {
         /* For DTLS we simply ignore bad packets. */
         rr->length = 0;
         s->packet_length = 0;
         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) && (EVP_MD_CTX_md(s->read_hash) != NULL)) {
         /* s->read_hash != NULL => mac_size != -1 */
         unsigned char *mac = NULL;
         unsigned char mac_tmp[EVP_MAX_MD_SIZE];
         mac_size = EVP_MD_CTX_size(s->read_hash);
         OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE);
 
         /*
          * kludge: *_cbc_remove_padding passes padding length in rr->type
          */
         orig_len = rr->length + ((unsigned int)rr->type >> 8);
 
         /*
          * orig_len is the length of the record before any padding was
          * removed. This is public information, as is the MAC in use,
          * therefore we can safely process the record in a different amount
          * of time if it's too short to possibly contain a MAC.
          */
         if (orig_len < mac_size ||
             /* CBC records must have a padding length byte too. */
             (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE &&
              orig_len < mac_size + 1)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
 
         if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) {
             /*
              * We update the length so that the TLS header bytes can be
              * constructed correctly but we need to extract the MAC in
              * constant time from within the record, without leaking the
              * contents of the padding bytes.
              */
             mac = mac_tmp;
             ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len);
             rr->length -= mac_size;
         } else {
             /*
              * In this case there's no padding, so |orig_len| equals
              * |rec->length| and we checked that there's enough bytes for
              * |mac_size| above.
              */
             rr->length -= mac_size;
             mac = &rr->data[rr->length];
         }
 
         i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ );
         if (i < 0 || mac == NULL
             || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0)
             enc_err = -1;
         if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size)
             enc_err = -1;
     }
 
     if (enc_err < 0) {
         /* decryption failed, silently discard message */
         rr->length = 0;
         s->packet_length = 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;
+
+    /* Mark receipt of record. */
+    dtls1_record_bitmap_update(s, bitmap);
+
     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);
 
+ again:
     /*
      * The epoch may have changed.  If so, process all the pending records.
      * This is a non-blocking operation.
      */
-    if (dtls1_process_buffered_records(s) < 0)
+    if (!dtls1_process_buffered_records(s))
         return -1;
 
     /* 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);
         /* 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 */
     }
 #ifndef OPENSSL_NO_SCTP
     /* Only do replay check if no SCTP bio */
     if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) {
 #endif
         /*
          * 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 &&
               s->packet_length > DTLS1_RT_HEADER_LENGTH &&
               s->packet[DTLS1_RT_HEADER_LENGTH] == 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 */
         }
 #ifndef OPENSSL_NO_SCTP
     }
 #endif
 
     /* 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. However, do not buffer anything while
      * listening.
      */
     if (is_next_epoch) {
         if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) {
             if (dtls1_buffer_record
                 (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0)
                 return -1;
-            /* Mark receipt of record. */
-            dtls1_record_bitmap_update(s, bitmap);
         }
         rr->length = 0;
         s->packet_length = 0;
         goto again;
     }
 
-    if (!dtls1_process_record(s)) {
+    if (!dtls1_process_record(s, bitmap)) {
         rr->length = 0;
         s->packet_length = 0;   /* dump this record */
         goto again;             /* get another record */
     }
-    dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */
 
     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.
      */
 
 #ifndef OPENSSL_NO_SCTP
     /*
      * Continue handshake if it had to be interrupted to read app data with
      * SCTP.
      */
     if ((!s->in_handshake && SSL_in_init(s)) ||
         (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
          (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
           || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)
          && s->s3->in_read_app_data != 2))
 #else
     if (!s->in_handshake && SSL_in_init(s))
 #endif
     {
         /* 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) {
 #ifndef OPENSSL_NO_SCTP
             /* Restore bio_dgram_sctp_rcvinfo struct */
             if (BIO_dgram_is_sctp(SSL_get_rbio(s))) {
                 DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data;
                 BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO,
                          sizeof(rdata->recordinfo), &rdata->recordinfo);
             }
 #endif
 
             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;
         }
     }
 
     if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) {
         rr->length = 0;
         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.
          */
         if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) <
             0) {
             SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR);
             return -1;
         }
         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;
             }
         }
 #ifndef OPENSSL_NO_SCTP
         /*
          * We were about to renegotiate but had to read belated application
          * data first, so retry.
          */
         if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
             rr->type == SSL3_RT_APPLICATION_DATA &&
             (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
              || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) {
             s->rwstate = SSL_READING;
             BIO_clear_retry_flags(SSL_get_rbio(s));
             BIO_set_retry_read(SSL_get_rbio(s));
         }
 
         /*
          * We might had to delay a close_notify alert because of reordered
          * app data. If there was an alert and there is no message to read
          * anymore, finally set shutdown.
          */
         if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
             s->d1->shutdown_received
             && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
             s->shutdown |= SSL_RECEIVED_SHUTDOWN;
             return (0);
         }
 #endif
         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;
         }
 #ifndef OPENSSL_NO_HEARTBEATS
         else if (rr->type == TLS1_RT_HEARTBEAT) {
             dtls1_process_heartbeat(s);
 
             /* Exit and notify application to read again */
             rr->length = 0;
             s->rwstate = SSL_READING;
             BIO_clear_retry_flags(SSL_get_rbio(s));
             BIO_set_retry_read(SSL_get_rbio(s));
             return (-1);
         }
 #endif
         /* 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 f_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) {
             s->d1->handshake_read_seq++;
             s->new_session = 1;
             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 == SSL3_AL_WARNING) {
             s->s3->warn_alert = alert_descr;
             if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
 #ifndef OPENSSL_NO_SCTP
                 /*
                  * With SCTP and streams the socket may deliver app data
                  * after a close_notify alert. We have to check this first so
                  * that nothing gets discarded.
                  */
                 if (BIO_dgram_is_sctp(SSL_get_rbio(s)) &&
                     BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
                     s->d1->shutdown_received = 1;
                     s->rwstate = SSL_READING;
                     BIO_clear_retry_flags(SSL_get_rbio(s));
                     BIO_set_retry_read(SSL_get_rbio(s));
                     return -1;
                 }
 #endif
                 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 == SSL3_AL_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++;
 
 #ifndef OPENSSL_NO_SCTP
         /*
          * Remember that a CCS has been received, so that an old key of
          * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no
          * SCTP is used
          */
         BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL);
 #endif
 
         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) {
             if (dtls1_check_timeout_num(s) < 0)
                 return -1;
 
             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->renegotiate = 1;
             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;
 
 #ifndef OPENSSL_NO_SCTP
     /*
      * Check if we have to continue an interrupted handshake for reading
      * belated app data with SCTP.
      */
     if ((SSL_in_init(s) && !s->in_handshake) ||
         (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
          (s->state == DTLS1_SCTP_ST_SR_READ_SOCK
           || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)))
 #else
     if (SSL_in_init(s) && !s->in_handshake)
 #endif
     {
         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);
+        if (RAND_bytes(p, bs) <= 0)
+            goto err;
         /*
          * master IV and last CBC residue stand for the rest of randomness
          */
         wr->length += bs;
     }
 
     if (s->method->ssl3_enc->enc(s, 1) < 1)
         goto err;
 
     /* 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 */
+    /*
+     * Only HM and ALERT messages can be from the next epoch and only if we
+     * have already processed all of the unprocessed records from the last
+     * epoch
+     */
     else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
+             s->d1->unprocessed_rcds.epoch != s->d1->r_epoch &&
              (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));
+
+        /*
+         * We must not use any buffered messages received from the previous
+         * epoch
+         */
+        dtls1_clear_received_buffer(s);
     } 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);
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/d1_srvr.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/d1_srvr.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/d1_srvr.c	(revision 306191)
@@ -1,1759 +1,1763 @@
 /* ssl/d1_srvr.c */
 /*
  * DTLS implementation written by Nagendra Modadugu
  * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
  */
 /* ====================================================================
  * Copyright (c) 1999-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).
  *
  */
 /* 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"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 #include <openssl/md5.h>
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 
 static const SSL_METHOD *dtls1_get_server_method(int ver);
 static int dtls1_send_hello_verify_request(SSL *s);
 
 static const SSL_METHOD *dtls1_get_server_method(int ver)
 {
     if (ver == DTLS1_VERSION)
         return (DTLSv1_server_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_dtls1_meth_func(DTLSv1_server_method,
                           dtls1_accept,
                           ssl_undefined_function, dtls1_get_server_method)
 
 int dtls1_accept(SSL *s)
 {
     BUF_MEM *buf;
     unsigned long Time = (unsigned long)time(NULL);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
     unsigned long alg_k;
     int ret = -1;
     int new_state, state, skip = 0;
     int listen;
 #ifndef OPENSSL_NO_SCTP
     unsigned char sctpauthkey[64];
     char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)];
 #endif
 
     RAND_add(&Time, sizeof(Time), 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;
 
     listen = s->d1->listen;
 
     /* init things to blank */
     s->in_handshake++;
     if (!SSL_in_init(s) || SSL_in_before(s))
         SSL_clear(s);
 
     s->d1->listen = listen;
 #ifndef OPENSSL_NO_SCTP
     /*
      * Notify SCTP BIO socket to enter handshake mode and prevent stream
      * identifier other than 0. Will be ignored if no SCTP is used.
      */
     BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
              s->in_handshake, NULL);
 #endif
 
     if (s->cert == NULL) {
         SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET);
         return (-1);
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     /*
      * If we're awaiting a HeartbeatResponse, pretend we already got and
      * don't await it anymore, because Heartbeats don't make sense during
      * handshakes anyway.
      */
     if (s->tlsext_hb_pending) {
         dtls1_stop_timer(s);
         s->tlsext_hb_pending = 0;
         s->tlsext_hb_seq++;
     }
 #endif
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_RENEGOTIATE:
             s->renegotiate = 1;
             /* s->state=SSL_ST_ACCEPT; */
 
         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);
 
             if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) {
                 SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR);
                 return -1;
             }
             s->type = SSL_ST_ACCEPT;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     BUF_MEM_free(buf);
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
             }
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             s->init_num = 0;
             s->d1->change_cipher_spec_ok = 0;
             /*
              * Should have been reset by ssl3_get_finished, too.
              */
             s->s3->change_cipher_spec = 0;
 
             if (s->state != SSL_ST_RENEGOTIATE) {
                 /*
                  * Ok, we now need to push on a buffering BIO so that the
                  * output is sent in a way that TCP likes :-) ...but not with
                  * SCTP :-)
                  */
 #ifndef OPENSSL_NO_SCTP
                 if (!BIO_dgram_is_sctp(SSL_get_wbio(s)))
 #endif
                     if (!ssl_init_wbio_buffer(s, 1)) {
                         ret = -1;
                         s->state = SSL_ST_ERR;
                         goto end;
                     }
 
                 ssl3_init_finished_mac(s);
                 s->state = SSL3_ST_SR_CLNT_HELLO_A;
                 s->ctx->stats.sess_accept++;
             } else if (!s->s3->send_connection_binding &&
                        !(s->options &
                          SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
                 /*
                  * Server attempting to renegotiate with client that doesn't
                  * support secure renegotiation.
                  */
                 SSLerr(SSL_F_DTLS1_ACCEPT,
                        SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             } else {
                 /*
                  * s->state == SSL_ST_RENEGOTIATE, we will just send a
                  * HelloRequest
                  */
                 s->ctx->stats.sess_accept_renegotiate++;
                 s->state = SSL3_ST_SW_HELLO_REQ_A;
             }
 
             break;
 
         case SSL3_ST_SW_HELLO_REQ_A:
         case SSL3_ST_SW_HELLO_REQ_B:
 
             s->shutdown = 0;
-            dtls1_clear_record_buffer(s);
+            dtls1_clear_sent_buffer(s);
             dtls1_start_timer(s);
             ret = dtls1_send_hello_request(s);
             if (ret <= 0)
                 goto end;
             s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
             s->state = SSL3_ST_SW_FLUSH;
             s->init_num = 0;
 
             ssl3_init_finished_mac(s);
             break;
 
         case SSL3_ST_SW_HELLO_REQ_C:
             s->state = SSL_ST_OK;
             break;
 
         case SSL3_ST_SR_CLNT_HELLO_A:
         case SSL3_ST_SR_CLNT_HELLO_B:
         case SSL3_ST_SR_CLNT_HELLO_C:
 
             s->shutdown = 0;
             ret = ssl3_get_client_hello(s);
             if (ret <= 0)
                 goto end;
             dtls1_stop_timer(s);
 
             if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE))
                 s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A;
             else
                 s->state = SSL3_ST_SW_SRVR_HELLO_A;
 
             s->init_num = 0;
 
             /*
              * Reflect ClientHello sequence to remain stateless while
              * listening
              */
             if (listen) {
                 memcpy(s->s3->write_sequence, s->s3->read_sequence,
                        sizeof(s->s3->write_sequence));
             }
 
             /* If we're just listening, stop here */
             if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) {
                 ret = 2;
                 s->d1->listen = 0;
                 /*
                  * Set expected sequence numbers to continue the handshake.
                  */
                 s->d1->handshake_read_seq = 2;
                 s->d1->handshake_write_seq = 1;
                 s->d1->next_handshake_write_seq = 1;
                 goto end;
             }
 
             break;
 
         case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
         case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
 
             ret = dtls1_send_hello_verify_request(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_FLUSH;
             s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A;
 
             /* HelloVerifyRequest resets Finished MAC */
             if (s->version != DTLS1_BAD_VER)
                 ssl3_init_finished_mac(s);
             break;
 
 #ifndef OPENSSL_NO_SCTP
         case DTLS1_SCTP_ST_SR_READ_SOCK:
 
             if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) {
                 s->s3->in_read_app_data = 2;
                 s->rwstate = SSL_READING;
                 BIO_clear_retry_flags(SSL_get_rbio(s));
                 BIO_set_retry_read(SSL_get_rbio(s));
                 ret = -1;
                 goto end;
             }
 
             s->state = SSL3_ST_SR_FINISHED_A;
             break;
 
         case DTLS1_SCTP_ST_SW_WRITE_SOCK:
             ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s));
             if (ret < 0)
                 goto end;
 
             if (ret == 0) {
                 if (s->d1->next_state != SSL_ST_OK) {
                     s->s3->in_read_app_data = 2;
                     s->rwstate = SSL_READING;
                     BIO_clear_retry_flags(SSL_get_rbio(s));
                     BIO_set_retry_read(SSL_get_rbio(s));
                     ret = -1;
                     goto end;
                 }
             }
 
             s->state = s->d1->next_state;
             break;
 #endif
 
         case SSL3_ST_SW_SRVR_HELLO_A:
         case SSL3_ST_SW_SRVR_HELLO_B:
             s->renegotiate = 2;
             dtls1_start_timer(s);
             ret = dtls1_send_server_hello(s);
             if (ret <= 0)
                 goto end;
 
             if (s->hit) {
 #ifndef OPENSSL_NO_SCTP
                 /*
                  * Add new shared key for SCTP-Auth, will be ignored if no
                  * SCTP used.
                  */
                 snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
                          DTLS1_SCTP_AUTH_LABEL);
 
                 if (SSL_export_keying_material(s, sctpauthkey,
                         sizeof(sctpauthkey), labelbuffer,
                         sizeof(labelbuffer), NULL, 0, 0) <= 0) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
 
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
                          sizeof(sctpauthkey), sctpauthkey);
 #endif
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_ticket_expected)
                     s->state = SSL3_ST_SW_SESSION_TICKET_A;
                 else
                     s->state = SSL3_ST_SW_CHANGE_A;
 #else
                 s->state = SSL3_ST_SW_CHANGE_A;
 #endif
             } else
                 s->state = SSL3_ST_SW_CERT_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_A:
         case SSL3_ST_SW_CERT_B:
             /* Check if it is anon DH or normal PSK */
             if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
                 && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 dtls1_start_timer(s);
                 ret = dtls1_send_server_certificate(s);
                 if (ret <= 0)
                     goto end;
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_status_expected)
                     s->state = SSL3_ST_SW_CERT_STATUS_A;
                 else
                     s->state = SSL3_ST_SW_KEY_EXCH_A;
             } else {
                 skip = 1;
                 s->state = SSL3_ST_SW_KEY_EXCH_A;
             }
 #else
             } else
                 skip = 1;
 
             s->state = SSL3_ST_SW_KEY_EXCH_A;
 #endif
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_KEY_EXCH_A:
         case SSL3_ST_SW_KEY_EXCH_B:
             alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
             /*
              * clear this, it may get reset by
              * send_server_key_exchange
              */
             s->s3->tmp.use_rsa_tmp = 0;
 
             /*
              * only send if a DH key exchange or RSA but we have a sign only
              * certificate
              */
             if (0
                 /*
                  * PSK: send ServerKeyExchange if PSK identity hint if
                  * provided
                  */
 #ifndef OPENSSL_NO_PSK
                 || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
 #endif
                 || (alg_k & SSL_kEDH)
                 || (alg_k & SSL_kEECDH)
                 || ((alg_k & SSL_kRSA)
                     && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
                         || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
                             && EVP_PKEY_size(s->cert->pkeys
                                              [SSL_PKEY_RSA_ENC].privatekey) *
                             8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
                         )
                     )
                 )
                 ) {
                 dtls1_start_timer(s);
                 ret = dtls1_send_server_key_exchange(s);
                 if (ret <= 0)
                     goto end;
             } else
                 skip = 1;
 
             s->state = SSL3_ST_SW_CERT_REQ_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_REQ_A:
         case SSL3_ST_SW_CERT_REQ_B:
             if (                /* don't request cert unless asked for it: */
                    !(s->verify_mode & SSL_VERIFY_PEER) ||
                    /*
                     * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
                     * during re-negotiation:
                     */
                    ((s->session->peer != NULL) &&
                     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
                    /*
                     * never request cert in anonymous ciphersuites (see
                     * section "Certificate request" in SSL 3 drafts and in
                     * RFC 2246):
                     */
                    ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                     /*
                      * ... except when the application insists on
                      * verification (against the specs, but s3_clnt.c accepts
                      * this for SSL 3)
                      */
                     !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
                    /*
                     * never request cert in Kerberos ciphersuites
                     */
                    (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)
                    /*
                     * With normal PSK Certificates and Certificate Requests
                     * are omitted
                     */
                    || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 /* no cert request */
                 skip = 1;
                 s->s3->tmp.cert_request = 0;
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
 #ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
                     s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
                 }
 #endif
             } else {
                 s->s3->tmp.cert_request = 1;
                 dtls1_start_timer(s);
                 ret = dtls1_send_certificate_request(s);
                 if (ret <= 0)
                     goto end;
 #ifndef NETSCAPE_HANG_BUG
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
 # ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A;
                     s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
                 }
 # endif
 #else
                 s->state = SSL3_ST_SW_FLUSH;
                 s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
 # ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = s->s3->tmp.next_state;
                     s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
                 }
 # endif
 #endif
                 s->init_num = 0;
             }
             break;
 
         case SSL3_ST_SW_SRVR_DONE_A:
         case SSL3_ST_SW_SRVR_DONE_B:
             dtls1_start_timer(s);
             ret = dtls1_send_server_done(s);
             if (ret <= 0)
                 goto end;
             s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
             s->state = SSL3_ST_SW_FLUSH;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_FLUSH:
             s->rwstate = SSL_WRITING;
             if (BIO_flush(s->wbio) <= 0) {
                 /*
                  * If the write error was fatal, stop trying
                  */
                 if (!BIO_should_retry(s->wbio)) {
                     s->rwstate = SSL_NOTHING;
                     s->state = s->s3->tmp.next_state;
                 }
 
                 ret = -1;
                 goto end;
             }
             s->rwstate = SSL_NOTHING;
             s->state = s->s3->tmp.next_state;
             break;
 
         case SSL3_ST_SR_CERT_A:
         case SSL3_ST_SR_CERT_B:
             /* Check for second client hello (MS SGC) */
             ret = ssl3_check_client_hello(s);
             if (ret <= 0)
                 goto end;
             if (ret == 2) {
                 dtls1_stop_timer(s);
                 s->state = SSL3_ST_SR_CLNT_HELLO_C;
             } else {
                 if (s->s3->tmp.cert_request) {
                     ret = ssl3_get_client_certificate(s);
                     if (ret <= 0)
                         goto end;
                 }
                 s->init_num = 0;
                 s->state = SSL3_ST_SR_KEY_EXCH_A;
             }
             break;
 
         case SSL3_ST_SR_KEY_EXCH_A:
         case SSL3_ST_SR_KEY_EXCH_B:
             ret = ssl3_get_client_key_exchange(s);
             if (ret <= 0)
                 goto end;
 #ifndef OPENSSL_NO_SCTP
             /*
              * Add new shared key for SCTP-Auth, will be ignored if no SCTP
              * used.
              */
             snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL),
                      DTLS1_SCTP_AUTH_LABEL);
 
             if (SSL_export_keying_material(s, sctpauthkey,
                                        sizeof(sctpauthkey), labelbuffer,
                                        sizeof(labelbuffer), NULL, 0, 0) <= 0) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY,
                      sizeof(sctpauthkey), sctpauthkey);
 #endif
 
             s->state = SSL3_ST_SR_CERT_VRFY_A;
             s->init_num = 0;
 
             if (ret == 2) {
                 /*
                  * For the ECDH ciphersuites when the client sends its ECDH
                  * pub key in a certificate, the CertificateVerify message is
                  * not sent.
                  */
                 s->state = SSL3_ST_SR_FINISHED_A;
                 s->init_num = 0;
             } else {
                 s->state = SSL3_ST_SR_CERT_VRFY_A;
                 s->init_num = 0;
 
                 /*
                  * We need to get hashes here so if there is a client cert,
                  * it can be verified
                  */
                 s->method->ssl3_enc->cert_verify_mac(s,
                                                      NID_md5,
                                                      &(s->s3->
                                                        tmp.cert_verify_md
                                                        [0]));
                 s->method->ssl3_enc->cert_verify_mac(s, NID_sha1,
                                                      &(s->s3->
                                                        tmp.cert_verify_md
                                                        [MD5_DIGEST_LENGTH]));
             }
             break;
 
         case SSL3_ST_SR_CERT_VRFY_A:
         case SSL3_ST_SR_CERT_VRFY_B:
             ret = ssl3_get_cert_verify(s);
             if (ret <= 0)
                 goto end;
 #ifndef OPENSSL_NO_SCTP
             if (BIO_dgram_is_sctp(SSL_get_wbio(s)) &&
                 state == SSL_ST_RENEGOTIATE)
                 s->state = DTLS1_SCTP_ST_SR_READ_SOCK;
             else
 #endif
                 s->state = SSL3_ST_SR_FINISHED_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SR_FINISHED_A:
         case SSL3_ST_SR_FINISHED_B:
             /*
              * Enable CCS. Receiving a CCS clears the flag, so make
              * sure not to re-enable it to ban duplicates. This *should* be the
              * first time we have received one - but we check anyway to be
              * cautious.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in d1_pkt.c, and remains set until
              * the client's Finished message is read.
              */
             if (!s->s3->change_cipher_spec)
                 s->d1->change_cipher_spec_ok = 1;
             ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
                                     SSL3_ST_SR_FINISHED_B);
             if (ret <= 0)
                 goto end;
             dtls1_stop_timer(s);
             if (s->hit)
                 s->state = SSL_ST_OK;
 #ifndef OPENSSL_NO_TLSEXT
             else if (s->tlsext_ticket_expected)
                 s->state = SSL3_ST_SW_SESSION_TICKET_A;
 #endif
             else
                 s->state = SSL3_ST_SW_CHANGE_A;
             s->init_num = 0;
             break;
 
 #ifndef OPENSSL_NO_TLSEXT
         case SSL3_ST_SW_SESSION_TICKET_A:
         case SSL3_ST_SW_SESSION_TICKET_B:
             ret = dtls1_send_newsession_ticket(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_CHANGE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_STATUS_A:
         case SSL3_ST_SW_CERT_STATUS_B:
             ret = ssl3_send_cert_status(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_KEY_EXCH_A;
             s->init_num = 0;
             break;
 
 #endif
 
         case SSL3_ST_SW_CHANGE_A:
         case SSL3_ST_SW_CHANGE_B:
 
             s->session->cipher = s->s3->tmp.new_cipher;
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             ret = dtls1_send_change_cipher_spec(s,
                                                 SSL3_ST_SW_CHANGE_A,
                                                 SSL3_ST_SW_CHANGE_B);
 
             if (ret <= 0)
                 goto end;
 
 #ifndef OPENSSL_NO_SCTP
             if (!s->hit) {
                 /*
                  * Change to new shared key of SCTP-Auth, will be ignored if
                  * no SCTP used.
                  */
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
                          0, NULL);
             }
 #endif
 
             s->state = SSL3_ST_SW_FINISHED_A;
             s->init_num = 0;
 
             if (!s->method->ssl3_enc->change_cipher_state(s,
                                                           SSL3_CHANGE_CIPHER_SERVER_WRITE))
             {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             dtls1_reset_seq_numbers(s, SSL3_CC_WRITE);
             break;
 
         case SSL3_ST_SW_FINISHED_A:
         case SSL3_ST_SW_FINISHED_B:
             ret = dtls1_send_finished(s,
                                       SSL3_ST_SW_FINISHED_A,
                                       SSL3_ST_SW_FINISHED_B,
                                       s->method->
                                       ssl3_enc->server_finished_label,
                                       s->method->
                                       ssl3_enc->server_finished_label_len);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_FLUSH;
             if (s->hit) {
                 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
 
 #ifndef OPENSSL_NO_SCTP
                 /*
                  * Change to new shared key of SCTP-Auth, will be ignored if
                  * no SCTP used.
                  */
                 BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY,
                          0, NULL);
 #endif
             } else {
                 s->s3->tmp.next_state = SSL_ST_OK;
 #ifndef OPENSSL_NO_SCTP
                 if (BIO_dgram_is_sctp(SSL_get_wbio(s))) {
                     s->d1->next_state = s->s3->tmp.next_state;
                     s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK;
                 }
 #endif
             }
             s->init_num = 0;
             break;
 
         case SSL_ST_OK:
             /* clean a few things up */
             ssl3_cleanup_key_block(s);
 
 #if 0
             BUF_MEM_free(s->init_buf);
             s->init_buf = NULL;
 #endif
 
             /* remove buffering on output */
             ssl_free_wbio_buffer(s);
 
             s->init_num = 0;
 
             if (s->renegotiate == 2) { /* skipped if we just sent a
                                         * HelloRequest */
                 s->renegotiate = 0;
                 s->new_session = 0;
 
                 ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
 
                 s->ctx->stats.sess_accept_good++;
                 /* s->server=1; */
                 s->handshake_func = dtls1_accept;
 
                 if (cb != NULL)
                     cb(s, SSL_CB_HANDSHAKE_DONE, 1);
             }
 
             ret = 1;
 
             /* done handshaking, next message is client hello */
             s->d1->handshake_read_seq = 0;
             /* next message is server hello */
             s->d1->handshake_write_seq = 0;
             s->d1->next_handshake_write_seq = 0;
+            dtls1_clear_received_buffer(s);
             goto end;
             /* break; */
 
         case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE);
             ret = -1;
             goto end;
             /* break; */
         }
 
         if (!s->s3->tmp.reuse_message && !skip) {
             if (s->debug) {
                 if ((ret = BIO_flush(s->wbio)) <= 0)
                     goto end;
             }
 
             if ((cb != NULL) && (s->state != state)) {
                 new_state = s->state;
                 s->state = state;
                 cb(s, SSL_CB_ACCEPT_LOOP, 1);
                 s->state = new_state;
             }
         }
         skip = 0;
     }
  end:
     /* BIO_flush(s->wbio); */
 
     s->in_handshake--;
 #ifndef OPENSSL_NO_SCTP
     /*
      * Notify SCTP BIO socket to leave handshake mode and prevent stream
      * identifier other than 0. Will be ignored if no SCTP is used.
      */
     BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE,
              s->in_handshake, NULL);
 #endif
 
     if (cb != NULL)
         cb(s, SSL_CB_ACCEPT_EXIT, ret);
     return (ret);
 }
 
 int dtls1_send_hello_request(SSL *s)
 {
     unsigned char *p;
 
     if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
         p = (unsigned char *)s->init_buf->data;
         p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0);
 
         s->state = SSL3_ST_SW_HELLO_REQ_B;
         /* number of bytes to write */
         s->init_num = DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /*
          * no need to buffer this message, since there are no retransmit
          * requests for it
          */
     }
 
     /* SSL3_ST_SW_HELLO_REQ_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int dtls1_send_hello_verify_request(SSL *s)
 {
     unsigned int msg_len;
     unsigned char *msg, *buf, *p;
 
     if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) {
         buf = (unsigned char *)s->init_buf->data;
 
         msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
         *(p++) = s->version >> 8;
         *(p++) = s->version & 0xFF;
 
         if (s->ctx->app_gen_cookie_cb == NULL ||
             s->ctx->app_gen_cookie_cb(s, s->d1->cookie,
                                       &(s->d1->cookie_len)) == 0) {
             SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST,
                    ERR_R_INTERNAL_ERROR);
             s->state = SSL_ST_ERR;
             return 0;
         }
 
         *(p++) = (unsigned char)s->d1->cookie_len;
         memcpy(p, s->d1->cookie, s->d1->cookie_len);
         p += s->d1->cookie_len;
         msg_len = p - msg;
 
         dtls1_set_message_header(s, buf,
                                  DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0,
                                  msg_len);
 
         s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B;
         /* number of bytes to write */
         s->init_num = p - buf;
         s->init_off = 0;
     }
 
     /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int dtls1_send_server_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int i;
     unsigned int sl;
     unsigned long l;
 
     if (s->state == SSL3_ST_SW_SRVR_HELLO_A) {
         buf = (unsigned char *)s->init_buf->data;
         p = s->s3->server_random;
         ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE);
         /* Do the message type and length last */
         d = p = &(buf[DTLS1_HM_HEADER_LENGTH]);
 
         *(p++) = s->version >> 8;
         *(p++) = s->version & 0xff;
 
         /* Random stuff */
         memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
         p += SSL3_RANDOM_SIZE;
 
         /*
          * now in theory we have 3 options to sending back the session id.
          * If it is a re-use, we send back the old session-id, if it is a new
          * session, we send back the new session-id or we send back a 0
          * length session-id if we want it to be single use. Currently I will
          * not implement the '0' length session-id 12-Jan-98 - I'll now
          * support the '0' length stuff.
          */
         if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER))
             s->session->session_id_length = 0;
 
         sl = s->session->session_id_length;
         if (sl > sizeof s->session->session_id) {
             SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             return -1;
         }
         *(p++) = sl;
         memcpy(p, s->session->session_id, sl);
         p += sl;
 
         /* put the cipher */
         if (s->s3->tmp.new_cipher == NULL)
             return -1;
         i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p);
         p += i;
 
         /* put the compression method */
 #ifdef OPENSSL_NO_COMP
         *(p++) = 0;
 #else
         if (s->s3->tmp.new_compression == NULL)
             *(p++) = 0;
         else
             *(p++) = s->s3->tmp.new_compression->id;
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
         if (ssl_prepare_serverhello_tlsext(s) <= 0) {
             SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
             return -1;
         }
         if ((p =
              ssl_add_serverhello_tlsext(s, p,
                                         buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
             NULL) {
             SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             return -1;
         }
 #endif
 
         /* do the header */
         l = (p - d);
         d = buf;
 
         d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l);
 
         s->state = SSL3_ST_SW_SRVR_HELLO_B;
         /* number of bytes to write */
         s->init_num = p - buf;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_SW_SRVR_HELLO_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int dtls1_send_server_done(SSL *s)
 {
     unsigned char *p;
 
     if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
         p = (unsigned char *)s->init_buf->data;
 
         /* do the header */
         p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0);
 
         s->state = SSL3_ST_SW_SRVR_DONE_B;
         /* number of bytes to write */
         s->init_num = DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_SW_SRVR_DONE_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int dtls1_send_server_key_exchange(SSL *s)
 {
 #ifndef OPENSSL_NO_RSA
     unsigned char *q;
     int j, num;
     RSA *rsa;
     unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
     unsigned int u;
 #endif
 #ifndef OPENSSL_NO_DH
     DH *dh = NULL, *dhp;
 #endif
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *ecdh = NULL, *ecdhp;
     unsigned char *encodedPoint = NULL;
     int encodedlen = 0;
     int curve_id = 0;
     BN_CTX *bn_ctx = NULL;
 #endif
     EVP_PKEY *pkey;
     unsigned char *p, *d;
     int al, i;
     unsigned long type;
     int n;
     CERT *cert;
     BIGNUM *r[4];
     int nr[4], kn;
     BUF_MEM *buf;
     EVP_MD_CTX md_ctx;
 
     EVP_MD_CTX_init(&md_ctx);
     if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
         type = s->s3->tmp.new_cipher->algorithm_mkey;
         cert = s->cert;
 
         buf = s->init_buf;
 
         r[0] = r[1] = r[2] = r[3] = NULL;
         n = 0;
 #ifndef OPENSSL_NO_RSA
         if (type & SSL_kRSA) {
             rsa = cert->rsa_tmp;
             if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) {
                 rsa = s->cert->rsa_tmp_cb(s,
                                           SSL_C_IS_EXPORT(s->s3->
                                                           tmp.new_cipher),
                                           SSL_C_EXPORT_PKEYLENGTH(s->s3->
                                                                   tmp.new_cipher));
                 if (rsa == NULL) {
                     al = SSL_AD_HANDSHAKE_FAILURE;
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                            SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
                     goto f_err;
                 }
                 RSA_up_ref(rsa);
                 cert->rsa_tmp = rsa;
             }
             if (rsa == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_RSA_KEY);
                 goto f_err;
             }
             r[0] = rsa->n;
             r[1] = rsa->e;
             s->s3->tmp.use_rsa_tmp = 1;
         } else
 #endif
 #ifndef OPENSSL_NO_DH
         if (type & SSL_kEDH) {
             dhp = cert->dh_tmp;
             if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
                 dhp = s->cert->dh_tmp_cb(s,
                                          SSL_C_IS_EXPORT(s->s3->
                                                          tmp.new_cipher),
                                          SSL_C_EXPORT_PKEYLENGTH(s->s3->
                                                                  tmp.new_cipher));
             if (dhp == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_DH_KEY);
                 goto f_err;
             }
 
             if (s->s3->tmp.dh != NULL) {
                 DH_free(dh);
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if ((dh = DHparams_dup(dhp)) == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
 
             s->s3->tmp.dh = dh;
             if ((dhp->pub_key == NULL ||
                  dhp->priv_key == NULL ||
                  (s->options & SSL_OP_SINGLE_DH_USE))) {
                 if (!DH_generate_key(dh)) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                            ERR_R_DH_LIB);
                     goto err;
                 }
             } else {
                 dh->pub_key = BN_dup(dhp->pub_key);
                 dh->priv_key = BN_dup(dhp->priv_key);
                 if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                            ERR_R_DH_LIB);
                     goto err;
                 }
             }
             r[0] = dh->p;
             r[1] = dh->g;
             r[2] = dh->pub_key;
         } else
 #endif
 #ifndef OPENSSL_NO_ECDH
         if (type & SSL_kEECDH) {
             const EC_GROUP *group;
 
             ecdhp = cert->ecdh_tmp;
             if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) {
                 ecdhp = s->cert->ecdh_tmp_cb(s,
                                              SSL_C_IS_EXPORT(s->s3->
                                                              tmp.new_cipher),
                                              SSL_C_EXPORT_PKEYLENGTH(s->
                                                                      s3->tmp.new_cipher));
             }
             if (ecdhp == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_ECDH_KEY);
                 goto f_err;
             }
 
             if (s->s3->tmp.ecdh != NULL) {
                 EC_KEY_free(s->s3->tmp.ecdh);
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             /* Duplicate the ECDH structure. */
             if (ecdhp == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
             if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             s->s3->tmp.ecdh = ecdh;
             if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
                 (EC_KEY_get0_private_key(ecdh) == NULL) ||
                 (s->options & SSL_OP_SINGLE_ECDH_USE)) {
                 if (!EC_KEY_generate_key(ecdh)) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                            ERR_R_ECDH_LIB);
                     goto err;
                 }
             }
 
             if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
                 (EC_KEY_get0_public_key(ecdh) == NULL) ||
                 (EC_KEY_get0_private_key(ecdh) == NULL)) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
                 (EC_GROUP_get_degree(group) > 163)) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
                 goto err;
             }
 
             /*
              * XXX: For now, we only support ephemeral ECDH keys over named
              * (not generic) curves. For supported named curves, curve_id is
              * non-zero.
              */
             if ((curve_id =
                  tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
                 == 0) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
                 goto err;
             }
 
             /*
              * Encode the public key. First check the size of encoding and
              * allocate memory accordingly.
              */
             encodedlen = EC_POINT_point2oct(group,
                                             EC_KEY_get0_public_key(ecdh),
                                             POINT_CONVERSION_UNCOMPRESSED,
                                             NULL, 0, NULL);
 
             encodedPoint = (unsigned char *)
                 OPENSSL_malloc(encodedlen * sizeof(unsigned char));
             bn_ctx = BN_CTX_new();
             if ((encodedPoint == NULL) || (bn_ctx == NULL)) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             encodedlen = EC_POINT_point2oct(group,
                                             EC_KEY_get0_public_key(ecdh),
                                             POINT_CONVERSION_UNCOMPRESSED,
                                             encodedPoint, encodedlen, bn_ctx);
 
             if (encodedlen == 0) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             BN_CTX_free(bn_ctx);
             bn_ctx = NULL;
 
             /*
              * XXX: For now, we only support named (not generic) curves in
              * ECDH ephemeral key exchanges. In this situation, we need four
              * additional bytes to encode the entire ServerECDHParams
              * structure.
              */
             n = 4 + encodedlen;
 
             /*
              * We'll generate the serverKeyExchange message explicitly so we
              * can set these to NULLs
              */
             r[0] = NULL;
             r[1] = NULL;
             r[2] = NULL;
             r[3] = NULL;
         } else
 #endif                          /* !OPENSSL_NO_ECDH */
 #ifndef OPENSSL_NO_PSK
         if (type & SSL_kPSK) {
             /*
              * reserve size for record length and PSK identity hint
              */
             n += 2 + strlen(s->ctx->psk_identity_hint);
         } else
 #endif                          /* !OPENSSL_NO_PSK */
         {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                    SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
             goto f_err;
         }
         for (i = 0; r[i] != NULL; i++) {
             nr[i] = BN_num_bytes(r[i]);
             n += 2 + nr[i];
         }
 
         if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL)
             && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
             if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, NULL))
                 == NULL) {
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
             kn = EVP_PKEY_size(pkey);
         } else {
             pkey = NULL;
             kn = 0;
         }
 
         if (!BUF_MEM_grow_clean(buf, n + DTLS1_HM_HEADER_LENGTH + kn)) {
             SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF);
             goto err;
         }
         d = (unsigned char *)s->init_buf->data;
         p = &(d[DTLS1_HM_HEADER_LENGTH]);
 
         for (i = 0; r[i] != NULL; i++) {
             s2n(nr[i], p);
             BN_bn2bin(r[i], p);
             p += nr[i];
         }
 
 #ifndef OPENSSL_NO_ECDH
         if (type & SSL_kEECDH) {
             /*
              * XXX: For now, we only support named (not generic) curves. In
              * this situation, the serverKeyExchange message has: [1 byte
              * CurveType], [2 byte CurveName] [1 byte length of encoded
              * point], followed by the actual encoded point itself
              */
             *p = NAMED_CURVE_TYPE;
             p += 1;
             *p = 0;
             p += 1;
             *p = curve_id;
             p += 1;
             *p = encodedlen;
             p += 1;
             memcpy((unsigned char *)p,
                    (unsigned char *)encodedPoint, encodedlen);
             OPENSSL_free(encodedPoint);
             encodedPoint = NULL;
             p += encodedlen;
         }
 #endif
 
 #ifndef OPENSSL_NO_PSK
         if (type & SSL_kPSK) {
             /* copy PSK identity hint */
             s2n(strlen(s->ctx->psk_identity_hint), p);
             strncpy((char *)p, s->ctx->psk_identity_hint,
                     strlen(s->ctx->psk_identity_hint));
             p += strlen(s->ctx->psk_identity_hint);
         }
 #endif
 
         /* not anonymous */
         if (pkey != NULL) {
             /*
              * n is the length of the params, they start at
              * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space at the
              * end.
              */
 #ifndef OPENSSL_NO_RSA
             if (pkey->type == EVP_PKEY_RSA) {
                 q = md_buf;
                 j = 0;
                 for (num = 2; num > 0; num--) {
                     EVP_DigestInit_ex(&md_ctx, (num == 2)
                                       ? s->ctx->md5 : s->ctx->sha1, NULL);
                     EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
                                      SSL3_RANDOM_SIZE);
                     EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
                                      SSL3_RANDOM_SIZE);
                     EVP_DigestUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]),
                                      n);
                     EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i);
                     q += i;
                     j += i;
                 }
                 if (RSA_sign(NID_md5_sha1, md_buf, j,
                              &(p[2]), &u, pkey->pkey.rsa) <= 0) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA);
                     goto err;
                 }
                 s2n(u, p);
                 n += u + 2;
             } else
 #endif
 #if !defined(OPENSSL_NO_DSA)
             if (pkey->type == EVP_PKEY_DSA) {
                 /* lets do DSS */
                 EVP_SignInit_ex(&md_ctx, EVP_dss1(), NULL);
                 EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
                                SSL3_RANDOM_SIZE);
                 EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
                                SSL3_RANDOM_SIZE);
                 EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n);
                 if (!EVP_SignFinal(&md_ctx, &(p[2]),
                                    (unsigned int *)&i, pkey)) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_DSA);
                     goto err;
                 }
                 s2n(i, p);
                 n += i + 2;
             } else
 #endif
 #if !defined(OPENSSL_NO_ECDSA)
             if (pkey->type == EVP_PKEY_EC) {
                 /* let's do ECDSA */
                 EVP_SignInit_ex(&md_ctx, EVP_ecdsa(), NULL);
                 EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
                                SSL3_RANDOM_SIZE);
                 EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
                                SSL3_RANDOM_SIZE);
                 EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n);
                 if (!EVP_SignFinal(&md_ctx, &(p[2]),
                                    (unsigned int *)&i, pkey)) {
                     SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                            ERR_LIB_ECDSA);
                     goto err;
                 }
                 s2n(i, p);
                 n += i + 2;
             } else
 #endif
             {
                 /* Is this error check actually needed? */
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_UNKNOWN_PKEY_TYPE);
                 goto f_err;
             }
         }
 
         d = dtls1_set_message_header(s, d,
                                      SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n);
 
         /*
          * we should now have things packed up, so lets send it off
          */
         s->init_num = n + DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     s->state = SSL3_ST_SW_KEY_EXCH_B;
     EVP_MD_CTX_cleanup(&md_ctx);
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
 #ifndef OPENSSL_NO_ECDH
     if (encodedPoint != NULL)
         OPENSSL_free(encodedPoint);
     BN_CTX_free(bn_ctx);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
     return (-1);
 }
 
 int dtls1_send_certificate_request(SSL *s)
 {
     unsigned char *p, *d;
     int i, j, nl, off, n;
     STACK_OF(X509_NAME) *sk = NULL;
     X509_NAME *name;
     BUF_MEM *buf;
     unsigned int msg_len;
 
     if (s->state == SSL3_ST_SW_CERT_REQ_A) {
         buf = s->init_buf;
 
         d = p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]);
 
         /* get the list of acceptable cert types */
         p++;
         n = ssl3_get_req_cert_type(s, p);
         d[0] = n;
         p += n;
         n++;
 
         off = n;
         p += 2;
         n += 2;
 
         sk = SSL_get_client_CA_list(s);
         nl = 0;
         if (sk != NULL) {
             for (i = 0; i < sk_X509_NAME_num(sk); i++) {
                 name = sk_X509_NAME_value(sk, i);
                 j = i2d_X509_NAME(name, NULL);
                 if (!BUF_MEM_grow_clean
                     (buf, DTLS1_HM_HEADER_LENGTH + n + j + 2)) {
                     SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST,
                            ERR_R_BUF_LIB);
                     goto err;
                 }
                 p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH + n]);
                 if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) {
                     s2n(j, p);
                     i2d_X509_NAME(name, &p);
                     n += 2 + j;
                     nl += 2 + j;
                 } else {
                     d = p;
                     i2d_X509_NAME(name, &p);
                     j -= 2;
                     s2n(j, d);
                     j += 2;
                     n += j;
                     nl += j;
                 }
             }
         }
         /* else no CA names */
         p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH + off]);
         s2n(nl, p);
 
         d = (unsigned char *)buf->data;
         *(d++) = SSL3_MT_CERTIFICATE_REQUEST;
         l2n3(n, d);
         s2n(s->d1->handshake_write_seq, d);
         s->d1->handshake_write_seq++;
 
         /*
          * we should now have things packed up, so lets send it off
          */
 
         s->init_num = n + DTLS1_HM_HEADER_LENGTH;
         s->init_off = 0;
 #ifdef NETSCAPE_HANG_BUG
 /* XXX: what to do about this? */
         p = (unsigned char *)s->init_buf->data + s->init_num;
 
         /* do the header */
         *(p++) = SSL3_MT_SERVER_DONE;
         *(p++) = 0;
         *(p++) = 0;
         *(p++) = 0;
         s->init_num += 4;
 #endif
 
         /* XDTLS:  set message header ? */
         msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
         dtls1_set_message_header(s, (void *)s->init_buf->data,
                                  SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0,
                                  msg_len);
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
 
         s->state = SSL3_ST_SW_CERT_REQ_B;
     }
 
     /* SSL3_ST_SW_CERT_REQ_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     return (-1);
 }
 
 int dtls1_send_server_certificate(SSL *s)
 {
     unsigned long l;
     X509 *x;
 
     if (s->state == SSL3_ST_SW_CERT_A) {
         x = ssl_get_server_send_cert(s);
         if (x == NULL) {
             /* VRS: allow null cert if auth == KRB5 */
             if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) ||
                 (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5)) {
                 SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE,
                        ERR_R_INTERNAL_ERROR);
                 return (0);
             }
         }
 
         l = dtls1_output_cert_chain(s, x);
         if (!l) {
             SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             return (0);
         }
         s->state = SSL3_ST_SW_CERT_B;
         s->init_num = (int)l;
         s->init_off = 0;
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_SW_CERT_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 int dtls1_send_newsession_ticket(SSL *s)
 {
     if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
         unsigned char *p, *senc, *macstart;
         int len, slen;
         unsigned int hlen, msg_len;
         EVP_CIPHER_CTX ctx;
         HMAC_CTX hctx;
         SSL_CTX *tctx = s->initial_ctx;
         unsigned char iv[EVP_MAX_IV_LENGTH];
         unsigned char key_name[16];
 
         /* get session encoding length */
         slen = i2d_SSL_SESSION(s->session, NULL);
         /*
          * Some length values are 16 bits, so forget it if session is too
          * long
          */
         if (slen > 0xFF00)
             return -1;
         /*
          * Grow buffer if need be: the length calculation is as follows 12
          * (DTLS handshake message header) + 4 (ticket lifetime hint) + 2
          * (ticket length) + 16 (key name) + max_iv_len (iv length) +
          * session_length + max_enc_block_size (max encrypted session length)
          * + max_md_size (HMAC).
          */
         if (!BUF_MEM_grow(s->init_buf,
                           DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH +
                           EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen))
             return -1;
         senc = OPENSSL_malloc(slen);
         if (!senc)
             return -1;
         p = senc;
         i2d_SSL_SESSION(s->session, &p);
 
         p = (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]);
         EVP_CIPHER_CTX_init(&ctx);
         HMAC_CTX_init(&hctx);
         /*
          * Initialize HMAC and cipher contexts. If callback present it does
          * all the work otherwise use generated values from parent ctx.
          */
         if (tctx->tlsext_ticket_key_cb) {
             if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
                                            &hctx, 1) < 0) {
                 OPENSSL_free(senc);
                 return -1;
             }
         } else {
-            RAND_pseudo_bytes(iv, 16);
+            if (RAND_bytes(iv, 16) <= 0) {
+                OPENSSL_free(senc);
+                return -1;
+            }
             EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                                tctx->tlsext_tick_aes_key, iv);
             HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
                          tlsext_tick_md(), NULL);
             memcpy(key_name, tctx->tlsext_tick_key_name, 16);
         }
         l2n(s->session->tlsext_tick_lifetime_hint, p);
         /* Skip ticket length for now */
         p += 2;
         /* Output key name */
         macstart = p;
         memcpy(p, key_name, 16);
         p += 16;
         /* output IV */
         memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
         p += EVP_CIPHER_CTX_iv_length(&ctx);
         /* Encrypt session data */
         EVP_EncryptUpdate(&ctx, p, &len, senc, slen);
         p += len;
         EVP_EncryptFinal(&ctx, p, &len);
         p += len;
         EVP_CIPHER_CTX_cleanup(&ctx);
 
         HMAC_Update(&hctx, macstart, p - macstart);
         HMAC_Final(&hctx, p, &hlen);
         HMAC_CTX_cleanup(&hctx);
 
         p += hlen;
         /* Now write out lengths: p points to end of data written */
         /* Total length */
         len = p - (unsigned char *)(s->init_buf->data);
         /* Ticket length */
         p = (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4;
         s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p);
 
         /* number of bytes to write */
         s->init_num = len;
         s->state = SSL3_ST_SW_SESSION_TICKET_B;
         s->init_off = 0;
         OPENSSL_free(senc);
 
         /* XDTLS:  set message header ? */
         msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH;
         dtls1_set_message_header(s, (void *)s->init_buf->data,
                                  SSL3_MT_NEWSESSION_TICKET, msg_len, 0,
                                  msg_len);
 
         /* buffer the message to handle re-xmits */
         dtls1_buffer_message(s, 0);
     }
 
     /* SSL3_ST_SW_SESSION_TICKET_B */
     return (dtls1_do_write(s, SSL3_RT_HANDSHAKE));
 }
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s23_clnt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s23_clnt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s23_clnt.c	(revision 306191)
@@ -1,790 +1,790 @@
 /* ssl/s23_clnt.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-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
  *    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 "ssl_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 
 static const SSL_METHOD *ssl23_get_client_method(int ver);
 static int ssl23_client_hello(SSL *s);
 static int ssl23_get_server_hello(SSL *s);
 static const SSL_METHOD *ssl23_get_client_method(int ver)
 {
 #ifndef OPENSSL_NO_SSL2
     if (ver == SSL2_VERSION)
         return (SSLv2_client_method());
 #endif
 #ifndef OPENSSL_NO_SSL3
     if (ver == SSL3_VERSION)
         return (SSLv3_client_method());
 #endif
     if (ver == TLS1_VERSION)
         return (TLSv1_client_method());
     else if (ver == TLS1_1_VERSION)
         return (TLSv1_1_client_method());
     else if (ver == TLS1_2_VERSION)
         return (TLSv1_2_client_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_ssl23_meth_func(SSLv23_client_method,
                           ssl_undefined_function,
                           ssl23_connect, ssl23_get_client_method)
 
 int ssl23_connect(SSL *s)
 {
     BUF_MEM *buf = NULL;
     unsigned long Time = (unsigned long)time(NULL);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
     int ret = -1;
     int new_state, state;
 
     RAND_add(&Time, sizeof(Time), 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;
 
     s->in_handshake++;
     if (!SSL_in_init(s) || SSL_in_before(s))
         SSL_clear(s);
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_BEFORE:
         case SSL_ST_CONNECT:
         case SSL_ST_BEFORE | SSL_ST_CONNECT:
         case SSL_ST_OK | SSL_ST_CONNECT:
 
             if (s->session != NULL) {
                 SSLerr(SSL_F_SSL23_CONNECT,
                        SSL_R_SSL23_DOING_SESSION_ID_REUSE);
                 ret = -1;
                 goto end;
             }
             s->server = 0;
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
             /* s->version=TLS1_VERSION; */
             s->type = SSL_ST_CONNECT;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
                     goto end;
                 }
                 s->init_buf = buf;
                 buf = NULL;
             }
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
                 goto end;
             }
 
             ssl3_init_finished_mac(s);
 
             s->state = SSL23_ST_CW_CLNT_HELLO_A;
             s->ctx->stats.sess_connect++;
             s->init_num = 0;
             break;
 
         case SSL23_ST_CW_CLNT_HELLO_A:
         case SSL23_ST_CW_CLNT_HELLO_B:
 
             s->shutdown = 0;
             ret = ssl23_client_hello(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL23_ST_CR_SRVR_HELLO_A;
             s->init_num = 0;
 
             break;
 
         case SSL23_ST_CR_SRVR_HELLO_A:
         case SSL23_ST_CR_SRVR_HELLO_B:
             ret = ssl23_get_server_hello(s);
             if (ret >= 0)
                 cb = NULL;
             goto end;
             /* break; */
 
         default:
             SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
             goto end;
             /* break; */
         }
 
         if (s->debug) {
             (void)BIO_flush(s->wbio);
         }
 
         if ((cb != NULL) && (s->state != state)) {
             new_state = s->state;
             s->state = state;
             cb(s, SSL_CB_CONNECT_LOOP, 1);
             s->state = new_state;
         }
     }
  end:
     s->in_handshake--;
     if (buf != NULL)
         BUF_MEM_free(buf);
     if (cb != NULL)
         cb(s, SSL_CB_CONNECT_EXIT, ret);
     return (ret);
 }
 
 static int ssl23_no_ssl2_ciphers(SSL *s)
 {
     SSL_CIPHER *cipher;
     STACK_OF(SSL_CIPHER) *ciphers;
     int i;
     ciphers = SSL_get_ciphers(s);
     for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
         cipher = sk_SSL_CIPHER_value(ciphers, i);
         if (cipher->algorithm_ssl == SSL_SSLV2)
             return 0;
     }
     return 1;
 }
 
 /*
  * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on
  * failure, 1 on success.
  */
 int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
 {
     int send_time = 0;
 
     if (len < 4)
         return 0;
     if (server)
         send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0;
     else
         send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0;
     if (send_time) {
         unsigned long Time = (unsigned long)time(NULL);
         unsigned char *p = result;
         l2n(Time, p);
-        return RAND_pseudo_bytes(p, len - 4);
+        return RAND_bytes(p, len - 4);
     } else
-        return RAND_pseudo_bytes(result, len);
+        return RAND_bytes(result, len);
 }
 
 static int ssl23_client_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int i, ch_len;
     unsigned long l;
     int ssl2_compat;
     int version = 0, version_major, version_minor;
 #ifndef OPENSSL_NO_COMP
     int j;
     SSL_COMP *comp;
 #endif
     int ret;
     unsigned long mask, options = s->options;
 
     ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1;
 
     if (ssl2_compat && ssl23_no_ssl2_ciphers(s))
         ssl2_compat = 0;
 
     /*
      * SSL_OP_NO_X disables all protocols above X *if* there are
      * some protocols below X enabled. This is required in order
      * to maintain "version capability" vector contiguous. So
      * that if application wants to disable TLS1.0 in favour of
      * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the
      * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2.
      */
     mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1
 #if !defined(OPENSSL_NO_SSL3)
         | SSL_OP_NO_SSLv3
 #endif
 #if !defined(OPENSSL_NO_SSL2)
         | (ssl2_compat ? SSL_OP_NO_SSLv2 : 0)
 #endif
         ;
 #if !defined(OPENSSL_NO_TLS1_2_CLIENT)
     version = TLS1_2_VERSION;
 
     if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask)
         version = TLS1_1_VERSION;
 #else
     version = TLS1_1_VERSION;
 #endif
     mask &= ~SSL_OP_NO_TLSv1_1;
     if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask)
         version = TLS1_VERSION;
     mask &= ~SSL_OP_NO_TLSv1;
 #if !defined(OPENSSL_NO_SSL3)
     if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask)
         version = SSL3_VERSION;
     mask &= ~SSL_OP_NO_SSLv3;
 #endif
 #if !defined(OPENSSL_NO_SSL2)
     if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask)
         version = SSL2_VERSION;
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
     if (version != SSL2_VERSION) {
         /*
          * have to disable SSL 2.0 compatibility if we need TLS extensions
          */
 
         if (s->tlsext_hostname != NULL)
             ssl2_compat = 0;
         if (s->tlsext_status_type != -1)
             ssl2_compat = 0;
 # ifdef TLSEXT_TYPE_opaque_prf_input
         if (s->ctx->tlsext_opaque_prf_input_callback != 0
             || s->tlsext_opaque_prf_input != NULL)
             ssl2_compat = 0;
 # endif
     }
 #endif
 
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL23_ST_CW_CLNT_HELLO_A) {
         /*
          * Since we're sending s23 client hello, we're not reusing a session, as
          * we'd be using the method from the saved session instead
          */
         if (!ssl_get_new_session(s, 0)) {
             return -1;
         }
 
         p = s->s3->client_random;
         if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
             return -1;
 
         if (version == TLS1_2_VERSION) {
             version_major = TLS1_2_VERSION_MAJOR;
             version_minor = TLS1_2_VERSION_MINOR;
         } else if (version == TLS1_1_VERSION) {
             version_major = TLS1_1_VERSION_MAJOR;
             version_minor = TLS1_1_VERSION_MINOR;
         } else if (version == TLS1_VERSION) {
             version_major = TLS1_VERSION_MAJOR;
             version_minor = TLS1_VERSION_MINOR;
         }
 #ifdef OPENSSL_FIPS
         else if (FIPS_mode()) {
             SSLerr(SSL_F_SSL23_CLIENT_HELLO,
                    SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
             return -1;
         }
 #endif
         else if (version == SSL3_VERSION) {
             version_major = SSL3_VERSION_MAJOR;
             version_minor = SSL3_VERSION_MINOR;
         } else if (version == SSL2_VERSION) {
             version_major = SSL2_VERSION_MAJOR;
             version_minor = SSL2_VERSION_MINOR;
         } else {
             SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE);
             return (-1);
         }
 
         s->client_version = version;
 
         if (ssl2_compat) {
             /* create SSL 2.0 compatible Client Hello */
 
             /* two byte record header will be written last */
             d = &(buf[2]);
             p = d + 9;          /* leave space for message type, version,
                                  * individual length fields */
 
             *(d++) = SSL2_MT_CLIENT_HELLO;
             *(d++) = version_major;
             *(d++) = version_minor;
 
             /* Ciphers supported */
             i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0);
             if (i == 0) {
                 /* no ciphers */
                 SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
                 return -1;
             }
             s2n(i, d);
             p += i;
 
             /*
              * put in the session-id length (zero since there is no reuse)
              */
             s2n(0, d);
 
             if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
                 ch_len = SSL2_CHALLENGE_LENGTH;
             else
                 ch_len = SSL2_MAX_CHALLENGE_LENGTH;
 
             /* write out sslv2 challenge */
             /*
              * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it
              * is one of SSL2_MAX_CHALLENGE_LENGTH (32) or
              * SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for
              * futurproofing
              */
             if (SSL3_RANDOM_SIZE < ch_len)
                 i = SSL3_RANDOM_SIZE;
             else
                 i = ch_len;
             s2n(i, d);
             memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE);
-            if (RAND_pseudo_bytes
-                (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0)
+            if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i)
+                    <= 0)
                 return -1;
 
             memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i);
             p += i;
 
             i = p - &(buf[2]);
             buf[0] = ((i >> 8) & 0xff) | 0x80;
             buf[1] = (i & 0xff);
 
             /* number of bytes to write */
             s->init_num = i + 2;
             s->init_off = 0;
 
             ssl3_finish_mac(s, &(buf[2]), i);
         } else {
             /* create Client Hello in SSL 3.0/TLS 1.0 format */
 
             /*
              * do the record header (5 bytes) and handshake message header (4
              * bytes) last
              */
             d = p = &(buf[9]);
 
             *(p++) = version_major;
             *(p++) = version_minor;
 
             /* Random stuff */
             memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
             p += SSL3_RANDOM_SIZE;
 
             /* Session ID (zero since there is no reuse) */
             *(p++) = 0;
 
             /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */
             i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]),
                                          ssl3_put_cipher_by_char);
             if (i == 0) {
                 SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
                 return -1;
             }
 #ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
             /*
              * Some servers hang if client hello > 256 bytes as hack
              * workaround chop number of supported ciphers to keep it well
              * below this if we use TLS v1.2
              */
             if (TLS1_get_version(s) >= TLS1_2_VERSION
                 && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
                 i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
 #endif
             s2n(i, p);
             p += i;
 
             /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
             *(p++) = 1;
 #else
             if ((s->options & SSL_OP_NO_COMPRESSION)
                 || !s->ctx->comp_methods)
                 j = 0;
             else
                 j = sk_SSL_COMP_num(s->ctx->comp_methods);
             *(p++) = 1 + j;
             for (i = 0; i < j; i++) {
                 comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
                 *(p++) = comp->id;
             }
 #endif
             *(p++) = 0;         /* Add the NULL method */
 
 #ifndef OPENSSL_NO_TLSEXT
             /* TLS extensions */
             if (ssl_prepare_clienthello_tlsext(s) <= 0) {
                 SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
                 return -1;
             }
             if ((p =
                  ssl_add_clienthello_tlsext(s, p,
                                             buf +
                                             SSL3_RT_MAX_PLAIN_LENGTH)) ==
                 NULL) {
                 SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
                 return -1;
             }
 #endif
 
             l = p - d;
 
             /* fill in 4-byte handshake header */
             d = &(buf[5]);
             *(d++) = SSL3_MT_CLIENT_HELLO;
             l2n3(l, d);
 
             l += 4;
 
             if (l > SSL3_RT_MAX_PLAIN_LENGTH) {
                 SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
                 return -1;
             }
 
             /* fill in 5-byte record header */
             d = buf;
             *(d++) = SSL3_RT_HANDSHAKE;
             *(d++) = version_major;
             /*
              * Some servers hang if we use long client hellos and a record
              * number > TLS 1.0.
              */
             if (TLS1_get_client_version(s) > TLS1_VERSION)
                 *(d++) = 1;
             else
                 *(d++) = version_minor;
             s2n((int)l, d);
 
             /* number of bytes to write */
             s->init_num = p - buf;
             s->init_off = 0;
 
             ssl3_finish_mac(s, &(buf[5]), s->init_num - 5);
         }
 
         s->state = SSL23_ST_CW_CLNT_HELLO_B;
         s->init_off = 0;
     }
 
     /* SSL3_ST_CW_CLNT_HELLO_B */
     ret = ssl23_write_bytes(s);
 
     if ((ret >= 2) && s->msg_callback) {
         /* Client Hello has been sent; tell msg_callback */
 
         if (ssl2_compat)
             s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2,
                             ret - 2, s, s->msg_callback_arg);
         else
             s->msg_callback(1, version, SSL3_RT_HANDSHAKE,
                             s->init_buf->data + 5, ret - 5, s,
                             s->msg_callback_arg);
     }
 
     return ret;
 }
 
 static int ssl23_get_server_hello(SSL *s)
 {
     char buf[8];
     unsigned char *p;
     int i;
     int n;
 
     n = ssl23_read_bytes(s, 7);
 
     if (n != 7)
         return (n);
     p = s->packet;
 
     memcpy(buf, p, n);
 
     if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) &&
         (p[5] == 0x00) && (p[6] == 0x02)) {
 #ifdef OPENSSL_NO_SSL2
         SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
         goto err;
 #else
         /* we are talking sslv2 */
         /*
          * we need to clean up the SSLv3 setup and put in the sslv2 stuff.
          */
         int ch_len;
 
         if (s->options & SSL_OP_NO_SSLv2) {
             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
             goto err;
         }
         if (s->s2 == NULL) {
             if (!ssl2_new(s))
                 goto err;
         } else
             ssl2_clear(s);
 
         if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG)
             ch_len = SSL2_CHALLENGE_LENGTH;
         else
             ch_len = SSL2_MAX_CHALLENGE_LENGTH;
 
         /* write out sslv2 challenge */
         /*
          * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is
          * one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH
          * (16), but leave the check in for futurproofing
          */
         i = (SSL3_RANDOM_SIZE < ch_len)
             ? SSL3_RANDOM_SIZE : ch_len;
         s->s2->challenge_length = i;
         memcpy(s->s2->challenge,
                &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i);
 
         if (s->s3 != NULL)
             ssl3_free(s);
 
         if (!BUF_MEM_grow_clean(s->init_buf,
                                 SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) {
             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB);
             goto err;
         }
 
         s->state = SSL2_ST_GET_SERVER_HELLO_A;
         if (!(s->client_version == SSL2_VERSION))
             /*
              * use special padding (SSL 3.0 draft/RFC 2246, App. E.2)
              */
             s->s2->ssl2_rollback = 1;
 
         /*
          * setup the 7 bytes we have read so we get them from the sslv2
          * buffer
          */
         s->rstate = SSL_ST_READ_HEADER;
         s->packet_length = n;
         s->packet = &(s->s2->rbuf[0]);
         memcpy(s->packet, buf, n);
         s->s2->rbuf_left = n;
         s->s2->rbuf_offs = 0;
 
         /* we have already written one */
         s->s2->write_sequence = 1;
 
         s->method = SSLv2_client_method();
         s->handshake_func = s->method->ssl_connect;
 #endif
     } else if (p[1] == SSL3_VERSION_MAJOR &&
                p[2] <= TLS1_2_VERSION_MINOR &&
                ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) ||
                 (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) {
         /* we have sslv3 or tls1 (server hello or alert) */
 
 #ifndef OPENSSL_NO_SSL3
         if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) {
 # ifdef OPENSSL_FIPS
             if (FIPS_mode()) {
                 SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,
                        SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
                 goto err;
             }
 # endif
             s->version = SSL3_VERSION;
             s->method = SSLv3_client_method();
         } else
 #endif
         if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) {
             s->version = TLS1_VERSION;
             s->method = TLSv1_client_method();
         } else if ((p[2] == TLS1_1_VERSION_MINOR) &&
                    !(s->options & SSL_OP_NO_TLSv1_1)) {
             s->version = TLS1_1_VERSION;
             s->method = TLSv1_1_client_method();
         } else if ((p[2] == TLS1_2_VERSION_MINOR) &&
                    !(s->options & SSL_OP_NO_TLSv1_2)) {
             s->version = TLS1_2_VERSION;
             s->method = TLSv1_2_client_method();
         } else {
             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
             goto err;
         }
 
         s->session->ssl_version = s->version;
 
         /* ensure that TLS_MAX_VERSION is up-to-date */
         OPENSSL_assert(s->version <= TLS_MAX_VERSION);
 
         if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) {
             /* fatal alert */
 
             void (*cb) (const SSL *ssl, int type, int val) = NULL;
             int j;
 
             if (s->info_callback != NULL)
                 cb = s->info_callback;
             else if (s->ctx->info_callback != NULL)
                 cb = s->ctx->info_callback;
 
             i = p[5];
             if (cb != NULL) {
                 j = (i << 8) | p[6];
                 cb(s, SSL_CB_READ_ALERT, j);
             }
 
             if (s->msg_callback)
                 s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s,
                                 s->msg_callback_arg);
 
             s->rwstate = SSL_NOTHING;
             SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]);
             goto err;
         }
 
         if (!ssl_init_wbio_buffer(s, 1))
             goto err;
 
         /* we are in this state */
         s->state = SSL3_ST_CR_SRVR_HELLO_A;
 
         /*
          * put the 7 bytes we have read into the input buffer for SSLv3
          */
         s->rstate = SSL_ST_READ_HEADER;
         s->packet_length = n;
         if (s->s3->rbuf.buf == NULL)
             if (!ssl3_setup_read_buffer(s))
                 goto err;
         s->packet = &(s->s3->rbuf.buf[0]);
         memcpy(s->packet, buf, n);
         s->s3->rbuf.left = n;
         s->s3->rbuf.offset = 0;
 
         s->handshake_func = s->method->ssl_connect;
     } else {
         SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL);
         goto err;
     }
     s->init_num = 0;
 
     return (SSL_connect(s));
  err:
     return (-1);
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s2_clnt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s2_clnt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s2_clnt.c	(revision 306191)
@@ -1,1094 +1,1094 @@
 /* ssl/s2_clnt.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/rand.h>
 # include <openssl/buffer.h>
 # include <openssl/objects.h>
 # include <openssl/evp.h>
 
 static const SSL_METHOD *ssl2_get_client_method(int ver);
 static int get_server_finished(SSL *s);
 static int get_server_verify(SSL *s);
 static int get_server_hello(SSL *s);
 static int client_hello(SSL *s);
 static int client_master_key(SSL *s);
 static int client_finished(SSL *s);
 static int client_certificate(SSL *s);
 static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
                                   unsigned char *to, int padding);
 # define BREAK   break
 
 static const SSL_METHOD *ssl2_get_client_method(int ver)
 {
     if (ver == SSL2_VERSION)
         return (SSLv2_client_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_ssl2_meth_func(SSLv2_client_method,
                          ssl_undefined_function,
                          ssl2_connect, ssl2_get_client_method)
 
 int ssl2_connect(SSL *s)
 {
     unsigned long l = (unsigned long)time(NULL);
     BUF_MEM *buf = NULL;
     int ret = -1;
     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);
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_BEFORE:
         case SSL_ST_CONNECT:
         case SSL_ST_BEFORE | SSL_ST_CONNECT:
         case SSL_ST_OK | SSL_ST_CONNECT:
 
             s->server = 0;
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
             s->version = SSL2_VERSION;
             s->type = SSL_ST_CONNECT;
 
             buf = s->init_buf;
             if ((buf == NULL) && ((buf = BUF_MEM_new()) == NULL)) {
                 ret = -1;
                 goto end;
             }
             if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) {
                 if (buf == s->init_buf)
                     buf = NULL;
                 ret = -1;
                 goto end;
             }
             s->init_buf = buf;
             buf = NULL;
             s->init_num = 0;
             s->state = SSL2_ST_SEND_CLIENT_HELLO_A;
             s->ctx->stats.sess_connect++;
             s->handshake_func = ssl2_connect;
             BREAK;
 
         case SSL2_ST_SEND_CLIENT_HELLO_A:
         case SSL2_ST_SEND_CLIENT_HELLO_B:
             s->shutdown = 0;
             ret = client_hello(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL2_ST_GET_SERVER_HELLO_A;
             BREAK;
 
         case SSL2_ST_GET_SERVER_HELLO_A:
         case SSL2_ST_GET_SERVER_HELLO_B:
             ret = get_server_hello(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             if (!s->hit) {      /* new session */
                 s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_A;
                 BREAK;
             } else {
                 s->state = SSL2_ST_CLIENT_START_ENCRYPTION;
                 break;
             }
 
         case SSL2_ST_SEND_CLIENT_MASTER_KEY_A:
         case SSL2_ST_SEND_CLIENT_MASTER_KEY_B:
             ret = client_master_key(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL2_ST_CLIENT_START_ENCRYPTION;
             break;
 
         case SSL2_ST_CLIENT_START_ENCRYPTION:
             /*
              * Ok, we now have all the stuff needed to start encrypting, so
              * lets fire it up :-)
              */
             if (!ssl2_enc_init(s, 1)) {
                 ret = -1;
                 goto end;
             }
             s->s2->clear_text = 0;
             s->state = SSL2_ST_SEND_CLIENT_FINISHED_A;
             break;
 
         case SSL2_ST_SEND_CLIENT_FINISHED_A:
         case SSL2_ST_SEND_CLIENT_FINISHED_B:
             ret = client_finished(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL2_ST_GET_SERVER_VERIFY_A;
             break;
 
         case SSL2_ST_GET_SERVER_VERIFY_A:
         case SSL2_ST_GET_SERVER_VERIFY_B:
             ret = get_server_verify(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL2_ST_GET_SERVER_FINISHED_A;
             break;
 
         case SSL2_ST_GET_SERVER_FINISHED_A:
         case SSL2_ST_GET_SERVER_FINISHED_B:
             ret = get_server_finished(s);
             if (ret <= 0)
                 goto end;
             break;
 
         case SSL2_ST_SEND_CLIENT_CERTIFICATE_A:
         case SSL2_ST_SEND_CLIENT_CERTIFICATE_B:
         case SSL2_ST_SEND_CLIENT_CERTIFICATE_C:
         case SSL2_ST_SEND_CLIENT_CERTIFICATE_D:
         case SSL2_ST_X509_GET_CLIENT_CERTIFICATE:
             ret = client_certificate(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL2_ST_GET_SERVER_FINISHED_A;
             break;
 
         case SSL_ST_OK:
             if (s->init_buf != NULL) {
                 BUF_MEM_free(s->init_buf);
                 s->init_buf = NULL;
             }
             s->init_num = 0;
             /*      ERR_clear_error(); */
 
             /*
              * If we want to cache session-ids in the client and we
              * successfully add the session-id to the cache, and there is a
              * callback, then pass it out. 26/11/96 - eay - only add if not a
              * re-used session.
              */
 
             ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
             if (s->hit)
                 s->ctx->stats.sess_hit++;
 
             ret = 1;
             /* s->server=0; */
             s->ctx->stats.sess_connect_good++;
 
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_DONE, 1);
 
             goto end;
             /* break; */
         default:
             SSLerr(SSL_F_SSL2_CONNECT, SSL_R_UNKNOWN_STATE);
             return (-1);
             /* break; */
         }
 
         if ((cb != NULL) && (s->state != state)) {
             new_state = s->state;
             s->state = state;
             cb(s, SSL_CB_CONNECT_LOOP, 1);
             s->state = new_state;
         }
     }
  end:
     s->in_handshake--;
     if (buf != NULL)
         BUF_MEM_free(buf);
     if (cb != NULL)
         cb(s, SSL_CB_CONNECT_EXIT, ret);
     return (ret);
 }
 
 static int get_server_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p;
     int i, j;
     unsigned long len;
     STACK_OF(SSL_CIPHER) *sk = NULL, *cl, *prio, *allow;
 
     buf = (unsigned char *)s->init_buf->data;
     p = buf;
     if (s->state == SSL2_ST_GET_SERVER_HELLO_A) {
         i = ssl2_read(s, (char *)&(buf[s->init_num]), 11 - s->init_num);
         if (i < (11 - s->init_num))
             return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i));
         s->init_num = 11;
 
         if (*(p++) != SSL2_MT_SERVER_HELLO) {
             if (p[-1] != SSL2_MT_ERROR) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_READ_WRONG_PACKET_TYPE);
             } else
                 SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_PEER_ERROR);
             return (-1);
         }
 # if 0
         s->hit = (*(p++)) ? 1 : 0;
         /*
          * Some [PPC?] compilers fail to increment p in above statement, e.g.
          * one provided with Rhapsody 5.5, but most recent example XL C 11.1
          * for AIX, even without optimization flag...
          */
 # else
         s->hit = (*p) ? 1 : 0;
         p++;
 # endif
         s->s2->tmp.cert_type = *(p++);
         n2s(p, i);
         if (i < s->version)
             s->version = i;
         n2s(p, i);
         s->s2->tmp.cert_length = i;
         n2s(p, i);
         s->s2->tmp.csl = i;
         n2s(p, i);
         s->s2->tmp.conn_id_length = i;
         s->state = SSL2_ST_GET_SERVER_HELLO_B;
     }
 
     /* SSL2_ST_GET_SERVER_HELLO_B */
     len =
         11 + (unsigned long)s->s2->tmp.cert_length +
         (unsigned long)s->s2->tmp.csl +
         (unsigned long)s->s2->tmp.conn_id_length;
     if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) {
         SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_MESSAGE_TOO_LONG);
         return -1;
     }
     j = (int)len - s->init_num;
     i = ssl2_read(s, (char *)&(buf[s->init_num]), j);
     if (i != j)
         return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i));
     if (s->msg_callback) {
         /* SERVER-HELLO */
         s->msg_callback(0, s->version, 0, buf, (size_t)len, s,
                         s->msg_callback_arg);
     }
 
     /* things are looking good */
 
     p = buf + 11;
     if (s->hit) {
         if (s->s2->tmp.cert_length != 0) {
             SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CERT_LENGTH_NOT_ZERO);
             return (-1);
         }
         if (s->s2->tmp.cert_type != 0) {
             if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) {
                 SSLerr(SSL_F_GET_SERVER_HELLO,
                        SSL_R_REUSE_CERT_TYPE_NOT_ZERO);
                 return (-1);
             }
         }
         if (s->s2->tmp.csl != 0) {
             SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CIPHER_LIST_NOT_ZERO);
             return (-1);
         }
     } else {
 # ifdef undef
         /* very bad */
         memset(s->session->session_id, 0,
                SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES);
         s->session->session_id_length = 0;
         */
 # endif
             /*
              * we need to do this in case we were trying to reuse a client
              * session but others are already reusing it. If this was a new
              * 'blank' session ID, the session-id length will still be 0
              */
             if (s->session->session_id_length > 0) {
             if (!ssl_get_new_session(s, 0)) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 return (-1);
             }
         }
 
         if (ssl2_set_certificate(s, s->s2->tmp.cert_type,
                                  s->s2->tmp.cert_length, p) <= 0) {
             ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE);
             return (-1);
         }
         p += s->s2->tmp.cert_length;
 
         if (s->s2->tmp.csl == 0) {
             ssl2_return_error(s, SSL2_PE_NO_CIPHER);
             SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_LIST);
             return (-1);
         }
 
         /*
          * We have just received a list of ciphers back from the server.  We
          * need to get the ones that match, then select the one we want the
          * most :-).
          */
 
         /* load the ciphers */
         sk = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.csl,
                                       &s->session->ciphers);
         p += s->s2->tmp.csl;
         if (sk == NULL) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_MALLOC_FAILURE);
             return (-1);
         }
 
         (void)sk_SSL_CIPHER_set_cmp_func(sk, ssl_cipher_ptr_id_cmp);
 
         /* get the array of ciphers we will accept */
         cl = SSL_get_ciphers(s);
         (void)sk_SSL_CIPHER_set_cmp_func(cl, ssl_cipher_ptr_id_cmp);
 
         /*
          * If server preference flag set, choose the first
          * (highest priority) cipher the server sends, otherwise
          * client preference has priority.
          */
         if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
             prio = sk;
             allow = cl;
         } else {
             prio = cl;
             allow = sk;
         }
         /*
          * In theory we could have ciphers sent back that we don't want to
          * use but that does not matter since we will check against the list
          * we originally sent and for performance reasons we should not
          * bother to match the two lists up just to check.
          */
         for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
             if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, i)) >= 0)
                 break;
         }
 
         if (i >= sk_SSL_CIPHER_num(prio)) {
             ssl2_return_error(s, SSL2_PE_NO_CIPHER);
             SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_MATCH);
             return (-1);
         }
         s->session->cipher = sk_SSL_CIPHER_value(prio, i);
 
         if (s->session->peer != NULL) { /* can't happen */
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             return (-1);
         }
 
         s->session->peer = s->session->sess_cert->peer_key->x509;
         /* peer_key->x509 has been set by ssl2_set_certificate. */
         CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509);
     }
 
     if (s->session->sess_cert == NULL
         || s->session->peer != s->session->sess_cert->peer_key->x509)
         /* can't happen */
     {
         ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
         return (-1);
     }
 
     s->s2->conn_id_length = s->s2->tmp.conn_id_length;
     if (s->s2->conn_id_length > sizeof s->s2->conn_id) {
         ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG);
         return -1;
     }
     memcpy(s->s2->conn_id, p, s->s2->tmp.conn_id_length);
     return (1);
 }
 
 static int client_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
 /*      CIPHER **cipher;*/
     int i, n, j;
 
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) {
         if ((s->session == NULL) || (s->session->ssl_version != s->version)) {
             if (!ssl_get_new_session(s, 0)) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 return (-1);
             }
         }
         /* else use the pre-loaded session */
 
         p = buf;                /* header */
         d = p + 9;              /* data section */
         *(p++) = SSL2_MT_CLIENT_HELLO; /* type */
         s2n(SSL2_VERSION, p);   /* version */
         n = j = 0;
 
         n = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), d, 0);
         d += n;
 
         if (n == 0) {
             SSLerr(SSL_F_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
             return (-1);
         }
 
         s2n(n, p);              /* cipher spec num bytes */
 
         if ((s->session->session_id_length > 0) &&
             (s->session->session_id_length <=
              SSL2_MAX_SSL_SESSION_ID_LENGTH)) {
             i = s->session->session_id_length;
             s2n(i, p);          /* session id length */
             memcpy(d, s->session->session_id, (unsigned int)i);
             d += i;
         } else {
             s2n(0, p);
         }
 
         s->s2->challenge_length = SSL2_CHALLENGE_LENGTH;
         s2n(SSL2_CHALLENGE_LENGTH, p); /* challenge length */
         /*
          * challenge id data
          */
-        if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0)
+        if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0)
             return -1;
         memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH);
         d += SSL2_CHALLENGE_LENGTH;
 
         s->state = SSL2_ST_SEND_CLIENT_HELLO_B;
         s->init_num = d - buf;
         s->init_off = 0;
     }
     /* SSL2_ST_SEND_CLIENT_HELLO_B */
     return (ssl2_do_write(s));
 }
 
 static int client_master_key(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int clear, enc, karg, i;
     SSL_SESSION *sess;
     const EVP_CIPHER *c;
     const EVP_MD *md;
 
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) {
 
         if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) {
             ssl2_return_error(s, SSL2_PE_NO_CIPHER);
             SSLerr(SSL_F_CLIENT_MASTER_KEY,
                    SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS);
             return (-1);
         }
         sess = s->session;
         p = buf;
         d = p + 10;
         *(p++) = SSL2_MT_CLIENT_MASTER_KEY; /* type */
 
         i = ssl_put_cipher_by_char(s, sess->cipher, p);
         p += i;
 
         /* make key_arg data */
         i = EVP_CIPHER_iv_length(c);
         sess->key_arg_length = i;
         if (i > SSL_MAX_KEY_ARG_LENGTH) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
             return -1;
         }
         if (i > 0)
-            if (RAND_pseudo_bytes(sess->key_arg, i) <= 0)
+            if (RAND_bytes(sess->key_arg, i) <= 0)
                 return -1;
 
         /* make a master key */
         i = EVP_CIPHER_key_length(c);
         sess->master_key_length = i;
         if (i > 0) {
             if (i > (int)sizeof(sess->master_key)) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
                 return -1;
             }
             if (RAND_bytes(sess->master_key, i) <= 0) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 return (-1);
             }
         }
 
         if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC)
             enc = 8;
         else if (SSL_C_IS_EXPORT(sess->cipher))
             enc = 5;
         else
             enc = i;
 
         if ((int)i < enc) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_CIPHER_TABLE_SRC_ERROR);
             return (-1);
         }
         clear = i - enc;
         s2n(clear, p);
         memcpy(d, sess->master_key, (unsigned int)clear);
         d += clear;
 
         enc = ssl_rsa_public_encrypt(sess->sess_cert, enc,
                                      &(sess->master_key[clear]), d,
                                      (s->
                                       s2->ssl2_rollback) ? RSA_SSLV23_PADDING
                                      : RSA_PKCS1_PADDING);
         if (enc <= 0) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_PUBLIC_KEY_ENCRYPT_ERROR);
             return (-1);
         }
 # ifdef PKCS1_CHECK
         if (s->options & SSL_OP_PKCS1_CHECK_1)
             d[1]++;
         if (s->options & SSL_OP_PKCS1_CHECK_2)
             sess->master_key[clear]++;
 # endif
         s2n(enc, p);
         d += enc;
         karg = sess->key_arg_length;
         s2n(karg, p);           /* key arg size */
         if (karg > (int)sizeof(sess->key_arg)) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR);
             return -1;
         }
         memcpy(d, sess->key_arg, (unsigned int)karg);
         d += karg;
 
         s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_B;
         s->init_num = d - buf;
         s->init_off = 0;
     }
 
     /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */
     return (ssl2_do_write(s));
 }
 
 static int client_finished(SSL *s)
 {
     unsigned char *p;
 
     if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A) {
         p = (unsigned char *)s->init_buf->data;
         *(p++) = SSL2_MT_CLIENT_FINISHED;
         if (s->s2->conn_id_length > sizeof s->s2->conn_id) {
             SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR);
             return -1;
         }
         memcpy(p, s->s2->conn_id, (unsigned int)s->s2->conn_id_length);
 
         s->state = SSL2_ST_SEND_CLIENT_FINISHED_B;
         s->init_num = s->s2->conn_id_length + 1;
         s->init_off = 0;
     }
     return (ssl2_do_write(s));
 }
 
 /* read the data and then respond */
 static int client_certificate(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int i;
     unsigned int n;
     int cert_ch_len;
     unsigned char *cert_ch;
 
     buf = (unsigned char *)s->init_buf->data;
 
     /*
      * We have a cert associated with the SSL, so attach it to the session if
      * it does not have one
      */
 
     if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) {
         i = ssl2_read(s, (char *)&(buf[s->init_num]),
                       SSL2_MAX_CERT_CHALLENGE_LENGTH + 2 - s->init_num);
         if (i < (SSL2_MIN_CERT_CHALLENGE_LENGTH + 2 - s->init_num))
             return (ssl2_part_read(s, SSL_F_CLIENT_CERTIFICATE, i));
         s->init_num += i;
         if (s->msg_callback) {
             /* REQUEST-CERTIFICATE */
             s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s,
                             s->msg_callback_arg);
         }
 
         /* type=buf[0]; */
         /* type eq x509 */
         if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) {
             ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE);
             SSLerr(SSL_F_CLIENT_CERTIFICATE, SSL_R_BAD_AUTHENTICATION_TYPE);
             return (-1);
         }
 
         if ((s->cert == NULL) ||
             (s->cert->key->x509 == NULL) ||
             (s->cert->key->privatekey == NULL)) {
             s->state = SSL2_ST_X509_GET_CLIENT_CERTIFICATE;
         } else
             s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
     }
 
     cert_ch = buf + 2;
     cert_ch_len = s->init_num - 2;
 
     if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) {
         X509 *x509 = NULL;
         EVP_PKEY *pkey = NULL;
 
         /*
          * If we get an error we need to ssl->rwstate=SSL_X509_LOOKUP;
          * return(error); We should then be retried when things are ok and we
          * can get a cert or not
          */
 
         i = 0;
         if (s->ctx->client_cert_cb != NULL) {
             i = s->ctx->client_cert_cb(s, &(x509), &(pkey));
         }
 
         if (i < 0) {
             s->rwstate = SSL_X509_LOOKUP;
             return (-1);
         }
         s->rwstate = SSL_NOTHING;
 
         if ((i == 1) && (pkey != NULL) && (x509 != NULL)) {
             s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C;
             if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) {
                 i = 0;
             }
             X509_free(x509);
             EVP_PKEY_free(pkey);
         } else if (i == 1) {
             if (x509 != NULL)
                 X509_free(x509);
             if (pkey != NULL)
                 EVP_PKEY_free(pkey);
             SSLerr(SSL_F_CLIENT_CERTIFICATE,
                    SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
             i = 0;
         }
 
         if (i == 0) {
             /*
              * We have no client certificate to respond with so send the
              * correct error message back
              */
             s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_B;
             p = buf;
             *(p++) = SSL2_MT_ERROR;
             s2n(SSL2_PE_NO_CERTIFICATE, p);
             s->init_off = 0;
             s->init_num = 3;
             /* Write is done at the end */
         }
     }
 
     if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) {
         return (ssl2_do_write(s));
     }
 
     if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) {
         EVP_MD_CTX ctx;
 
         /*
          * ok, now we calculate the checksum do it first so we can reuse buf
          * :-)
          */
         p = buf;
         EVP_MD_CTX_init(&ctx);
         EVP_SignInit_ex(&ctx, s->ctx->rsa_md5, NULL);
         EVP_SignUpdate(&ctx, s->s2->key_material, s->s2->key_material_length);
         EVP_SignUpdate(&ctx, cert_ch, (unsigned int)cert_ch_len);
         i = i2d_X509(s->session->sess_cert->peer_key->x509, &p);
         /*
          * Don't update the signature if it fails - FIXME: probably should
          * handle this better
          */
         if (i > 0)
             EVP_SignUpdate(&ctx, buf, (unsigned int)i);
 
         p = buf;
         d = p + 6;
         *(p++) = SSL2_MT_CLIENT_CERTIFICATE;
         *(p++) = SSL2_CT_X509_CERTIFICATE;
         n = i2d_X509(s->cert->key->x509, &d);
         s2n(n, p);
 
         if (!EVP_SignFinal(&ctx, d, &n, s->cert->key->privatekey)) {
             /*
              * this is not good.  If things have failed it means there so
              * something wrong with the key. We will continue with a 0 length
              * signature
              */
         }
         EVP_MD_CTX_cleanup(&ctx);
         s2n(n, p);
         d += n;
 
         s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_D;
         s->init_num = d - buf;
         s->init_off = 0;
     }
     /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */
     return (ssl2_do_write(s));
 }
 
 static int get_server_verify(SSL *s)
 {
     unsigned char *p;
     int i, n, len;
 
     p = (unsigned char *)s->init_buf->data;
     if (s->state == SSL2_ST_GET_SERVER_VERIFY_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_SERVER_VERIFY, i));
         s->init_num += i;
 
         s->state = SSL2_ST_GET_SERVER_VERIFY_B;
         if (*p != SSL2_MT_SERVER_VERIFY) {
             if (p[0] != SSL2_MT_ERROR) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE);
             } else {
                 SSLerr(SSL_F_GET_SERVER_VERIFY, 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);
         }
     }
 
     p = (unsigned char *)s->init_buf->data;
     len = 1 + s->s2->challenge_length;
     n = 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_SERVER_VERIFY, i));
     if (s->msg_callback) {
         /* SERVER-VERIFY */
         s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg);
     }
     p += 1;
 
     if (CRYPTO_memcmp(p, s->s2->challenge, s->s2->challenge_length) != 0) {
         ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_CHALLENGE_IS_DIFFERENT);
         return (-1);
     }
     return (1);
 }
 
 static int get_server_finished(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p;
     int i, n, len;
 
     buf = (unsigned char *)s->init_buf->data;
     p = buf;
     if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) {
         i = ssl2_read(s, (char *)&(buf[s->init_num]), 1 - s->init_num);
         if (i < (1 - s->init_num))
             return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i));
         s->init_num += i;
 
         if (*p == SSL2_MT_REQUEST_CERTIFICATE) {
             s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_A;
             return (1);
         } else if (*p != SSL2_MT_SERVER_FINISHED) {
             if (p[0] != SSL2_MT_ERROR) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 SSLerr(SSL_F_GET_SERVER_FINISHED,
                        SSL_R_READ_WRONG_PACKET_TYPE);
             } else {
                 SSLerr(SSL_F_GET_SERVER_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_SERVER_FINISHED_B;
     }
 
     len = 1 + SSL2_SSL_SESSION_ID_LENGTH;
     n = len - s->init_num;
     i = ssl2_read(s, (char *)&(buf[s->init_num]), n);
     if (i < n) {
         /*
          * XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH,
          * that's the maximum
          */
         return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i));
     }
     s->init_num += i;
     if (s->msg_callback) {
         /* SERVER-FINISHED */
         s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s,
                         s->msg_callback_arg);
     }
 
     if (!s->hit) {              /* new session */
         /* new session-id */
         /*
          * Make sure we were not trying to re-use an old SSL_SESSION or bad
          * things can happen
          */
         /* ZZZZZZZZZZZZZ */
         s->session->session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
         memcpy(s->session->session_id, p + 1, SSL2_SSL_SESSION_ID_LENGTH);
     } else {
         if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) {
             if ((s->session->session_id_length >
                  sizeof s->session->session_id)
                 || (0 !=
                     memcmp(buf + 1, s->session->session_id,
                            (unsigned int)s->session->session_id_length))) {
                 ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
                 SSLerr(SSL_F_GET_SERVER_FINISHED,
                        SSL_R_SSL_SESSION_ID_IS_DIFFERENT);
                 return (-1);
             }
         }
     }
     s->state = SSL_ST_OK;
     return (1);
 }
 
 /* loads in the certificate from the server */
 int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data)
 {
     STACK_OF(X509) *sk = NULL;
     EVP_PKEY *pkey = NULL;
     SESS_CERT *sc = NULL;
     int i;
     X509 *x509 = NULL;
     int ret = 0;
 
     x509 = d2i_X509(NULL, &data, (long)len);
     if (x509 == NULL) {
         SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_X509_LIB);
         goto err;
     }
 
     if ((sk = sk_X509_new_null()) == NULL || !sk_X509_push(sk, x509)) {
         SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     i = ssl_verify_cert_chain(s, sk);
 
     if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) {
         SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED);
         goto err;
     }
     ERR_clear_error();          /* but we keep s->verify_result */
     s->session->verify_result = s->verify_result;
 
     /* server's cert for this session */
     sc = ssl_sess_cert_new();
     if (sc == NULL) {
         ret = -1;
         goto err;
     }
     if (s->session->sess_cert)
         ssl_sess_cert_free(s->session->sess_cert);
     s->session->sess_cert = sc;
 
     sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509 = x509;
     sc->peer_key = &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]);
 
     pkey = X509_get_pubkey(x509);
     x509 = NULL;
     if (pkey == NULL) {
         SSLerr(SSL_F_SSL2_SET_CERTIFICATE,
                SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY);
         goto err;
     }
     if (pkey->type != EVP_PKEY_RSA) {
         SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_PUBLIC_KEY_NOT_RSA);
         goto err;
     }
 
     if (!ssl_set_peer_cert_type(sc, SSL2_CT_X509_CERTIFICATE))
         goto err;
     ret = 1;
  err:
     sk_X509_free(sk);
     X509_free(x509);
     EVP_PKEY_free(pkey);
     return (ret);
 }
 
 static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from,
                                   unsigned char *to, int padding)
 {
     EVP_PKEY *pkey = NULL;
     int i = -1;
 
     if ((sc == NULL) || (sc->peer_key->x509 == NULL) ||
         ((pkey = X509_get_pubkey(sc->peer_key->x509)) == NULL)) {
         SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_NO_PUBLICKEY);
         return (-1);
     }
     if (pkey->type != EVP_PKEY_RSA) {
         SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA);
         goto end;
     }
 
     /* we have the public key */
     i = RSA_public_encrypt(len, from, to, pkey->pkey.rsa, padding);
     if (i < 0)
         SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, ERR_R_RSA_LIB);
  end:
     EVP_PKEY_free(pkey);
     return (i);
 }
 #else                           /* !OPENSSL_NO_SSL2 */
 
 # if PEDANTIC
 static void *dummy = &dummy;
 # endif
 
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s2_srvr.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s2_srvr.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s2_srvr.c	(revision 306191)
@@ -1,1171 +1,1167 @@
 /* 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 "../crypto/constant_time_locl.h"
 # 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;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     goto end;
                 }
                 if (!BUF_MEM_grow
                     (buf, (int)SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) {
                     BUF_MEM_free(buf);
                     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;
     unsigned int num_encrypted_key_bytes, key_length;
     unsigned long len;
     unsigned char *p;
     const SSL_CIPHER *cp;
     const EVP_CIPHER *c;
     const EVP_MD *md;
     unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
     unsigned char decrypt_good;
     size_t j;
 
     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 || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) {
             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) {
         /* CLIENT-MASTER-KEY */
         s->msg_callback(0, s->version, 0, p, (size_t)len, s,
                         s->msg_callback_arg);
     }
     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);
     }
 
     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);
     }
 
     /*
      * The format of the CLIENT-MASTER-KEY message is
      * 1 byte message type
      * 3 bytes cipher
      * 2-byte clear key length (stored in s->s2->tmp.clear)
      * 2-byte encrypted key length (stored in s->s2->tmp.enc)
      * 2-byte key args length (IV etc)
      * clear key
      * encrypted key
      * key args
      *
      * If the cipher is an export cipher, then the encrypted key bytes
      * are a fixed portion of the total key (5 or 8 bytes). The size of
      * this portion is in |num_encrypted_key_bytes|. If the cipher is not an
      * export cipher, then the entire key material is encrypted (i.e., clear
      * key length must be zero).
      */
     key_length = (unsigned int)EVP_CIPHER_key_length(c);
     if (key_length > 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;
     }
 
     if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) {
         is_export = 1;
         num_encrypted_key_bytes = 8;
     } else if (is_export) {
         num_encrypted_key_bytes = 5;
     } else {
         num_encrypted_key_bytes = key_length;
     }
 
     if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) {
         ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH);
         return -1;
     }
     /*
      * The encrypted blob must decrypt to the encrypted portion of the key.
      * Decryption can't be expanding, so if we don't have enough encrypted
      * bytes to fit the key in the buffer, stop now.
      */
     if (s->s2->tmp.enc < num_encrypted_key_bytes) {
         ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR);
         SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT);
         return -1;
     }
 
     /*
      * We must not leak whether a decryption failure occurs because of
      * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
      * section 7.4.7.1). The code follows that advice of the TLS RFC and
      * generates a random premaster secret for the case that the decrypt
      * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
      */
 
-    /*
-     * should be RAND_bytes, but we cannot work around a failure.
-     */
-    if (RAND_pseudo_bytes(rand_premaster_secret,
-                          (int)num_encrypted_key_bytes) <= 0)
+    if (RAND_bytes(rand_premaster_secret,
+                  (int)num_encrypted_key_bytes) <= 0)
         return 0;
 
     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);
     ERR_clear_error();
     /*
      * If a bad decrypt, continue with protocol but with a random master
      * secret (Bleichenbacher attack)
      */
     decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes);
     for (j = 0; j < num_encrypted_key_bytes; j++) {
         p[s->s2->tmp.clear + j] =
                 constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j],
                                        rand_premaster_secret[j]);
     }
 
     s->session->master_key_length = (int)key_length;
     memcpy(s->session->master_key, p, key_length);
     OPENSSL_cleanse(p, key_length);
 
     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;
         if ((i < 0) || (i > SSL_MAX_SSL_SESSION_ID_LENGTH)) {
             ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR);
             SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
             return -1;
         }
         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) {
         /* CLIENT-HELLO */
         s->msg_callback(0, s->version, 0, p, (size_t)len, s,
                         s->msg_callback_arg);
     }
     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;
         }
 
         /* Generate list of SSLv2 ciphers shared between client and server */
         for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) {
             const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z);
             if ((cp->algorithm_ssl & SSL_SSLV2) == 0 ||
                 sk_SSL_CIPHER_find(allow, cp) < 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;
         }
 
         /* Make sure we have at least one cipher in common */
         if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) {
             ssl2_return_error(s, SSL2_PE_NO_CIPHER);
             SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH);
             return -1;
         }
         /*
          * 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)
+        if (RAND_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) {
         /* CLIENT-FINISHED */
         s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg);
     }
     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)
+        if (RAND_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;
         /* try to read 6 octets ... */
         i = ssl2_read(s, (char *)&(p[s->init_num]), 6 - s->init_num);
         /*
          * ... but don't call ssl2_part_read now if we got at least 3
          * (probably NO-CERTIFICATE-ERROR)
          */
         if (i < 3 - s->init_num) {
             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) {
                 /* ERROR */
                 s->msg_callback(0, s->version, 0, p, 3, s,
                                 s->msg_callback_arg);
             }
 
             /*
              * 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) {
         /* CLIENT-CERTIFICATE */
         s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg);
     }
     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);
         if (!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))
             goto msg_end;
 
         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);
         if (!EVP_VerifyUpdate(&ctx, buf2, (unsigned int)i)) {
             OPENSSL_free(buf2);
             goto msg_end;
         }
         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
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s3_both.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s3_both.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s3_both.c	(revision 306191)
@@ -1,818 +1,826 @@
 /* ssl/s3_both.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-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.
  * ECC cipher suite support in OpenSSL originally developed by
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 
 #include <limits.h>
 #include <string.h>
 #include <stdio.h>
 #include "ssl_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
 
 /*
  * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or
  * SSL3_RT_CHANGE_CIPHER_SPEC)
  */
 int ssl3_do_write(SSL *s, int type)
 {
     int ret;
 
     ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off],
                            s->init_num);
     if (ret < 0)
         return (-1);
     if (type == SSL3_RT_HANDSHAKE)
         /*
          * should not be done for 'Hello Request's, but in that case we'll
          * ignore the result anyway
          */
         ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off],
                         ret);
 
     if (ret == s->init_num) {
         if (s->msg_callback)
             s->msg_callback(1, s->version, type, s->init_buf->data,
                             (size_t)(s->init_off + s->init_num), s,
                             s->msg_callback_arg);
         return (1);
     }
     s->init_off += ret;
     s->init_num -= ret;
     return (0);
 }
 
 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen)
 {
     unsigned char *p, *d;
     int i;
     unsigned long l;
 
     if (s->state == a) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[4]);
 
         i = s->method->ssl3_enc->final_finish_mac(s,
                                                   sender, slen,
                                                   s->s3->tmp.finish_md);
         if (i <= 0)
             return 0;
         s->s3->tmp.finish_md_len = i;
         memcpy(p, s->s3->tmp.finish_md, i);
         p += i;
         l = i;
 
         /*
          * Copy the finished so we can use it for renegotiation checks
          */
         if (s->type == SSL_ST_CONNECT) {
             OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
             memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i);
             s->s3->previous_client_finished_len = i;
         } else {
             OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
             memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i);
             s->s3->previous_server_finished_len = i;
         }
 
 #ifdef OPENSSL_SYS_WIN16
         /*
          * MSVC 1.5 does not clear the top bytes of the word unless I do
          * this.
          */
         l &= 0xffff;
 #endif
 
         *(d++) = SSL3_MT_FINISHED;
         l2n3(l, d);
         s->init_num = (int)l + 4;
         s->init_off = 0;
 
         s->state = b;
     }
 
     /* SSL3_ST_SEND_xxxxxx_HELLO_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen
  * to far.
  */
 static void ssl3_take_mac(SSL *s)
 {
     const char *sender;
     int slen;
     /*
      * If no new cipher setup return immediately: other functions will set
      * the appropriate error.
      */
     if (s->s3->tmp.new_cipher == NULL)
         return;
     if (s->state & SSL_ST_CONNECT) {
         sender = s->method->ssl3_enc->server_finished_label;
         slen = s->method->ssl3_enc->server_finished_label_len;
     } else {
         sender = s->method->ssl3_enc->client_finished_label;
         slen = s->method->ssl3_enc->client_finished_label_len;
     }
 
     s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s,
                                                                           sender,
                                                                           slen,
                                                                           s->s3->tmp.peer_finish_md);
 }
 #endif
 
 int ssl3_get_finished(SSL *s, int a, int b)
 {
     int al, i, ok;
     long n;
     unsigned char *p;
 
 #ifdef OPENSSL_NO_NEXTPROTONEG
     /*
      * the mac has already been generated when we received the change cipher
      * spec message and is in s->s3->tmp.peer_finish_md.
      */
 #endif
 
     /* 64 argument should actually be 36+4 :-) */
     n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok);
 
     if (!ok)
         return ((int)n);
 
     /* If this occurs, we have missed a message */
     if (!s->s3->change_cipher_spec) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
         goto f_err;
     }
     s->s3->change_cipher_spec = 0;
 
     p = (unsigned char *)s->init_msg;
     i = s->s3->tmp.peer_finish_md_len;
 
     if (i != n) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH);
         goto f_err;
     }
 
     if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) {
         al = SSL_AD_DECRYPT_ERROR;
         SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED);
         goto f_err;
     }
 
     /*
      * Copy the finished so we can use it for renegotiation checks
      */
     if (s->type == SSL_ST_ACCEPT) {
         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
         memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i);
         s->s3->previous_client_finished_len = i;
     } else {
         OPENSSL_assert(i <= EVP_MAX_MD_SIZE);
         memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i);
         s->s3->previous_server_finished_len = i;
     }
 
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
     return (0);
 }
 
 /*-
  * for these 2 messages, we need to
  * ssl->enc_read_ctx                    re-init
  * ssl->s3->read_sequence               zero
  * ssl->s3->read_mac_secret             re-init
  * ssl->session->read_sym_enc           assign
  * ssl->session->read_compression       assign
  * ssl->session->read_hash              assign
  */
 int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
 {
     unsigned char *p;
 
     if (s->state == a) {
         p = (unsigned char *)s->init_buf->data;
         *p = SSL3_MT_CCS;
         s->init_num = 1;
         s->init_off = 0;
 
         s->state = b;
     }
 
     /* SSL3_ST_CW_CHANGE_B */
     return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC));
 }
 
 static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
 {
     int n;
     unsigned char *p;
 
     n = i2d_X509(x, NULL);
     if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
         SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF, ERR_R_BUF_LIB);
         return (-1);
     }
     p = (unsigned char *)&(buf->data[*l]);
     l2n3(n, p);
     i2d_X509(x, &p);
     *l += n + 3;
 
     return (0);
 }
 
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
 {
     unsigned char *p;
     int i;
     unsigned long l = 7;
     BUF_MEM *buf;
     int no_chain;
 
     if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
         no_chain = 1;
     else
         no_chain = 0;
 
     /* TLSv1 sends a chain with nothing in it, instead of an alert */
     buf = s->init_buf;
     if (!BUF_MEM_grow_clean(buf, 10)) {
         SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB);
         return (0);
     }
     if (x != NULL) {
         if (no_chain) {
             if (ssl3_add_cert_to_buf(buf, &l, x))
                 return (0);
         } else {
             X509_STORE_CTX xs_ctx;
 
             if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, x, NULL)) {
                 SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_X509_LIB);
                 return (0);
             }
             X509_verify_cert(&xs_ctx);
             /* Don't leave errors in the queue */
             ERR_clear_error();
             for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) {
                 x = sk_X509_value(xs_ctx.chain, i);
 
                 if (ssl3_add_cert_to_buf(buf, &l, x)) {
                     X509_STORE_CTX_cleanup(&xs_ctx);
                     return 0;
                 }
             }
             X509_STORE_CTX_cleanup(&xs_ctx);
         }
     }
     /* Thawte special :-) */
     for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) {
         x = sk_X509_value(s->ctx->extra_certs, i);
         if (ssl3_add_cert_to_buf(buf, &l, x))
             return (0);
     }
 
     l -= 7;
     p = (unsigned char *)&(buf->data[4]);
     l2n3(l, p);
     l += 3;
     p = (unsigned char *)&(buf->data[0]);
     *(p++) = SSL3_MT_CERTIFICATE;
     l2n3(l, p);
     l += 4;
     return (l);
 }
 
 /*
  * Obtain handshake message of message type 'mt' (any if mt == -1), maximum
  * acceptable body length 'max'. The first four bytes (msg_type and length)
  * are read in state 'st1', the body is read in state 'stn'.
  */
 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
 {
     unsigned char *p;
     unsigned long l;
     long n;
     int i, al;
 
     if (s->s3->tmp.reuse_message) {
         s->s3->tmp.reuse_message = 0;
         if ((mt >= 0) && (s->s3->tmp.message_type != mt)) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
         *ok = 1;
         s->state = stn;
-        s->init_msg = s->init_buf->data + 4;
+        s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
         s->init_num = (int)s->s3->tmp.message_size;
         return s->init_num;
     }
 
     p = (unsigned char *)s->init_buf->data;
 
-    if (s->state == st1) {      /* s->init_num < 4 */
+    if (s->state == st1) {      /* s->init_num < SSL3_HM_HEADER_LENGTH */
         int skip_message;
 
         do {
-            while (s->init_num < 4) {
+            while (s->init_num < SSL3_HM_HEADER_LENGTH) {
                 i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
                                               &p[s->init_num],
-                                              4 - s->init_num, 0);
+                                              SSL3_HM_HEADER_LENGTH -
+                                              s->init_num, 0);
                 if (i <= 0) {
                     s->rwstate = SSL_READING;
                     *ok = 0;
                     return i;
                 }
                 s->init_num += i;
             }
 
             skip_message = 0;
             if (!s->server)
                 if (p[0] == SSL3_MT_HELLO_REQUEST)
                     /*
                      * The server may always send 'Hello Request' messages --
                      * we are doing a handshake anyway now, so ignore them if
                      * their format is correct. Does not count for 'Finished'
                      * MAC.
                      */
                     if (p[1] == 0 && p[2] == 0 && p[3] == 0) {
                         s->init_num = 0;
                         skip_message = 1;
 
                         if (s->msg_callback)
                             s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
-                                            p, 4, s, s->msg_callback_arg);
+                                            p, SSL3_HM_HEADER_LENGTH, s,
+                                            s->msg_callback_arg);
                     }
         }
         while (skip_message);
 
-        /* s->init_num == 4 */
+        /* s->init_num == SSL3_HM_HEADER_LENGTH */
 
         if ((mt >= 0) && (*p != mt)) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
         if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) &&
             (st1 == SSL3_ST_SR_CERT_A) && (stn == SSL3_ST_SR_CERT_B)) {
             /*
              * At this point we have got an MS SGC second client hello (maybe
              * we should always allow the client to start a new handshake?).
              * We need to restart the mac. Don't increment
              * {num,total}_renegotiations because we have not completed the
              * handshake.
              */
             ssl3_init_finished_mac(s);
         }
 
         s->s3->tmp.message_type = *(p++);
 
         n2l3(p, l);
         if (l > (unsigned long)max) {
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
             goto f_err;
         }
-        if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */
-            al = SSL_AD_ILLEGAL_PARAMETER;
-            SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
-            goto f_err;
-        }
-        if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) {
+        /*
+         * Make buffer slightly larger than message length as a precaution
+         * against small OOB reads e.g. CVE-2016-6306
+         */
+        if (l
+            && !BUF_MEM_grow_clean(s->init_buf,
+                                   (int)l + SSL3_HM_HEADER_LENGTH + 16)) {
             SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB);
             goto err;
         }
         s->s3->tmp.message_size = l;
         s->state = stn;
 
-        s->init_msg = s->init_buf->data + 4;
+        s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
         s->init_num = 0;
     }
 
     /* next state (stn) */
     p = s->init_msg;
     n = s->s3->tmp.message_size - s->init_num;
     while (n > 0) {
         i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num],
                                       n, 0);
         if (i <= 0) {
             s->rwstate = SSL_READING;
             *ok = 0;
             return i;
         }
         s->init_num += i;
         n -= i;
     }
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
     /*
      * If receiving Finished, record MAC of prior handshake messages for
      * Finished verification.
      */
     if (*s->init_buf->data == SSL3_MT_FINISHED)
         ssl3_take_mac(s);
 #endif
 
     /* Feed this message into MAC computation. */
-    ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+    ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+                    s->init_num + SSL3_HM_HEADER_LENGTH);
     if (s->msg_callback)
         s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
-                        (size_t)s->init_num + 4, s, s->msg_callback_arg);
+                        (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
+                        s->msg_callback_arg);
     *ok = 1;
     return s->init_num;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     *ok = 0;
     return (-1);
 }
 
 int ssl_cert_type(X509 *x, EVP_PKEY *pkey)
 {
     EVP_PKEY *pk;
     int ret = -1, i;
 
     if (pkey == NULL)
         pk = X509_get_pubkey(x);
     else
         pk = pkey;
     if (pk == NULL)
         goto err;
 
     i = pk->type;
     if (i == EVP_PKEY_RSA) {
         ret = SSL_PKEY_RSA_ENC;
     } else if (i == EVP_PKEY_DSA) {
         ret = SSL_PKEY_DSA_SIGN;
     }
 #ifndef OPENSSL_NO_EC
     else if (i == EVP_PKEY_EC) {
         ret = SSL_PKEY_ECC;
     }
 #endif
     else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) {
         ret = SSL_PKEY_GOST94;
     } else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) {
         ret = SSL_PKEY_GOST01;
     }
  err:
     if (!pkey)
         EVP_PKEY_free(pk);
     return (ret);
 }
 
 int ssl_verify_alarm_type(long type)
 {
     int al;
 
     switch (type) {
     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
     case X509_V_ERR_UNABLE_TO_GET_CRL:
     case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER:
         al = SSL_AD_UNKNOWN_CA;
         break;
     case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE:
     case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE:
     case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY:
     case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
     case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
     case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD:
     case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD:
     case X509_V_ERR_CERT_NOT_YET_VALID:
     case X509_V_ERR_CRL_NOT_YET_VALID:
     case X509_V_ERR_CERT_UNTRUSTED:
     case X509_V_ERR_CERT_REJECTED:
         al = SSL_AD_BAD_CERTIFICATE;
         break;
     case X509_V_ERR_CERT_SIGNATURE_FAILURE:
     case X509_V_ERR_CRL_SIGNATURE_FAILURE:
         al = SSL_AD_DECRYPT_ERROR;
         break;
     case X509_V_ERR_CERT_HAS_EXPIRED:
     case X509_V_ERR_CRL_HAS_EXPIRED:
         al = SSL_AD_CERTIFICATE_EXPIRED;
         break;
     case X509_V_ERR_CERT_REVOKED:
         al = SSL_AD_CERTIFICATE_REVOKED;
         break;
+    case X509_V_ERR_UNSPECIFIED:
     case X509_V_ERR_OUT_OF_MEM:
+    case X509_V_ERR_INVALID_CALL:
+    case X509_V_ERR_STORE_LOOKUP:
         al = SSL_AD_INTERNAL_ERROR;
         break;
     case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
     case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN:
     case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY:
     case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE:
     case X509_V_ERR_CERT_CHAIN_TOO_LONG:
     case X509_V_ERR_PATH_LENGTH_EXCEEDED:
     case X509_V_ERR_INVALID_CA:
         al = SSL_AD_UNKNOWN_CA;
         break;
     case X509_V_ERR_APPLICATION_VERIFICATION:
         al = SSL_AD_HANDSHAKE_FAILURE;
         break;
     case X509_V_ERR_INVALID_PURPOSE:
         al = SSL_AD_UNSUPPORTED_CERTIFICATE;
         break;
     default:
         al = SSL_AD_CERTIFICATE_UNKNOWN;
         break;
     }
     return (al);
 }
 
 #ifndef OPENSSL_NO_BUF_FREELISTS
 /*-
  * On some platforms, malloc() performance is bad enough that you can't just
  * free() and malloc() buffers all the time, so we need to use freelists from
  * unused buffers.  Currently, each freelist holds memory chunks of only a
  * given size (list->chunklen); other sized chunks are freed and malloced.
  * This doesn't help much if you're using many different SSL option settings
  * with a given context.  (The options affecting buffer size are
  * max_send_fragment, read buffer vs write buffer,
  * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and
  * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.)  Using a separate freelist for every
  * possible size is not an option, since max_send_fragment can take on many
  * different values.
  *
  * If you are on a platform with a slow malloc(), and you're using SSL
  * connections with many different settings for these options, and you need to
  * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options:
  *    - Link against a faster malloc implementation.
  *    - Use a separate SSL_CTX for each option set.
  *    - Improve this code.
  */
 static void *freelist_extract(SSL_CTX *ctx, int for_read, int sz)
 {
     SSL3_BUF_FREELIST *list;
     SSL3_BUF_FREELIST_ENTRY *ent = NULL;
     void *result = NULL;
 
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
     list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
     if (list != NULL && sz == (int)list->chunklen)
         ent = list->head;
     if (ent != NULL) {
         list->head = ent->next;
         result = ent;
         if (--list->len == 0)
             list->chunklen = 0;
     }
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
     if (!result)
         result = OPENSSL_malloc(sz);
     return result;
 }
 
 static void freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem)
 {
     SSL3_BUF_FREELIST *list;
     SSL3_BUF_FREELIST_ENTRY *ent;
 
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
     list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
     if (list != NULL &&
         (sz == list->chunklen || list->chunklen == 0) &&
         list->len < ctx->freelist_max_len && sz >= sizeof(*ent)) {
         list->chunklen = sz;
         ent = mem;
         ent->next = list->head;
         list->head = ent;
         ++list->len;
         mem = NULL;
     }
 
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
     if (mem)
         OPENSSL_free(mem);
 }
 #else
 # define freelist_extract(c,fr,sz) OPENSSL_malloc(sz)
 # define freelist_insert(c,fr,sz,m) OPENSSL_free(m)
 #endif
 
 int ssl3_setup_read_buffer(SSL *s)
 {
     unsigned char *p;
     size_t len, align = 0, headerlen;
 
     if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
         headerlen = DTLS1_RT_HEADER_LENGTH;
     else
         headerlen = SSL3_RT_HEADER_LENGTH;
 
 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
     align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
 #endif
 
     if (s->s3->rbuf.buf == NULL) {
         len = SSL3_RT_MAX_PLAIN_LENGTH
             + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
         if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
             s->s3->init_extra = 1;
             len += SSL3_RT_MAX_EXTRA;
         }
 #ifndef OPENSSL_NO_COMP
         if (!(s->options & SSL_OP_NO_COMPRESSION))
             len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
 #endif
         if ((p = freelist_extract(s->ctx, 1, len)) == NULL)
             goto err;
         s->s3->rbuf.buf = p;
         s->s3->rbuf.len = len;
     }
 
     s->packet = &(s->s3->rbuf.buf[0]);
     return 1;
 
  err:
     SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
 int ssl3_setup_write_buffer(SSL *s)
 {
     unsigned char *p;
     size_t len, align = 0, headerlen;
 
     if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER)
         headerlen = DTLS1_RT_HEADER_LENGTH + 1;
     else
         headerlen = SSL3_RT_HEADER_LENGTH;
 
 #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0
     align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
 #endif
 
     if (s->s3->wbuf.buf == NULL) {
         len = s->max_send_fragment
             + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align;
 #ifndef OPENSSL_NO_COMP
         if (!(s->options & SSL_OP_NO_COMPRESSION))
             len += SSL3_RT_MAX_COMPRESSED_OVERHEAD;
 #endif
         if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS))
             len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
 
         if ((p = freelist_extract(s->ctx, 0, len)) == NULL)
             goto err;
         s->s3->wbuf.buf = p;
         s->s3->wbuf.len = len;
     }
 
     return 1;
 
  err:
     SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE);
     return 0;
 }
 
 int ssl3_setup_buffers(SSL *s)
 {
     if (!ssl3_setup_read_buffer(s))
         return 0;
     if (!ssl3_setup_write_buffer(s))
         return 0;
     return 1;
 }
 
 int ssl3_release_write_buffer(SSL *s)
 {
     if (s->s3->wbuf.buf != NULL) {
         freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf);
         s->s3->wbuf.buf = NULL;
     }
     return 1;
 }
 
 int ssl3_release_read_buffer(SSL *s)
 {
     if (s->s3->rbuf.buf != NULL) {
         freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf);
         s->s3->rbuf.buf = NULL;
     }
     return 1;
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s3_clnt.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s3_clnt.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s3_clnt.c	(revision 306191)
@@ -1,3570 +1,3562 @@
 /* ssl/s3_clnt.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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by
  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
  *
  * The Contribution is licensed pursuant to the OpenSSL open source
  * license provided above.
  *
  * ECC cipher suite support in OpenSSL originally written by
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #include <stdio.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/md5.h>
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 #endif
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 
 static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
 #ifndef OPENSSL_NO_TLSEXT
 static int ssl3_check_finished(SSL *s);
 #endif
 
 #ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_client_method(int ver)
 {
     if (ver == SSL3_VERSION)
         return (SSLv3_client_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_ssl3_meth_func(SSLv3_client_method,
                          ssl_undefined_function,
                          ssl3_connect, ssl3_get_client_method)
 #endif
 int ssl3_connect(SSL *s)
 {
     BUF_MEM *buf = NULL;
     unsigned long Time = (unsigned long)time(NULL);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
     int ret = -1;
     int new_state, state, skip = 0;
 
     RAND_add(&Time, sizeof(Time), 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;
 
     s->in_handshake++;
     if (!SSL_in_init(s) || SSL_in_before(s))
         SSL_clear(s);
 
 #ifndef OPENSSL_NO_HEARTBEATS
     /*
      * If we're awaiting a HeartbeatResponse, pretend we already got and
      * don't await it anymore, because Heartbeats don't make sense during
      * handshakes anyway.
      */
     if (s->tlsext_hb_pending) {
         s->tlsext_hb_pending = 0;
         s->tlsext_hb_seq++;
     }
 #endif
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_RENEGOTIATE:
             s->renegotiate = 1;
             s->state = SSL_ST_CONNECT;
             s->ctx->stats.sess_connect_renegotiate++;
             /* break */
         case SSL_ST_BEFORE:
         case SSL_ST_CONNECT:
         case SSL_ST_BEFORE | SSL_ST_CONNECT:
         case SSL_ST_OK | SSL_ST_CONNECT:
 
             s->server = 0;
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_START, 1);
 
             if ((s->version & 0xff00) != 0x0300) {
                 SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR);
                 s->state = SSL_ST_ERR;
                 ret = -1;
                 goto end;
             }
 
             /* s->version=SSL3_VERSION; */
             s->type = SSL_ST_CONNECT;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
                 buf = NULL;
             }
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
                 goto end;
             }
 
             /* setup buffing BIO */
             if (!ssl_init_wbio_buffer(s, 0)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             /* don't push the buffering BIO quite yet */
 
             ssl3_init_finished_mac(s);
 
             s->state = SSL3_ST_CW_CLNT_HELLO_A;
             s->ctx->stats.sess_connect++;
             s->init_num = 0;
             s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
             /*
              * Should have been reset by ssl3_get_finished, too.
              */
             s->s3->change_cipher_spec = 0;
             break;
 
         case SSL3_ST_CW_CLNT_HELLO_A:
         case SSL3_ST_CW_CLNT_HELLO_B:
 
             s->shutdown = 0;
             ret = ssl3_client_hello(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_SRVR_HELLO_A;
             s->init_num = 0;
 
             /* turn on buffering for the next lot of output */
             if (s->bbio != s->wbio)
                 s->wbio = BIO_push(s->bbio, s->wbio);
 
             break;
 
         case SSL3_ST_CR_SRVR_HELLO_A:
         case SSL3_ST_CR_SRVR_HELLO_B:
             ret = ssl3_get_server_hello(s);
             if (ret <= 0)
                 goto end;
 
             if (s->hit) {
                 s->state = SSL3_ST_CR_FINISHED_A;
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_ticket_expected) {
                     /* receive renewed session ticket */
                     s->state = SSL3_ST_CR_SESSION_TICKET_A;
                 }
 #endif
             } else
                 s->state = SSL3_ST_CR_CERT_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_CERT_A:
         case SSL3_ST_CR_CERT_B:
 #ifndef OPENSSL_NO_TLSEXT
             /* Noop (ret = 0) for everything but EAP-FAST. */
             ret = ssl3_check_finished(s);
             if (ret < 0)
                 goto end;
             if (ret == 1) {
                 s->hit = 1;
                 s->state = SSL3_ST_CR_FINISHED_A;
                 s->init_num = 0;
                 break;
             }
 #endif
             /* Check if it is anon DH/ECDH, SRP auth */
             /* or PSK */
             if (!
                 (s->s3->tmp.
                  new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
                     && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 ret = ssl3_get_server_certificate(s);
                 if (ret <= 0)
                     goto end;
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_status_expected)
                     s->state = SSL3_ST_CR_CERT_STATUS_A;
                 else
                     s->state = SSL3_ST_CR_KEY_EXCH_A;
             } else {
                 skip = 1;
                 s->state = SSL3_ST_CR_KEY_EXCH_A;
             }
 #else
             } else
                 skip = 1;
 
             s->state = SSL3_ST_CR_KEY_EXCH_A;
 #endif
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_KEY_EXCH_A:
         case SSL3_ST_CR_KEY_EXCH_B:
             ret = ssl3_get_key_exchange(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_CERT_REQ_A;
             s->init_num = 0;
 
             /*
              * at this point we check that we have the required stuff from
              * the server
              */
             if (!ssl3_check_cert_and_algorithm(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
             break;
 
         case SSL3_ST_CR_CERT_REQ_A:
         case SSL3_ST_CR_CERT_REQ_B:
             ret = ssl3_get_certificate_request(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_SRVR_DONE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_SRVR_DONE_A:
         case SSL3_ST_CR_SRVR_DONE_B:
             ret = ssl3_get_server_done(s);
             if (ret <= 0)
                 goto end;
 #ifndef OPENSSL_NO_SRP
             if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) {
                 if ((ret = SRP_Calc_A_param(s)) <= 0) {
                     SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC);
                     ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
             }
 #endif
             if (s->s3->tmp.cert_req)
                 s->state = SSL3_ST_CW_CERT_A;
             else
                 s->state = SSL3_ST_CW_KEY_EXCH_A;
             s->init_num = 0;
 
             break;
 
         case SSL3_ST_CW_CERT_A:
         case SSL3_ST_CW_CERT_B:
         case SSL3_ST_CW_CERT_C:
         case SSL3_ST_CW_CERT_D:
             ret = ssl3_send_client_certificate(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_KEY_EXCH_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_KEY_EXCH_A:
         case SSL3_ST_CW_KEY_EXCH_B:
             ret = ssl3_send_client_key_exchange(s);
             if (ret <= 0)
                 goto end;
             /*
              * EAY EAY EAY need to check for DH fix cert sent back
              */
             /*
              * For TLS, cert_req is set to 2, so a cert chain of nothing is
              * sent, but no verify packet is sent
              */
             /*
              * XXX: For now, we do not support client authentication in ECDH
              * cipher suites with ECDH (rather than ECDSA) certificates. We
              * need to skip the certificate verify message when client's
              * ECDH public key is sent inside the client certificate.
              */
             if (s->s3->tmp.cert_req == 1) {
                 s->state = SSL3_ST_CW_CERT_VRFY_A;
             } else {
                 s->state = SSL3_ST_CW_CHANGE_A;
             }
             if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) {
                 s->state = SSL3_ST_CW_CHANGE_A;
             }
 
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_CERT_VRFY_A:
         case SSL3_ST_CW_CERT_VRFY_B:
             ret = ssl3_send_client_verify(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_CHANGE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_CHANGE_A:
         case SSL3_ST_CW_CHANGE_B:
             ret = ssl3_send_change_cipher_spec(s,
                                                SSL3_ST_CW_CHANGE_A,
                                                SSL3_ST_CW_CHANGE_B);
             if (ret <= 0)
                 goto end;
 
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
             s->state = SSL3_ST_CW_FINISHED_A;
 #else
             if (s->s3->next_proto_neg_seen)
                 s->state = SSL3_ST_CW_NEXT_PROTO_A;
             else
                 s->state = SSL3_ST_CW_FINISHED_A;
 #endif
             s->init_num = 0;
 
             s->session->cipher = s->s3->tmp.new_cipher;
 #ifdef OPENSSL_NO_COMP
             s->session->compress_meth = 0;
 #else
             if (s->s3->tmp.new_compression == NULL)
                 s->session->compress_meth = 0;
             else
                 s->session->compress_meth = s->s3->tmp.new_compression->id;
 #endif
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             if (!s->method->ssl3_enc->change_cipher_state(s,
                                                           SSL3_CHANGE_CIPHER_CLIENT_WRITE))
             {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             break;
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
         case SSL3_ST_CW_NEXT_PROTO_A:
         case SSL3_ST_CW_NEXT_PROTO_B:
             ret = ssl3_send_next_proto(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_FINISHED_A;
             break;
 #endif
 
         case SSL3_ST_CW_FINISHED_A:
         case SSL3_ST_CW_FINISHED_B:
             ret = ssl3_send_finished(s,
                                      SSL3_ST_CW_FINISHED_A,
                                      SSL3_ST_CW_FINISHED_B,
                                      s->method->
                                      ssl3_enc->client_finished_label,
                                      s->method->
                                      ssl3_enc->client_finished_label_len);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CW_FLUSH;
 
             /* clear flags */
             s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
             if (s->hit) {
                 s->s3->tmp.next_state = SSL_ST_OK;
                 if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) {
                     s->state = SSL_ST_OK;
                     s->s3->flags |= SSL3_FLAGS_POP_BUFFER;
                     s->s3->delay_buf_pop_ret = 0;
                 }
             } else {
 #ifndef OPENSSL_NO_TLSEXT
                 /*
                  * Allow NewSessionTicket if ticket expected
                  */
                 if (s->tlsext_ticket_expected)
                     s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A;
                 else
 #endif
 
                     s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A;
             }
             s->init_num = 0;
             break;
 
 #ifndef OPENSSL_NO_TLSEXT
         case SSL3_ST_CR_SESSION_TICKET_A:
         case SSL3_ST_CR_SESSION_TICKET_B:
             ret = ssl3_get_new_session_ticket(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_FINISHED_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CR_CERT_STATUS_A:
         case SSL3_ST_CR_CERT_STATUS_B:
             ret = ssl3_get_cert_status(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_CR_KEY_EXCH_A;
             s->init_num = 0;
             break;
 #endif
 
         case SSL3_ST_CR_FINISHED_A:
         case SSL3_ST_CR_FINISHED_B:
             if (!s->s3->change_cipher_spec)
                 s->s3->flags |= SSL3_FLAGS_CCS_OK;
             ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A,
                                     SSL3_ST_CR_FINISHED_B);
             if (ret <= 0)
                 goto end;
 
             if (s->hit)
                 s->state = SSL3_ST_CW_CHANGE_A;
             else
                 s->state = SSL_ST_OK;
             s->init_num = 0;
             break;
 
         case SSL3_ST_CW_FLUSH:
             s->rwstate = SSL_WRITING;
             if (BIO_flush(s->wbio) <= 0) {
                 ret = -1;
                 goto end;
             }
             s->rwstate = SSL_NOTHING;
             s->state = s->s3->tmp.next_state;
             break;
 
         case SSL_ST_OK:
             /* clean a few things up */
             ssl3_cleanup_key_block(s);
 
             if (s->init_buf != NULL) {
                 BUF_MEM_free(s->init_buf);
                 s->init_buf = NULL;
             }
 
             /*
              * If we are not 'joining' the last two packets, remove the
              * buffering now
              */
             if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER))
                 ssl_free_wbio_buffer(s);
             /* else do it later in ssl3_write */
 
             s->init_num = 0;
             s->renegotiate = 0;
             s->new_session = 0;
 
             ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
             if (s->hit)
                 s->ctx->stats.sess_hit++;
 
             ret = 1;
             /* s->server=0; */
             s->handshake_func = ssl3_connect;
             s->ctx->stats.sess_connect_good++;
 
             if (cb != NULL)
                 cb(s, SSL_CB_HANDSHAKE_DONE, 1);
 
             goto end;
             /* break; */
 
         case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE);
             ret = -1;
             goto end;
             /* break; */
         }
 
         /* did we do anything */
         if (!s->s3->tmp.reuse_message && !skip) {
             if (s->debug) {
                 if ((ret = BIO_flush(s->wbio)) <= 0)
                     goto end;
             }
 
             if ((cb != NULL) && (s->state != state)) {
                 new_state = s->state;
                 s->state = state;
                 cb(s, SSL_CB_CONNECT_LOOP, 1);
                 s->state = new_state;
             }
         }
         skip = 0;
     }
  end:
     s->in_handshake--;
     if (buf != NULL)
         BUF_MEM_free(buf);
     if (cb != NULL)
         cb(s, SSL_CB_CONNECT_EXIT, ret);
     return (ret);
 }
 
 int ssl3_client_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int i;
     unsigned long l;
 #ifndef OPENSSL_NO_COMP
     int j;
     SSL_COMP *comp;
 #endif
 
     buf = (unsigned char *)s->init_buf->data;
     if (s->state == SSL3_ST_CW_CLNT_HELLO_A) {
         SSL_SESSION *sess = s->session;
         if ((sess == NULL) || (sess->ssl_version != s->version) ||
 #ifdef OPENSSL_NO_TLSEXT
             !sess->session_id_length ||
 #else
             /*
              * In the case of EAP-FAST, we can have a pre-shared
              * "ticket" without a session ID.
              */
             (!sess->session_id_length && !sess->tlsext_tick) ||
 #endif
             (sess->not_resumable)) {
             if (!ssl_get_new_session(s, 0))
                 goto err;
         }
         /* else use the pre-loaded session */
 
         p = s->s3->client_random;
 
         if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
             goto err;
 
         /* Do the message type and length last */
         d = p = &(buf[4]);
 
         /*-
          * version indicates the negotiated version: for example from
          * an SSLv2/v3 compatible client hello). The client_version
          * field is the maximum version we permit and it is also
          * used in RSA encrypted premaster secrets. Some servers can
          * choke if we initially report a higher version then
          * renegotiate to a lower one in the premaster secret. This
          * didn't happen with TLS 1.0 as most servers supported it
          * but it can with TLS 1.1 or later if the server only supports
          * 1.0.
          *
          * Possible scenario with previous logic:
          *      1. Client hello indicates TLS 1.2
          *      2. Server hello says TLS 1.0
          *      3. RSA encrypted premaster secret uses 1.2.
          *      4. Handhaked proceeds using TLS 1.0.
          *      5. Server sends hello request to renegotiate.
          *      6. Client hello indicates TLS v1.0 as we now
          *         know that is maximum server supports.
          *      7. Server chokes on RSA encrypted premaster secret
          *         containing version 1.0.
          *
          * For interoperability it should be OK to always use the
          * maximum version we support in client hello and then rely
          * on the checking of version to ensure the servers isn't
          * being inconsistent: for example initially negotiating with
          * TLS 1.0 and renegotiating with TLS 1.2. We do this by using
          * client_version in client hello and not resetting it to
          * the negotiated version.
          */
 #if 0
         *(p++) = s->version >> 8;
         *(p++) = s->version & 0xff;
         s->client_version = s->version;
 #else
         *(p++) = s->client_version >> 8;
         *(p++) = s->client_version & 0xff;
 #endif
 
         /* Random stuff */
         memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
         p += SSL3_RANDOM_SIZE;
 
         /* Session ID */
         if (s->new_session)
             i = 0;
         else
             i = s->session->session_id_length;
         *(p++) = i;
         if (i != 0) {
             if (i > (int)sizeof(s->session->session_id)) {
                 SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             memcpy(p, s->session->session_id, i);
             p += i;
         }
 
         /* Ciphers supported */
         i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0);
         if (i == 0) {
             SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE);
             goto err;
         }
 #ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH
         /*
          * Some servers hang if client hello > 256 bytes as hack workaround
          * chop number of supported ciphers to keep it well below this if we
          * use TLS v1.2
          */
         if (TLS1_get_version(s) >= TLS1_2_VERSION
             && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH)
             i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1;
 #endif
         s2n(i, p);
         p += i;
 
         /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
         *(p++) = 1;
 #else
 
         if ((s->options & SSL_OP_NO_COMPRESSION)
             || !s->ctx->comp_methods)
             j = 0;
         else
             j = sk_SSL_COMP_num(s->ctx->comp_methods);
         *(p++) = 1 + j;
         for (i = 0; i < j; i++) {
             comp = sk_SSL_COMP_value(s->ctx->comp_methods, i);
             *(p++) = comp->id;
         }
 #endif
         *(p++) = 0;             /* Add the NULL method */
 
 #ifndef OPENSSL_NO_TLSEXT
         /* TLS extensions */
         if (ssl_prepare_clienthello_tlsext(s) <= 0) {
             SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
             goto err;
         }
         if ((p =
              ssl_add_clienthello_tlsext(s, p,
                                         buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
             NULL) {
             SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 #endif
 
         l = (p - d);
         d = buf;
         *(d++) = SSL3_MT_CLIENT_HELLO;
         l2n3(l, d);
 
         s->state = SSL3_ST_CW_CLNT_HELLO_B;
         /* number of bytes to write */
         s->init_num = p - buf;
         s->init_off = 0;
     }
 
     /* SSL3_ST_CW_CLNT_HELLO_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_server_hello(SSL *s)
 {
     STACK_OF(SSL_CIPHER) *sk;
     const SSL_CIPHER *c;
     unsigned char *p, *d;
     int i, al, ok;
     unsigned int j;
     long n;
 #ifndef OPENSSL_NO_COMP
     SSL_COMP *comp;
 #endif
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_SRVR_HELLO_A,
                                    SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, &ok);
 
     if (!ok)
         return ((int)n);
 
     if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) {
         if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) {
             if (s->d1->send_cookie == 0) {
                 s->s3->tmp.reuse_message = 1;
                 return 1;
             } else {            /* already sent a cookie */
 
                 al = SSL_AD_UNEXPECTED_MESSAGE;
                 SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE);
                 goto f_err;
             }
         }
     }
 
     if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE);
         goto f_err;
     }
 
     d = p = (unsigned char *)s->init_msg;
 
     if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) {
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION);
         s->version = (s->version & 0xff00) | p[1];
         al = SSL_AD_PROTOCOL_VERSION;
         goto f_err;
     }
     p += 2;
 
     /* load the server hello data */
     /* load the server random */
     memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE);
     p += SSL3_RANDOM_SIZE;
 
     s->hit = 0;
 
     /* get the session-id */
     j = *(p++);
 
     if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG);
         goto f_err;
     }
 #ifndef OPENSSL_NO_TLSEXT
     /*
      * Check if we can resume the session based on external pre-shared secret.
      * EAP-FAST (RFC 4851) supports two types of session resumption.
      * Resumption based on server-side state works with session IDs.
      * Resumption based on pre-shared Protected Access Credentials (PACs)
      * works by overriding the SessionTicket extension at the application
      * layer, and does not send a session ID. (We do not know whether EAP-FAST
      * servers would honour the session ID.) Therefore, the session ID alone
      * is not a reliable indicator of session resumption, so we first check if
      * we can resume, and later peek at the next handshake message to see if the
      * server wants to resume.
      */
     if (s->version >= TLS1_VERSION && s->tls_session_secret_cb &&
         s->session->tlsext_tick) {
         SSL_CIPHER *pref_cipher = NULL;
         s->session->master_key_length = sizeof(s->session->master_key);
         if (s->tls_session_secret_cb(s, s->session->master_key,
                                      &s->session->master_key_length,
                                      NULL, &pref_cipher,
                                      s->tls_session_secret_cb_arg)) {
             s->session->cipher = pref_cipher ?
                 pref_cipher : ssl_get_cipher_by_char(s, p + j);
         } else {
             SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
     }
 #endif                          /* OPENSSL_NO_TLSEXT */
 
     if (j != 0 && j == s->session->session_id_length
         && memcmp(p, s->session->session_id, j) == 0) {
         if (s->sid_ctx_length != s->session->sid_ctx_length
             || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
             /* actually a client application bug */
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
                    SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
             goto f_err;
         }
         s->hit = 1;
     } else {
         /*
          * If we were trying for session-id reuse but the server
          * didn't echo the ID, make a new SSL_SESSION.
          * In the case of EAP-FAST and PAC, we do not send a session ID,
          * so the PAC-based session secret is always preserved. It'll be
          * overwritten if the server refuses resumption.
          */
         if (s->session->session_id_length > 0) {
             if (!ssl_get_new_session(s, 0)) {
                 al = SSL_AD_INTERNAL_ERROR;
                 goto f_err;
             }
         }
         s->session->session_id_length = j;
         memcpy(s->session->session_id, p, j); /* j could be 0 */
     }
     p += j;
     c = ssl_get_cipher_by_char(s, p);
     if (c == NULL) {
         /* unknown cipher */
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED);
         goto f_err;
     }
     /* TLS v1.2 only ciphersuites require v1.2 or later */
     if ((c->algorithm_ssl & SSL_TLSV1_2) &&
         (TLS1_get_version(s) < TLS1_2_VERSION)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
         goto f_err;
     }
 #ifndef OPENSSL_NO_SRP
     if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP)) &&
         !(s->srp_ctx.srp_Mask & SSL_kSRP)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
         goto f_err;
     }
 #endif                          /* OPENSSL_NO_SRP */
     p += ssl_put_cipher_by_char(s, NULL, NULL);
 
     sk = ssl_get_ciphers_by_id(s);
     i = sk_SSL_CIPHER_find(sk, c);
     if (i < 0) {
         /* we did not say we would use this cipher */
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED);
         goto f_err;
     }
 
     /*
      * Depending on the session caching (internal/external), the cipher
      * and/or cipher_id values may not be set. Make sure that cipher_id is
      * set and use it for comparison.
      */
     if (s->session->cipher)
         s->session->cipher_id = s->session->cipher->id;
     if (s->hit && (s->session->cipher_id != c->id)) {
 /* Workaround is now obsolete */
 #if 0
         if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG))
 #endif
         {
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
                    SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
             goto f_err;
         }
     }
     s->s3->tmp.new_cipher = c;
     /*
      * Don't digest cached records if TLS v1.2: we may need them for client
      * authentication.
      */
     if (TLS1_get_version(s) < TLS1_2_VERSION
         && !ssl3_digest_cached_records(s)) {
         al = SSL_AD_INTERNAL_ERROR;
         goto f_err;
     }
     /* lets get the compression algorithm */
     /* COMPRESSION */
 #ifdef OPENSSL_NO_COMP
     if (*(p++) != 0) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
                SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
         goto f_err;
     }
     /*
      * If compression is disabled we'd better not try to resume a session
      * using compression.
      */
     if (s->session->compress_meth != 0) {
         al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION);
         goto f_err;
     }
 #else
     j = *(p++);
     if (s->hit && j != s->session->compress_meth) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
                SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED);
         goto f_err;
     }
     if (j == 0)
         comp = NULL;
     else if (s->options & SSL_OP_NO_COMPRESSION) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED);
         goto f_err;
     } else
         comp = ssl3_comp_find(s->ctx->comp_methods, j);
 
     if ((j != 0) && (comp == NULL)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,
                SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
         goto f_err;
     } else {
         s->s3->tmp.new_compression = comp;
     }
 #endif
 
 #ifndef OPENSSL_NO_TLSEXT
     /* TLS extensions */
     if (s->version >= SSL3_VERSION) {
         if (!ssl_parse_serverhello_tlsext(s, &p, d, n, &al)) {
             /* 'al' set by ssl_parse_serverhello_tlsext */
             SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT);
             goto f_err;
         }
         if (ssl_check_serverhello_tlsext(s) <= 0) {
             SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
             goto err;
         }
     }
 #endif
 
     if (p != (d + n)) {
         /* wrong packet length */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
         goto f_err;
     }
 
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_server_certificate(SSL *s)
 {
     int al, i, ok, ret = -1;
     unsigned long n, nc, llen, l;
     X509 *x = NULL;
     const unsigned char *q, *p;
     unsigned char *d;
     STACK_OF(X509) *sk = NULL;
     SESS_CERT *sc;
     EVP_PKEY *pkey = NULL;
     int need_cert = 1;          /* VRS: 0=> will allow null cert if auth ==
                                  * KRB5 */
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_CERT_A,
                                    SSL3_ST_CR_CERT_B,
                                    -1, s->max_cert_list, &ok);
 
     if (!ok)
         return ((int)n);
 
     if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) ||
         ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) &&
          (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) {
         s->s3->tmp.reuse_message = 1;
         return (1);
     }
 
     if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_BAD_MESSAGE_TYPE);
         goto f_err;
     }
     p = d = (unsigned char *)s->init_msg;
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     n2l3(p, llen);
     if (llen + 3 != n) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
     for (nc = 0; nc < llen;) {
+        if (nc + 3 > llen) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
         n2l3(p, l);
         if ((l + nc + 3) > llen) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
                    SSL_R_CERT_LENGTH_MISMATCH);
             goto f_err;
         }
 
         q = p;
         x = d2i_X509(NULL, &q, l);
         if (x == NULL) {
             al = SSL_AD_BAD_CERTIFICATE;
             SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_ASN1_LIB);
             goto f_err;
         }
         if (q != (p + l)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
                    SSL_R_CERT_LENGTH_MISMATCH);
             goto f_err;
         }
         if (!sk_X509_push(sk, x)) {
             SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         x = NULL;
         nc += l + 3;
         p = q;
     }
 
     i = ssl_verify_cert_chain(s, sk);
     if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)
 #ifndef OPENSSL_NO_KRB5
         && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
              (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
 #endif                          /* OPENSSL_NO_KRB5 */
         ) {
         al = ssl_verify_alarm_type(s->verify_result);
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
                SSL_R_CERTIFICATE_VERIFY_FAILED);
         goto f_err;
     }
     ERR_clear_error();          /* but we keep s->verify_result */
 
     sc = ssl_sess_cert_new();
     if (sc == NULL)
         goto err;
 
     if (s->session->sess_cert)
         ssl_sess_cert_free(s->session->sess_cert);
     s->session->sess_cert = sc;
 
     sc->cert_chain = sk;
     /*
      * Inconsistency alert: cert_chain does include the peer's certificate,
      * which we don't include in s3_srvr.c
      */
     x = sk_X509_value(sk, 0);
     sk = NULL;
     /*
      * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end
      */
 
     pkey = X509_get_pubkey(x);
 
     /* VRS: allow null cert if auth == KRB5 */
     need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) &&
                  (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5))
         ? 0 : 1;
 
 #ifdef KSSL_DEBUG
     fprintf(stderr, "pkey,x = %p, %p\n", pkey, x);
     fprintf(stderr, "ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x, pkey));
     fprintf(stderr, "cipher, alg, nc = %s, %lx, %lx, %d\n",
             s->s3->tmp.new_cipher->name,
             s->s3->tmp.new_cipher->algorithm_mkey,
             s->s3->tmp.new_cipher->algorithm_auth, need_cert);
 #endif                          /* KSSL_DEBUG */
 
     if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) {
         x = NULL;
         al = SSL3_AL_FATAL;
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
                SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
         goto f_err;
     }
 
     i = ssl_cert_type(x, pkey);
     if (need_cert && i < 0) {
         x = NULL;
         al = SSL3_AL_FATAL;
         SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
                SSL_R_UNKNOWN_CERTIFICATE_TYPE);
         goto f_err;
     }
 
     if (need_cert) {
         sc->peer_cert_type = i;
         CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
         /*
          * Why would the following ever happen? We just created sc a couple
          * of lines ago.
          */
         if (sc->peer_pkeys[i].x509 != NULL)
             X509_free(sc->peer_pkeys[i].x509);
         sc->peer_pkeys[i].x509 = x;
         sc->peer_key = &(sc->peer_pkeys[i]);
 
         if (s->session->peer != NULL)
             X509_free(s->session->peer);
         CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
         s->session->peer = x;
     } else {
         sc->peer_cert_type = i;
         sc->peer_key = NULL;
 
         if (s->session->peer != NULL)
             X509_free(s->session->peer);
         s->session->peer = NULL;
     }
     s->session->verify_result = s->verify_result;
 
     x = NULL;
     ret = 1;
 
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
         s->state = SSL_ST_ERR;
     }
 
     EVP_PKEY_free(pkey);
     X509_free(x);
     sk_X509_pop_free(sk, X509_free);
     return (ret);
 }
 
 int ssl3_get_key_exchange(SSL *s)
 {
 #ifndef OPENSSL_NO_RSA
     unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2];
 #endif
     EVP_MD_CTX md_ctx;
     unsigned char *param, *p;
     int al, j, ok;
     long i, param_len, n, alg_k, alg_a;
     EVP_PKEY *pkey = NULL;
     const EVP_MD *md = NULL;
 #ifndef OPENSSL_NO_RSA
     RSA *rsa = NULL;
 #endif
 #ifndef OPENSSL_NO_DH
     DH *dh = NULL;
 #endif
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *ecdh = NULL;
     BN_CTX *bn_ctx = NULL;
     EC_POINT *srvr_ecpoint = NULL;
     int curve_nid = 0;
     int encoded_pt_len = 0;
 #endif
 
     EVP_MD_CTX_init(&md_ctx);
 
     /*
      * use same message size as in ssl3_get_certificate_request() as
      * ServerKeyExchange message may be skipped
      */
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_KEY_EXCH_A,
                                    SSL3_ST_CR_KEY_EXCH_B,
                                    -1, s->max_cert_list, &ok);
     if (!ok)
         return ((int)n);
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
     if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
         /*
          * Can't skip server key exchange if this is an ephemeral
          * ciphersuite.
          */
         if (alg_k & (SSL_kEDH | SSL_kEECDH)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
             al = SSL_AD_UNEXPECTED_MESSAGE;
             goto f_err;
         }
 #ifndef OPENSSL_NO_PSK
         /*
          * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no
          * identity hint is sent. Set session->sess_cert anyway to avoid
          * problems later.
          */
         if (alg_k & SSL_kPSK) {
             s->session->sess_cert = ssl_sess_cert_new();
             if (s->ctx->psk_identity_hint)
                 OPENSSL_free(s->ctx->psk_identity_hint);
             s->ctx->psk_identity_hint = NULL;
         }
 #endif
         s->s3->tmp.reuse_message = 1;
         return (1);
     }
 
     param = p = (unsigned char *)s->init_msg;
     if (s->session->sess_cert != NULL) {
 #ifndef OPENSSL_NO_RSA
         if (s->session->sess_cert->peer_rsa_tmp != NULL) {
             RSA_free(s->session->sess_cert->peer_rsa_tmp);
             s->session->sess_cert->peer_rsa_tmp = NULL;
         }
 #endif
 #ifndef OPENSSL_NO_DH
         if (s->session->sess_cert->peer_dh_tmp) {
             DH_free(s->session->sess_cert->peer_dh_tmp);
             s->session->sess_cert->peer_dh_tmp = NULL;
         }
 #endif
 #ifndef OPENSSL_NO_ECDH
         if (s->session->sess_cert->peer_ecdh_tmp) {
             EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
             s->session->sess_cert->peer_ecdh_tmp = NULL;
         }
 #endif
     } else {
         s->session->sess_cert = ssl_sess_cert_new();
     }
 
     /* Total length of the parameters including the length prefix */
     param_len = 0;
 
     alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
     al = SSL_AD_DECODE_ERROR;
 
 #ifndef OPENSSL_NO_PSK
     if (alg_k & SSL_kPSK) {
         param_len = 2;
         if (param_len > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         n2s(p, i);
 
         /*
          * Store PSK identity hint for later use, hint is used in
          * ssl3_send_client_key_exchange.  Assume that the maximum length of
          * a PSK identity hint can be as long as the maximum length of a PSK
          * identity.
          */
         if (i > PSK_MAX_IDENTITY_LEN) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG);
             goto f_err;
         }
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                    SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         s->session->psk_identity_hint = BUF_strndup((char *)p, i);
         if (s->session->psk_identity_hint == NULL) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
 
         p += i;
         n -= param_len;
     } else
 #endif                          /* !OPENSSL_NO_PSK */
 #ifndef OPENSSL_NO_SRP
     if (alg_k & SSL_kSRP) {
         param_len = 2;
         if (param_len > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(s->srp_ctx.N = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 2;
 
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(s->srp_ctx.g = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (1 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 1;
 
         i = (unsigned int)(p[0]);
         p++;
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(s->srp_ctx.s = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 2;
 
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(s->srp_ctx.B = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
         n -= param_len;
 
         if (!srp_verify_server_param(s, &al)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS);
             goto f_err;
         }
 
 /* We must check if there is a certificate */
 # ifndef OPENSSL_NO_RSA
         if (alg_a & SSL_aRSA)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 # else
         if (0) ;
 # endif
 # ifndef OPENSSL_NO_DSA
         else if (alg_a & SSL_aDSS)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].
                                 x509);
 # endif
     } else
 #endif                          /* !OPENSSL_NO_SRP */
 #ifndef OPENSSL_NO_RSA
     if (alg_k & SSL_kRSA) {
         /* Temporary RSA keys only allowed in export ciphersuites */
         if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
         if ((rsa = RSA_new()) == NULL) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         param_len = 2;
         if (param_len > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 2;
 
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
         n -= param_len;
 
         /* this should be because we are using an export cipher */
         if (alg_a & SSL_aRSA)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
         else {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 
         if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
             al = SSL_AD_UNEXPECTED_MESSAGE;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
             goto f_err;
         }
 
         s->session->sess_cert->peer_rsa_tmp = rsa;
         rsa = NULL;
     }
 #else                           /* OPENSSL_NO_RSA */
     if (0) ;
 #endif
 #ifndef OPENSSL_NO_DH
     else if (alg_k & SSL_kEDH) {
         if ((dh = DH_new()) == NULL) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB);
             goto err;
         }
 
         param_len = 2;
         if (param_len > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(dh->p = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (BN_is_zero(dh->p)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
             goto f_err;
         }
 
 
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 2;
 
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(dh->g = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
 
         if (BN_is_zero(dh->g)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
             goto f_err;
         }
 
         if (2 > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         param_len += 2;
 
         n2s(p, i);
 
         if (i > n - param_len) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH);
             goto f_err;
         }
         param_len += i;
 
         if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         p += i;
         n -= param_len;
 
         if (BN_is_zero(dh->pub_key)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE);
             goto f_err;
         }
 
 # ifndef OPENSSL_NO_RSA
         if (alg_a & SSL_aRSA)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 # else
         if (0) ;
 # endif
 # ifndef OPENSSL_NO_DSA
         else if (alg_a & SSL_aDSS)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN].
                                 x509);
 # endif
         /* else anonymous DH, so no certificate or pkey. */
 
         s->session->sess_cert->peer_dh_tmp = dh;
         dh = NULL;
     } else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER);
         goto f_err;
     }
 #endif                          /* !OPENSSL_NO_DH */
 
 #ifndef OPENSSL_NO_ECDH
     else if (alg_k & SSL_kEECDH) {
         EC_GROUP *ngroup;
         const EC_GROUP *group;
 
         if ((ecdh = EC_KEY_new()) == NULL) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         /*
          * Extract elliptic curve parameters and the server's ephemeral ECDH
          * public key. Keep accumulating lengths of various components in
          * param_len and make sure it never exceeds n.
          */
 
         /*
          * XXX: For now we only support named (not generic) curves and the
          * ECParameters in this case is just three bytes. We also need one
          * byte for the length of the encoded point
          */
         param_len = 4;
         if (param_len > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
 
         if ((*p != NAMED_CURVE_TYPE) ||
             ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                    SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
             goto f_err;
         }
 
         ngroup = EC_GROUP_new_by_curve_name(curve_nid);
         if (ngroup == NULL) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB);
             goto err;
         }
         if (EC_KEY_set_group(ecdh, ngroup) == 0) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB);
             goto err;
         }
         EC_GROUP_free(ngroup);
 
         group = EC_KEY_get0_group(ecdh);
 
         if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
             (EC_GROUP_get_degree(group) > 163)) {
             al = SSL_AD_EXPORT_RESTRICTION;
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                    SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
             goto f_err;
         }
 
         p += 3;
 
         /* Next, get the encoded ECPoint */
         if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
             ((bn_ctx = BN_CTX_new()) == NULL)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         encoded_pt_len = *p;    /* length of encoded point */
         p += 1;
 
         if ((encoded_pt_len > n - param_len) ||
             (EC_POINT_oct2point(group, srvr_ecpoint,
                                 p, encoded_pt_len, bn_ctx) == 0)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
             goto f_err;
         }
         param_len += encoded_pt_len;
 
         n -= param_len;
         p += encoded_pt_len;
 
         /*
          * The ECC/TLS specification does not mention the use of DSA to sign
          * ECParameters in the server key exchange message. We do support RSA
          * and ECDSA.
          */
         if (0) ;
 # ifndef OPENSSL_NO_RSA
         else if (alg_a & SSL_aRSA)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
 # endif
 # ifndef OPENSSL_NO_ECDSA
         else if (alg_a & SSL_aECDSA)
             pkey =
                 X509_get_pubkey(s->session->
                                 sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
 # endif
         /* else anonymous ECDH, so no certificate or pkey. */
         EC_KEY_set_public_key(ecdh, srvr_ecpoint);
         s->session->sess_cert->peer_ecdh_tmp = ecdh;
         ecdh = NULL;
         BN_CTX_free(bn_ctx);
         bn_ctx = NULL;
         EC_POINT_free(srvr_ecpoint);
         srvr_ecpoint = NULL;
     } else if (alg_k) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE);
         goto f_err;
     }
 #endif                          /* !OPENSSL_NO_ECDH */
 
     /* p points to the next byte, there are 'n' bytes left */
 
     /* if it was signed, check the signature */
     if (pkey != NULL) {
         if (TLS1_get_version(s) >= TLS1_2_VERSION) {
             int sigalg;
             if (2 > n) {
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
                 goto f_err;
             }
 
             sigalg = tls12_get_sigid(pkey);
             /* Should never happen */
             if (sigalg == -1) {
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             /* Check key type is consistent with signature */
             if (sigalg != (int)p[1]) {
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                        SSL_R_WRONG_SIGNATURE_TYPE);
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
             md = tls12_get_hash(p[0]);
             if (md == NULL) {
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNKNOWN_DIGEST);
                 goto f_err;
             }
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
             p += 2;
             n -= 2;
         } else
             md = EVP_sha1();
 
         if (2 > n) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         n2s(p, i);
         n -= 2;
         j = EVP_PKEY_size(pkey);
 
         /*
          * Check signature length. If n is 0 then signature is empty
          */
         if ((i != n) || (n > j) || (n <= 0)) {
             /* wrong packet length */
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH);
             goto f_err;
         }
 #ifndef OPENSSL_NO_RSA
         if (pkey->type == EVP_PKEY_RSA
             && TLS1_get_version(s) < TLS1_2_VERSION) {
             int num;
             unsigned int size;
 
             j = 0;
             q = md_buf;
             for (num = 2; num > 0; num--) {
                 EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                 if (EVP_DigestInit_ex(&md_ctx,
                                       (num == 2) ? s->ctx->md5 : s->ctx->sha1,
                                       NULL) <= 0
                         || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
                                             SSL3_RANDOM_SIZE) <= 0
                         || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
                                             SSL3_RANDOM_SIZE) <= 0
                         || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0
                         || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) {
                     SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
                            ERR_R_INTERNAL_ERROR);
                     al = SSL_AD_INTERNAL_ERROR;
                     goto f_err;
                 }
                 q += size;
                 j += size;
             }
             i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa);
             if (i < 0) {
                 al = SSL_AD_DECRYPT_ERROR;
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT);
                 goto f_err;
             }
             if (i == 0) {
                 /* bad signature */
                 al = SSL_AD_DECRYPT_ERROR;
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
                 goto f_err;
             }
         } else
 #endif
         {
             if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0
                     || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]),
                                         SSL3_RANDOM_SIZE) <= 0
                     || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]),
                                         SSL3_RANDOM_SIZE) <= 0
                     || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) {
                 al = SSL_AD_INTERNAL_ERROR;
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB);
                 goto f_err;
             }
             if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) {
                 /* bad signature */
                 al = SSL_AD_DECRYPT_ERROR;
                 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE);
                 goto f_err;
             }
         }
     } else {
         /* aNULL, aSRP or kPSK do not need public keys */
         if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto err;
         }
         /* still data left over */
         if (n != 0) {
             SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE);
             goto f_err;
         }
     }
     EVP_PKEY_free(pkey);
     EVP_MD_CTX_cleanup(&md_ctx);
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     EVP_PKEY_free(pkey);
 #ifndef OPENSSL_NO_RSA
     if (rsa != NULL)
         RSA_free(rsa);
 #endif
 #ifndef OPENSSL_NO_DH
     if (dh != NULL)
         DH_free(dh);
 #endif
 #ifndef OPENSSL_NO_ECDH
     BN_CTX_free(bn_ctx);
     EC_POINT_free(srvr_ecpoint);
     if (ecdh != NULL)
         EC_KEY_free(ecdh);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_certificate_request(SSL *s)
 {
     int ok, ret = 0;
     unsigned long n, nc, l;
     unsigned int llen, ctype_num, i;
     X509_NAME *xn = NULL;
     const unsigned char *p, *q;
     unsigned char *d;
     STACK_OF(X509_NAME) *ca_sk = NULL;
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_CERT_REQ_A,
                                    SSL3_ST_CR_CERT_REQ_B,
                                    -1, s->max_cert_list, &ok);
 
     if (!ok)
         return ((int)n);
 
     s->s3->tmp.cert_req = 0;
 
     if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) {
         s->s3->tmp.reuse_message = 1;
         /*
          * If we get here we don't need any cached handshake records as we
          * wont be doing client auth.
          */
         if (s->s3->handshake_buffer) {
             if (!ssl3_digest_cached_records(s))
                 goto err;
         }
         return (1);
     }
 
     if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
         SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_WRONG_MESSAGE_TYPE);
         goto err;
     }
 
     /* TLS does not like anon-DH with client cert */
     if (s->version > SSL3_VERSION) {
         if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
                    SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER);
             goto err;
         }
     }
 
     p = d = (unsigned char *)s->init_msg;
 
     if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
         SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     /* get the certificate types */
     ctype_num = *(p++);
     if (ctype_num > SSL3_CT_NUMBER)
         ctype_num = SSL3_CT_NUMBER;
     for (i = 0; i < ctype_num; i++)
         s->s3->tmp.ctype[i] = p[i];
     p += ctype_num;
     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
         n2s(p, llen);
         /*
          * Check we have enough room for signature algorithms and following
          * length value.
          */
         if ((unsigned long)(p - d + llen + 2) > n) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto err;
         }
         if ((llen & 1) || !tls1_process_sigalgs(s, p, llen)) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
                    SSL_R_SIGNATURE_ALGORITHMS_ERROR);
             goto err;
         }
         p += llen;
     }
 
     /* get the CA RDNs */
     n2s(p, llen);
 #if 0
     {
         FILE *out;
         out = fopen("/tmp/vsign.der", "w");
         fwrite(p, 1, llen, out);
         fclose(out);
     }
 #endif
 
     if ((unsigned long)(p - d + llen) != n) {
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
         goto err;
     }
 
     for (nc = 0; nc < llen;) {
+        if (nc + 2 > llen) {
+            ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+            SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG);
+            goto err;
+        }
         n2s(p, l);
         if ((l + nc + 2) > llen) {
             if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
                 goto cont;      /* netscape bugs */
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG);
             goto err;
         }
 
         q = p;
 
         if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) {
             /* If netscape tolerance is on, ignore errors */
             if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG)
                 goto cont;
             else {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
                 SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB);
                 goto err;
             }
         }
 
         if (q != (p + l)) {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST,
                    SSL_R_CA_DN_LENGTH_MISMATCH);
             goto err;
         }
         if (!sk_X509_NAME_push(ca_sk, xn)) {
             SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         xn = NULL;
 
         p += l;
         nc += l + 2;
     }
 
     if (0) {
  cont:
         ERR_clear_error();
     }
 
     /* we should setup a certificate to return.... */
     s->s3->tmp.cert_req = 1;
     s->s3->tmp.ctype_num = ctype_num;
     if (s->s3->tmp.ca_names != NULL)
         sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
     s->s3->tmp.ca_names = ca_sk;
     ca_sk = NULL;
 
     ret = 1;
     goto done;
  err:
     s->state = SSL_ST_ERR;
  done:
     X509_NAME_free(xn);
     if (ca_sk != NULL)
         sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
     return (ret);
 }
 
 static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
 {
     return (X509_NAME_cmp(*a, *b));
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 int ssl3_get_new_session_ticket(SSL *s)
 {
     int ok, al, ret = 0, ticklen;
     long n;
     const unsigned char *p;
     unsigned char *d;
     unsigned long ticket_lifetime_hint;
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_SESSION_TICKET_A,
                                    SSL3_ST_CR_SESSION_TICKET_B,
                                    SSL3_MT_NEWSESSION_TICKET, 16384, &ok);
 
     if (!ok)
         return ((int)n);
 
     if (n < 6) {
         /* need at least ticket_lifetime_hint + ticket length */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
 
     p = d = (unsigned char *)s->init_msg;
 
     n2l(p, ticket_lifetime_hint);
     n2s(p, ticklen);
     /* ticket_lifetime_hint + ticket_length + ticket */
     if (ticklen + 6 != n) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
 
     /* Server is allowed to change its mind and send an empty ticket. */
     if (ticklen == 0)
         return 1;
 
     if (s->session->session_id_length > 0) {
         int i = s->session_ctx->session_cache_mode;
         SSL_SESSION *new_sess;
         /*
          * We reused an existing session, so we need to replace it with a new
          * one
          */
         if (i & SSL_SESS_CACHE_CLIENT) {
             /*
              * Remove the old session from the cache
              */
             if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) {
                 if (s->session_ctx->remove_session_cb != NULL)
                     s->session_ctx->remove_session_cb(s->session_ctx,
                                                       s->session);
             } else {
                 /* We carry on if this fails */
                 SSL_CTX_remove_session(s->session_ctx, s->session);
             }
         }
 
         if ((new_sess = ssl_session_dup(s->session, 0)) == 0) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
 
         SSL_SESSION_free(s->session);
         s->session = new_sess;
     }
 
     if (s->session->tlsext_tick) {
         OPENSSL_free(s->session->tlsext_tick);
         s->session->tlsext_ticklen = 0;
     }
     s->session->tlsext_tick = OPENSSL_malloc(ticklen);
     if (!s->session->tlsext_tick) {
         SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE);
         goto err;
     }
     memcpy(s->session->tlsext_tick, p, ticklen);
     s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
     s->session->tlsext_ticklen = ticklen;
     /*
      * There are two ways to detect a resumed ticket session. One is to set
      * an appropriate session ID and then the server must return a match in
      * ServerHello. This allows the normal client session ID matching to work
      * and we know much earlier that the ticket has been accepted. The
      * other way is to set zero length session ID when the ticket is
      * presented and rely on the handshake to determine session resumption.
      * We choose the former approach because this fits in with assumptions
      * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is
      * SHA256 is disabled) hash of the ticket.
      */
     EVP_Digest(p, ticklen,
                s->session->session_id, &s->session->session_id_length,
 # ifndef OPENSSL_NO_SHA256
                EVP_sha256(), NULL);
 # else
                EVP_sha1(), NULL);
 # endif
     ret = 1;
     return (ret);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_cert_status(SSL *s)
 {
     int ok, al;
     unsigned long resplen, n;
     const unsigned char *p;
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_CERT_STATUS_A,
                                    SSL3_ST_CR_CERT_STATUS_B,
                                    -1, 16384, &ok);
 
     if (!ok)
         return ((int)n);
 
     if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) {
         /*
          * The CertificateStatus message is optional even if
          * tlsext_status_expected is set
          */
         s->s3->tmp.reuse_message = 1;
     } else {
         if (n < 4) {
             /* need at least status type + length */
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
         p = (unsigned char *)s->init_msg;
         if (*p++ != TLSEXT_STATUSTYPE_ocsp) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE);
             goto f_err;
         }
         n2l3(p, resplen);
         if (resplen + 4 != n) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH);
             goto f_err;
         }
         s->tlsext_ocsp_resp = BUF_memdup(p, resplen);
         if (s->tlsext_ocsp_resp == NULL) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
         s->tlsext_ocsp_resplen = resplen;
     }
     if (s->ctx->tlsext_status_cb) {
         int ret;
         ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
         if (ret == 0) {
             al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE);
             goto f_err;
         }
         if (ret < 0) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
     }
     return 1;
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
     s->state = SSL_ST_ERR;
     return (-1);
 }
 #endif
 
 int ssl3_get_server_done(SSL *s)
 {
     int ok, ret = 0;
     long n;
 
     /* Second to last param should be very small, like 0 :-) */
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_CR_SRVR_DONE_A,
                                    SSL3_ST_CR_SRVR_DONE_B,
                                    SSL3_MT_SERVER_DONE, 30, &ok);
 
     if (!ok)
         return ((int)n);
     if (n > 0) {
         /* should contain no data */
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
         SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH);
         s->state = SSL_ST_ERR;
         return -1;
     }
     ret = 1;
     return (ret);
 }
 
 int ssl3_send_client_key_exchange(SSL *s)
 {
     unsigned char *p, *d;
     int n;
     unsigned long alg_k;
 #ifndef OPENSSL_NO_RSA
     unsigned char *q;
     EVP_PKEY *pkey = NULL;
 #endif
 #ifndef OPENSSL_NO_KRB5
     KSSL_ERR kssl_err;
 #endif                          /* OPENSSL_NO_KRB5 */
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *clnt_ecdh = NULL;
     const EC_POINT *srvr_ecpoint = NULL;
     EVP_PKEY *srvr_pub_pkey = NULL;
     unsigned char *encodedPoint = NULL;
     int encoded_pt_len = 0;
     BN_CTX *bn_ctx = NULL;
 #endif
 
     if (s->state == SSL3_ST_CW_KEY_EXCH_A) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[4]);
 
         alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
         /* Fool emacs indentation */
         if (0) {
         }
 #ifndef OPENSSL_NO_RSA
         else if (alg_k & SSL_kRSA) {
             RSA *rsa;
             unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
 
             if (s->session->sess_cert == NULL) {
                 /*
                  * We should always have a server certificate with SSL_kRSA.
                  */
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if (s->session->sess_cert->peer_rsa_tmp != NULL)
                 rsa = s->session->sess_cert->peer_rsa_tmp;
             else {
                 pkey =
                     X509_get_pubkey(s->session->
                                     sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].
                                     x509);
                 if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA)
                     || (pkey->pkey.rsa == NULL)) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_INTERNAL_ERROR);
                     EVP_PKEY_free(pkey);
                     goto err;
                 }
                 rsa = pkey->pkey.rsa;
                 EVP_PKEY_free(pkey);
             }
 
             tmp_buf[0] = s->client_version >> 8;
             tmp_buf[1] = s->client_version & 0xff;
             if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0)
                 goto err;
 
             s->session->master_key_length = sizeof tmp_buf;
 
             q = p;
             /* Fix buf for TLS and beyond */
             if (s->version > SSL3_VERSION)
                 p += 2;
             n = RSA_public_encrypt(sizeof tmp_buf,
                                    tmp_buf, p, rsa, RSA_PKCS1_PADDING);
 # ifdef PKCS1_CHECK
             if (s->options & SSL_OP_PKCS1_CHECK_1)
                 p[1]++;
             if (s->options & SSL_OP_PKCS1_CHECK_2)
                 tmp_buf[0] = 0x70;
 # endif
             if (n <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_BAD_RSA_ENCRYPT);
                 goto err;
             }
 
             /* Fix buf for TLS and beyond */
             if (s->version > SSL3_VERSION) {
                 s2n(n, q);
                 n += 2;
             }
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             tmp_buf,
                                                             sizeof tmp_buf);
             OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
         }
 #endif
 #ifndef OPENSSL_NO_KRB5
         else if (alg_k & SSL_kKRB5) {
             krb5_error_code krb5rc;
             KSSL_CTX *kssl_ctx = s->kssl_ctx;
             /*  krb5_data   krb5_ap_req;  */
             krb5_data *enc_ticket;
             krb5_data authenticator, *authp = NULL;
             EVP_CIPHER_CTX ciph_ctx;
             const EVP_CIPHER *enc = NULL;
             unsigned char iv[EVP_MAX_IV_LENGTH];
             unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
             unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH];
             int padl, outl = sizeof(epms);
 
             EVP_CIPHER_CTX_init(&ciph_ctx);
 
 # ifdef KSSL_DEBUG
             fprintf(stderr, "ssl3_send_client_key_exchange(%lx & %lx)\n",
                     alg_k, SSL_kKRB5);
 # endif                         /* KSSL_DEBUG */
 
             authp = NULL;
 # ifdef KRB5SENDAUTH
             if (KRB5SENDAUTH)
                 authp = &authenticator;
 # endif                         /* KRB5SENDAUTH */
 
             krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err);
             enc = kssl_map_enc(kssl_ctx->enctype);
             if (enc == NULL)
                 goto err;
 # ifdef KSSL_DEBUG
             {
                 fprintf(stderr, "kssl_cget_tkt rtn %d\n", krb5rc);
                 if (krb5rc && kssl_err.text)
                     fprintf(stderr, "kssl_cget_tkt kssl_err=%s\n",
                             kssl_err.text);
             }
 # endif                         /* KSSL_DEBUG */
 
             if (krb5rc) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason);
                 goto err;
             }
 
             /*-
              * 20010406 VRS - Earlier versions used KRB5 AP_REQ
              * in place of RFC 2712 KerberosWrapper, as in:
              *
              * Send ticket (copy to *p, set n = length)
              * n = krb5_ap_req.length;
              * memcpy(p, krb5_ap_req.data, krb5_ap_req.length);
              * if (krb5_ap_req.data)
              *   kssl_krb5_free_data_contents(NULL,&krb5_ap_req);
              *
              * Now using real RFC 2712 KerberosWrapper
              * (Thanks to Simon Wilkinson <sxw@sxw.org.uk>)
              * Note: 2712 "opaque" types are here replaced
              * with a 2-byte length followed by the value.
              * Example:
              * KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms
              * Where "xx xx" = length bytes.  Shown here with
              * optional authenticator omitted.
              */
 
             /*  KerberosWrapper.Ticket              */
             s2n(enc_ticket->length, p);
             memcpy(p, enc_ticket->data, enc_ticket->length);
             p += enc_ticket->length;
             n = enc_ticket->length + 2;
 
             /*  KerberosWrapper.Authenticator       */
             if (authp && authp->length) {
                 s2n(authp->length, p);
                 memcpy(p, authp->data, authp->length);
                 p += authp->length;
                 n += authp->length + 2;
 
                 free(authp->data);
                 authp->data = NULL;
                 authp->length = 0;
             } else {
                 s2n(0, p);      /* null authenticator length */
                 n += 2;
             }
 
             tmp_buf[0] = s->client_version >> 8;
             tmp_buf[1] = s->client_version & 0xff;
             if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0)
                 goto err;
 
             /*-
              * 20010420 VRS.  Tried it this way; failed.
              *      EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL);
              *      EVP_CIPHER_CTX_set_key_length(&ciph_ctx,
              *                              kssl_ctx->length);
              *      EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv);
              */
 
             memset(iv, 0, sizeof iv); /* per RFC 1510 */
             EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv);
             EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf,
                               sizeof tmp_buf);
             EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl);
             outl += padl;
             if (outl > (int)sizeof epms) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
             /*  KerberosWrapper.EncryptedPreMasterSecret    */
             s2n(outl, p);
             memcpy(p, epms, outl);
             p += outl;
             n += outl + 2;
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             tmp_buf,
                                                             sizeof tmp_buf);
 
             OPENSSL_cleanse(tmp_buf, sizeof tmp_buf);
             OPENSSL_cleanse(epms, outl);
         }
 #endif
 #ifndef OPENSSL_NO_DH
         else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) {
             DH *dh_srvr, *dh_clnt;
 
             if (s->session->sess_cert == NULL) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNEXPECTED_MESSAGE);
                 goto err;
             }
 
             if (s->session->sess_cert->peer_dh_tmp != NULL)
                 dh_srvr = s->session->sess_cert->peer_dh_tmp;
             else {
                 /* we get them from the cert */
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNABLE_TO_FIND_DH_PARAMETERS);
                 goto err;
             }
 
             /* generate a new random key */
             if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
             if (!DH_generate_key(dh_clnt)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 DH_free(dh_clnt);
                 goto err;
             }
 
             /*
              * use the 'p' output buffer for the DH key, but make sure to
              * clear it out afterwards
              */
 
             n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt);
 
             if (n <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
                 DH_free(dh_clnt);
                 goto err;
             }
 
             /* generate master key from the result */
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             p, n);
             /* clean up */
             memset(p, 0, n);
 
             /* send off the data */
             n = BN_num_bytes(dh_clnt->pub_key);
             s2n(n, p);
             BN_bn2bin(dh_clnt->pub_key, p);
             n += 2;
 
             DH_free(dh_clnt);
         }
 #endif
 
 #ifndef OPENSSL_NO_ECDH
         else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) {
             const EC_GROUP *srvr_group = NULL;
             EC_KEY *tkey;
             int ecdh_clnt_cert = 0;
             int field_size = 0;
 
             if (s->session->sess_cert == NULL) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNEXPECTED_MESSAGE);
                 goto err;
             }
 
             /*
              * Did we send out the client's ECDH share for use in premaster
              * computation as part of client certificate? If so, set
              * ecdh_clnt_cert to 1.
              */
             if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) {
                 /*-
                  * XXX: For now, we do not support client
                  * authentication using ECDH certificates.
                  * To add such support, one needs to add
                  * code that checks for appropriate
                  * conditions and sets ecdh_clnt_cert to 1.
                  * For example, the cert have an ECC
                  * key on the same curve as the server's
                  * and the key should be authorized for
                  * key agreement.
                  *
                  * One also needs to add code in ssl3_connect
                  * to skip sending the certificate verify
                  * message.
                  *
                  * if ((s->cert->key->privatekey != NULL) &&
                  *     (s->cert->key->privatekey->type ==
                  *      EVP_PKEY_EC) && ...)
                  * ecdh_clnt_cert = 1;
                  */
             }
 
             if (s->session->sess_cert->peer_ecdh_tmp != NULL) {
                 tkey = s->session->sess_cert->peer_ecdh_tmp;
             } else {
                 /* Get the Server Public Key from Cert */
                 srvr_pub_pkey =
                     X509_get_pubkey(s->session->
                                     sess_cert->peer_pkeys[SSL_PKEY_ECC].x509);
                 if ((srvr_pub_pkey == NULL)
                     || (srvr_pub_pkey->type != EVP_PKEY_EC)
                     || (srvr_pub_pkey->pkey.ec == NULL)) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_INTERNAL_ERROR);
                     goto err;
                 }
 
                 tkey = srvr_pub_pkey->pkey.ec;
             }
 
             srvr_group = EC_KEY_get0_group(tkey);
             srvr_ecpoint = EC_KEY_get0_public_key(tkey);
 
             if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if ((clnt_ecdh = EC_KEY_new()) == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
             if (ecdh_clnt_cert) {
                 /*
                  * Reuse key info from our certificate We only need our
                  * private key to perform the ECDH computation.
                  */
                 const BIGNUM *priv_key;
                 tkey = s->cert->key->privatekey->pkey.ec;
                 priv_key = EC_KEY_get0_private_key(tkey);
                 if (priv_key == NULL) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
                     goto err;
                 }
                 if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                     goto err;
                 }
             } else {
                 /* Generate a new ECDH key pair */
                 if (!(EC_KEY_generate_key(clnt_ecdh))) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_ECDH_LIB);
                     goto err;
                 }
             }
 
             /*
              * use the 'p' output buffer for the ECDH key, but make sure to
              * clear it out afterwards
              */
 
             field_size = EC_GROUP_get_degree(srvr_group);
             if (field_size <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
             n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint,
                                  clnt_ecdh, NULL);
             if (n <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             /* generate master key from the result */
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             p, n);
 
             memset(p, 0, n);    /* clean up */
 
             if (ecdh_clnt_cert) {
                 /* Send empty client key exch message */
                 n = 0;
             } else {
                 /*
                  * First check the size of encoding and allocate memory
                  * accordingly.
                  */
                 encoded_pt_len =
                     EC_POINT_point2oct(srvr_group,
                                        EC_KEY_get0_public_key(clnt_ecdh),
                                        POINT_CONVERSION_UNCOMPRESSED,
                                        NULL, 0, NULL);
 
                 encodedPoint = (unsigned char *)
                     OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char));
                 bn_ctx = BN_CTX_new();
                 if ((encodedPoint == NULL) || (bn_ctx == NULL)) {
                     SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                            ERR_R_MALLOC_FAILURE);
                     goto err;
                 }
 
                 /* Encode the public key */
                 n = EC_POINT_point2oct(srvr_group,
                                        EC_KEY_get0_public_key(clnt_ecdh),
                                        POINT_CONVERSION_UNCOMPRESSED,
                                        encodedPoint, encoded_pt_len, bn_ctx);
 
                 *p = n;         /* length of encoded point */
                 /* Encoded point will be copied here */
                 p += 1;
                 /* copy the point */
                 memcpy((unsigned char *)p, encodedPoint, n);
                 /* increment n to account for length field */
                 n += 1;
             }
 
             /* Free allocated memory */
             BN_CTX_free(bn_ctx);
             if (encodedPoint != NULL)
                 OPENSSL_free(encodedPoint);
             if (clnt_ecdh != NULL)
                 EC_KEY_free(clnt_ecdh);
             EVP_PKEY_free(srvr_pub_pkey);
         }
 #endif                          /* !OPENSSL_NO_ECDH */
         else if (alg_k & SSL_kGOST) {
             /* GOST key exchange message creation */
             EVP_PKEY_CTX *pkey_ctx;
             X509 *peer_cert;
             size_t msglen;
             unsigned int md_len;
             int keytype;
             unsigned char premaster_secret[32], shared_ukm[32], tmp[256];
             EVP_MD_CTX *ukm_hash;
             EVP_PKEY *pub_key;
 
             /*
              * Get server sertificate PKEY and create ctx from it
              */
             peer_cert =
                 s->session->
                 sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST01)].x509;
             if (!peer_cert)
                 peer_cert =
                     s->session->
                     sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST94)].x509;
             if (!peer_cert) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
                 goto err;
             }
 
             pkey_ctx = EVP_PKEY_CTX_new(pub_key =
                                         X509_get_pubkey(peer_cert), NULL);
             if (pkey_ctx == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
             /*
              * If we have send a certificate, and certificate key
              *
              * * parameters match those of server certificate, use
              * certificate key for key exchange
              */
 
             /* Otherwise, generate ephemeral key pair */
 
             if (pkey_ctx == NULL
                     || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
                     /* Generate session key */
                     || RAND_bytes(premaster_secret, 32) <= 0) {
                 EVP_PKEY_CTX_free(pkey_ctx);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             /*
-             * If we have client certificate, use its secret as peer key
-             */
-            if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
-                if (EVP_PKEY_derive_set_peer
-                    (pkey_ctx, s->cert->key->privatekey) <= 0) {
-                    /*
-                     * If there was an error - just ignore it. Ephemeral key
-                     * * would be used
-                     */
-                    ERR_clear_error();
-                }
-            }
-            /*
              * Compute shared IV and store it in algorithm-specific context
              * data
              */
             ukm_hash = EVP_MD_CTX_create();
             if (EVP_DigestInit(ukm_hash,
                                EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0
                     || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
                                         SSL3_RANDOM_SIZE) <= 0
                     || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
                                         SSL3_RANDOM_SIZE) <= 0
                     || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
                 EVP_MD_CTX_destroy(ukm_hash);
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             EVP_MD_CTX_destroy(ukm_hash);
             if (EVP_PKEY_CTX_ctrl
                 (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
                  shared_ukm) < 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_LIBRARY_BUG);
                 goto err;
             }
             /* Make GOST keytransport blob message */
             /*
              * Encapsulate it into sequence
              */
             *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
             msglen = 255;
             if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32)
                 <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_LIBRARY_BUG);
                 goto err;
             }
             if (msglen >= 0x80) {
                 *(p++) = 0x81;
                 *(p++) = msglen & 0xff;
                 n = msglen + 3;
             } else {
                 *(p++) = msglen & 0xff;
                 n = msglen + 2;
             }
             memcpy(p, tmp, msglen);
-            /* Check if pubkey from client certificate was used */
-            if (EVP_PKEY_CTX_ctrl
-                (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) {
-                /* Set flag "skip certificate verify" */
-                s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
-            }
             EVP_PKEY_CTX_free(pkey_ctx);
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             premaster_secret,
                                                             32);
             EVP_PKEY_free(pub_key);
 
         }
 #ifndef OPENSSL_NO_SRP
         else if (alg_k & SSL_kSRP) {
             if (s->srp_ctx.A != NULL) {
                 /* send off the data */
                 n = BN_num_bytes(s->srp_ctx.A);
                 s2n(n, p);
                 BN_bn2bin(s->srp_ctx.A, p);
                 n += 2;
             } else {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             if (s->session->srp_username != NULL)
                 OPENSSL_free(s->session->srp_username);
             s->session->srp_username = BUF_strdup(s->srp_ctx.login);
             if (s->session->srp_username == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             if ((s->session->master_key_length =
                  SRP_generate_client_master_secret(s,
                                                    s->session->master_key)) <
                 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
         }
 #endif
 #ifndef OPENSSL_NO_PSK
         else if (alg_k & SSL_kPSK) {
             /*
              * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a
              * \0-terminated identity. The last byte is for us for simulating
              * strnlen.
              */
             char identity[PSK_MAX_IDENTITY_LEN + 2];
             size_t identity_len;
             unsigned char *t = NULL;
             unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4];
             unsigned int pre_ms_len = 0, psk_len = 0;
             int psk_err = 1;
 
             n = 0;
             if (s->psk_client_callback == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_PSK_NO_CLIENT_CB);
                 goto err;
             }
 
             memset(identity, 0, sizeof(identity));
             psk_len = s->psk_client_callback(s, s->session->psk_identity_hint,
                                              identity, sizeof(identity) - 1,
                                              psk_or_pre_ms,
                                              sizeof(psk_or_pre_ms));
             if (psk_len > PSK_MAX_PSK_LEN) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto psk_err;
             } else if (psk_len == 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        SSL_R_PSK_IDENTITY_NOT_FOUND);
                 goto psk_err;
             }
             identity[PSK_MAX_IDENTITY_LEN + 1] = '\0';
             identity_len = strlen(identity);
             if (identity_len > PSK_MAX_IDENTITY_LEN) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto psk_err;
             }
             /* create PSK pre_master_secret */
             pre_ms_len = 2 + psk_len + 2 + psk_len;
             t = psk_or_pre_ms;
             memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len);
             s2n(psk_len, t);
             memset(t, 0, psk_len);
             t += psk_len;
             s2n(psk_len, t);
 
             if (s->session->psk_identity_hint != NULL)
                 OPENSSL_free(s->session->psk_identity_hint);
             s->session->psk_identity_hint =
                 BUF_strdup(s->ctx->psk_identity_hint);
             if (s->ctx->psk_identity_hint != NULL
                 && s->session->psk_identity_hint == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto psk_err;
             }
 
             if (s->session->psk_identity != NULL)
                 OPENSSL_free(s->session->psk_identity);
             s->session->psk_identity = BUF_strdup(identity);
             if (s->session->psk_identity == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto psk_err;
             }
 
             s->session->master_key_length =
                 s->method->ssl3_enc->generate_master_secret(s,
                                                             s->
                                                             session->master_key,
                                                             psk_or_pre_ms,
                                                             pre_ms_len);
             s2n(identity_len, p);
             memcpy(p, identity, identity_len);
             n = 2 + identity_len;
             psk_err = 0;
  psk_err:
             OPENSSL_cleanse(identity, sizeof(identity));
             OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
             if (psk_err != 0) {
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 goto err;
             }
         }
 #endif
         else {
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
             SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 
         *(d++) = SSL3_MT_CLIENT_KEY_EXCHANGE;
         l2n3(n, d);
 
         s->state = SSL3_ST_CW_KEY_EXCH_B;
         /* number of bytes to write */
         s->init_num = n + 4;
         s->init_off = 0;
     }
 
     /* SSL3_ST_CW_KEY_EXCH_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
 #ifndef OPENSSL_NO_ECDH
     BN_CTX_free(bn_ctx);
     if (encodedPoint != NULL)
         OPENSSL_free(encodedPoint);
     if (clnt_ecdh != NULL)
         EC_KEY_free(clnt_ecdh);
     EVP_PKEY_free(srvr_pub_pkey);
 #endif
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_send_client_verify(SSL *s)
 {
     unsigned char *p, *d;
     unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
     EVP_PKEY *pkey;
     EVP_PKEY_CTX *pctx = NULL;
     EVP_MD_CTX mctx;
     unsigned u = 0;
     unsigned long n;
     int j;
 
     EVP_MD_CTX_init(&mctx);
 
     if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
         d = (unsigned char *)s->init_buf->data;
         p = &(d[4]);
         pkey = s->cert->key->privatekey;
 /* Create context from key and test if sha1 is allowed as digest */
         pctx = EVP_PKEY_CTX_new(pkey, NULL);
         if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) {
             SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
             goto err;
         }
         if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) {
             if (TLS1_get_version(s) < TLS1_2_VERSION)
                 s->method->ssl3_enc->cert_verify_mac(s,
                                                      NID_sha1,
                                                      &(data
                                                        [MD5_DIGEST_LENGTH]));
         } else {
             ERR_clear_error();
         }
         /*
          * For TLS v1.2 send signature algorithm and signature using agreed
          * digest and cached handshake records.
          */
         if (TLS1_get_version(s) >= TLS1_2_VERSION) {
             long hdatalen = 0;
             void *hdata;
             const EVP_MD *md = s->cert->key->digest;
             hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
             if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             p += 2;
 #ifdef SSL_DEBUG
             fprintf(stderr, "Using TLS 1.2 with client alg %s\n",
                     EVP_MD_name(md));
 #endif
             if (!EVP_SignInit_ex(&mctx, md, NULL)
                 || !EVP_SignUpdate(&mctx, hdata, hdatalen)
                 || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_EVP_LIB);
                 goto err;
             }
             s2n(u, p);
             n = u + 4;
             if (!ssl3_digest_cached_records(s))
                 goto err;
         } else
 #ifndef OPENSSL_NO_RSA
         if (pkey->type == EVP_PKEY_RSA) {
             s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0]));
             if (RSA_sign(NID_md5_sha1, data,
                          MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
                          &(p[2]), &u, pkey->pkey.rsa) <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB);
                 goto err;
             }
             s2n(u, p);
             n = u + 2;
         } else
 #endif
 #ifndef OPENSSL_NO_DSA
         if (pkey->type == EVP_PKEY_DSA) {
             if (!DSA_sign(pkey->save_type,
                           &(data[MD5_DIGEST_LENGTH]),
                           SHA_DIGEST_LENGTH, &(p[2]),
                           (unsigned int *)&j, pkey->pkey.dsa)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB);
                 goto err;
             }
             s2n(j, p);
             n = j + 2;
         } else
 #endif
 #ifndef OPENSSL_NO_ECDSA
         if (pkey->type == EVP_PKEY_EC) {
             if (!ECDSA_sign(pkey->save_type,
                             &(data[MD5_DIGEST_LENGTH]),
                             SHA_DIGEST_LENGTH, &(p[2]),
                             (unsigned int *)&j, pkey->pkey.ec)) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB);
                 goto err;
             }
             s2n(j, p);
             n = j + 2;
         } else
 #endif
         if (pkey->type == NID_id_GostR3410_94
                 || pkey->type == NID_id_GostR3410_2001) {
             unsigned char signbuf[64];
             int i;
             size_t sigsize = 64;
             s->method->ssl3_enc->cert_verify_mac(s,
                                                  NID_id_GostR3411_94, data);
             if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) {
                 SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
             for (i = 63, j = 0; i >= 0; j++, i--) {
                 p[2 + j] = signbuf[i];
             }
             s2n(j, p);
             n = j + 2;
         } else {
             SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR);
             goto err;
         }
         *(d++) = SSL3_MT_CERTIFICATE_VERIFY;
         l2n3(n, d);
 
         s->state = SSL3_ST_CW_CERT_VRFY_B;
         s->init_num = (int)n + 4;
         s->init_off = 0;
     }
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_CTX_free(pctx);
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_CTX_free(pctx);
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_send_client_certificate(SSL *s)
 {
     X509 *x509 = NULL;
     EVP_PKEY *pkey = NULL;
     int i;
     unsigned long l;
 
     if (s->state == SSL3_ST_CW_CERT_A) {
         if ((s->cert == NULL) ||
             (s->cert->key->x509 == NULL) ||
             (s->cert->key->privatekey == NULL))
             s->state = SSL3_ST_CW_CERT_B;
         else
             s->state = SSL3_ST_CW_CERT_C;
     }
 
     /* We need to get a client cert */
     if (s->state == SSL3_ST_CW_CERT_B) {
         /*
          * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP;
          * return(-1); We then get retied later
          */
         i = ssl_do_client_cert_cb(s, &x509, &pkey);
         if (i < 0) {
             s->rwstate = SSL_X509_LOOKUP;
             return (-1);
         }
         s->rwstate = SSL_NOTHING;
         if ((i == 1) && (pkey != NULL) && (x509 != NULL)) {
             s->state = SSL3_ST_CW_CERT_B;
             if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey))
                 i = 0;
         } else if (i == 1) {
             i = 0;
             SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE,
                    SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
         }
 
         if (x509 != NULL)
             X509_free(x509);
         if (pkey != NULL)
             EVP_PKEY_free(pkey);
         if (i == 0) {
             if (s->version == SSL3_VERSION) {
                 s->s3->tmp.cert_req = 0;
                 ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE);
                 return (1);
             } else {
                 s->s3->tmp.cert_req = 2;
             }
         }
 
         /* Ok, we have a cert */
         s->state = SSL3_ST_CW_CERT_C;
     }
 
     if (s->state == SSL3_ST_CW_CERT_C) {
         s->state = SSL3_ST_CW_CERT_D;
         l = ssl3_output_cert_chain(s,
                                    (s->s3->tmp.cert_req ==
                                     2) ? NULL : s->cert->key->x509);
         if (!l) {
             SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
             s->state = SSL_ST_ERR;
             return 0;
         }
         s->init_num = (int)l;
         s->init_off = 0;
     }
     /* SSL3_ST_CW_CERT_D */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 #define has_bits(i,m)   (((i)&(m)) == (m))
 
 int ssl3_check_cert_and_algorithm(SSL *s)
 {
     int i, idx;
     long alg_k, alg_a;
     EVP_PKEY *pkey = NULL;
     int pkey_bits;
     SESS_CERT *sc;
 #ifndef OPENSSL_NO_RSA
     RSA *rsa;
 #endif
 #ifndef OPENSSL_NO_DH
     DH *dh;
 #endif
     int al = SSL_AD_HANDSHAKE_FAILURE;
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
     alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
     /* we don't have a certificate */
     if ((alg_a & (SSL_aDH | SSL_aNULL | SSL_aKRB5)) || (alg_k & SSL_kPSK))
         return (1);
 
     sc = s->session->sess_cert;
     if (sc == NULL) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
         goto err;
     }
 #ifndef OPENSSL_NO_RSA
     rsa = s->session->sess_cert->peer_rsa_tmp;
 #endif
 #ifndef OPENSSL_NO_DH
     dh = s->session->sess_cert->peer_dh_tmp;
 #endif
 
     /* This is the passed certificate */
 
     idx = sc->peer_cert_type;
 #ifndef OPENSSL_NO_ECDH
     if (idx == SSL_PKEY_ECC) {
         if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) {
             /* check failed */
             SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT);
             goto f_err;
         } else {
             return 1;
         }
     }
 #endif
     pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509);
     pkey_bits = EVP_PKEY_bits(pkey);
     i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey);
     EVP_PKEY_free(pkey);
 
     /* Check that we have a certificate if we require one */
     if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_RSA_SIGNING_CERT);
         goto f_err;
     }
 #ifndef OPENSSL_NO_DSA
     else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_DSA_SIGNING_CERT);
         goto f_err;
     }
 #endif
 #ifndef OPENSSL_NO_RSA
     if (alg_k & SSL_kRSA) {
         if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
             !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
             SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                    SSL_R_MISSING_RSA_ENCRYPTING_CERT);
             goto f_err;
         } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) {
             if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
                 if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) {
                     SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                            SSL_R_MISSING_RSA_ENCRYPTING_CERT);
                     goto f_err;
                 }
                 if (rsa != NULL) {
                     /* server key exchange is not allowed. */
                     al = SSL_AD_INTERNAL_ERROR;
                     SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
                     goto f_err;
                 }
             }
         }
     }
 #endif
 #ifndef OPENSSL_NO_DH
     if ((alg_k & SSL_kEDH) && dh == NULL) {
         al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR);
         goto f_err;
     }
     if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_DH_RSA_CERT);
         goto f_err;
     }
 # ifndef OPENSSL_NO_DSA
     if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) {
         SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                SSL_R_MISSING_DH_DSA_CERT);
         goto f_err;
     }
 # endif
 
     /* Check DHE only: static DH not implemented. */
     if (alg_k & SSL_kEDH) {
         int dh_size = BN_num_bits(dh->p);
         if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024)
             || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) {
             SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL);
             goto f_err;
         }
     }
 #endif  /* !OPENSSL_NO_DH */
 
     if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
         pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
 #ifndef OPENSSL_NO_RSA
         if (alg_k & SSL_kRSA) {
             if (rsa == NULL) {
                 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                        SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
                 goto f_err;
             } else if (BN_num_bits(rsa->n) >
                 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
                 /* We have a temporary RSA key but it's too large. */
                 al = SSL_AD_EXPORT_RESTRICTION;
                 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                        SSL_R_MISSING_EXPORT_TMP_RSA_KEY);
                 goto f_err;
             }
         } else
 #endif
 #ifndef OPENSSL_NO_DH
         if (alg_k & SSL_kEDH) {
             if (BN_num_bits(dh->p) >
                 SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) {
                 /* We have a temporary DH key but it's too large. */
                 al = SSL_AD_EXPORT_RESTRICTION;
                 SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                        SSL_R_MISSING_EXPORT_TMP_DH_KEY);
                 goto f_err;
             }
         } else if (alg_k & (SSL_kDHr | SSL_kDHd)) {
             /* The cert should have had an export DH key. */
             al = SSL_AD_EXPORT_RESTRICTION;
             SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                    SSL_R_MISSING_EXPORT_TMP_DH_KEY);
                 goto f_err;
         } else
 #endif
         {
             SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,
                    SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
             goto f_err;
         }
     }
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
     return (0);
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 /*
  * Normally, we can tell if the server is resuming the session from
  * the session ID. EAP-FAST (RFC 4851), however, relies on the next server
  * message after the ServerHello to determine if the server is resuming.
  * Therefore, we allow EAP-FAST to peek ahead.
  * ssl3_check_finished returns 1 if we are resuming from an external
  * pre-shared secret, we have a "ticket" and the next server handshake message
  * is Finished; and 0 otherwise. It returns -1 upon an error.
  */
 static int ssl3_check_finished(SSL *s)
 {
     int ok = 0;
 
     if (s->version < TLS1_VERSION || !s->tls_session_secret_cb ||
         !s->session->tlsext_tick)
         return 0;
 
     /* Need to permit this temporarily, in case the next message is Finished. */
     s->s3->flags |= SSL3_FLAGS_CCS_OK;
     /*
      * This function is called when we might get a Certificate message instead,
      * so permit appropriate message length.
      * We ignore the return value as we're only interested in the message type
      * and not its length.
      */
     s->method->ssl_get_message(s,
                                SSL3_ST_CR_CERT_A,
                                SSL3_ST_CR_CERT_B,
                                -1, s->max_cert_list, &ok);
     s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
 
     if (!ok)
         return -1;
 
     s->s3->tmp.reuse_message = 1;
 
     if (s->s3->tmp.message_type == SSL3_MT_FINISHED)
         return 1;
 
     /* If we're not done, then the CCS arrived early and we should bail. */
     if (s->s3->change_cipher_spec) {
         SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY);
         ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
         return -1;
     }
 
     return 0;
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 int ssl3_send_next_proto(SSL *s)
 {
     unsigned int len, padding_len;
     unsigned char *d;
 
     if (s->state == SSL3_ST_CW_NEXT_PROTO_A) {
         len = s->next_proto_negotiated_len;
         padding_len = 32 - ((len + 2) % 32);
         d = (unsigned char *)s->init_buf->data;
         d[4] = len;
         memcpy(d + 5, s->next_proto_negotiated, len);
         d[5 + len] = padding_len;
         memset(d + 6 + len, 0, padding_len);
         *(d++) = SSL3_MT_NEXT_PROTO;
         l2n3(2 + len + padding_len, d);
         s->state = SSL3_ST_CW_NEXT_PROTO_B;
         s->init_num = 4 + 2 + len + padding_len;
         s->init_off = 0;
     }
 
     return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
 }
 #endif                          /* !OPENSSL_NO_NEXTPROTONEG */
 #endif                          /* !OPENSSL_NO_TLSEXT */
 
 int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey)
 {
     int i = 0;
 #ifndef OPENSSL_NO_ENGINE
     if (s->ctx->client_cert_engine) {
         i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s,
                                         SSL_get_client_CA_list(s),
                                         px509, ppkey, NULL, NULL, NULL);
         if (i != 0)
             return i;
     }
 #endif
     if (s->ctx->client_cert_cb)
         i = s->ctx->client_cert_cb(s, px509, ppkey);
     return i;
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s3_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s3_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s3_lib.c	(revision 306191)
@@ -1,4366 +1,4366 @@
 /* ssl/s3_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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by
  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
  *
  * The Contribution is licensed pursuant to the OpenSSL open source
  * license provided above.
  *
  * ECC cipher suite support in OpenSSL originally written by
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #include <stdio.h>
 #include <openssl/objects.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
 #ifndef OPENSSL_NO_TLSEXT
 # ifndef OPENSSL_NO_EC
 #  include "../crypto/ec/ec_lcl.h"
 # endif                         /* OPENSSL_NO_EC */
 #endif                          /* OPENSSL_NO_TLSEXT */
 #include <openssl/md5.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 
 const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT;
 
 #define SSL3_NUM_CIPHERS        (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER))
 
 /* list of available SSLv3 ciphers (sorted by id) */
 OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
 
 /* The RSA ciphers */
 /* Cipher 01 */
     {
      1,
      SSL3_TXT_RSA_NULL_MD5,
      SSL3_CK_RSA_NULL_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eNULL,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_STRONG_NONE,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
 /* Cipher 02 */
     {
      1,
      SSL3_TXT_RSA_NULL_SHA,
      SSL3_CK_RSA_NULL_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eNULL,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
 /* Cipher 03 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_RSA_RC4_40_MD5,
      SSL3_CK_RSA_RC4_40_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 #endif
 
 /* Cipher 04 */
     {
      1,
      SSL3_TXT_RSA_RC4_128_MD5,
      SSL3_CK_RSA_RC4_128_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 05 */
     {
      1,
      SSL3_TXT_RSA_RC4_128_SHA,
      SSL3_CK_RSA_RC4_128_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC4,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 06 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_RSA_RC2_40_MD5,
      SSL3_CK_RSA_RC2_40_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC2,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 #endif
 
 /* Cipher 07 */
 #ifndef OPENSSL_NO_IDEA
     {
      1,
      SSL3_TXT_RSA_IDEA_128_SHA,
      SSL3_CK_RSA_IDEA_128_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_IDEA,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 #endif
 
 /* Cipher 08 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_RSA_DES_40_CBC_SHA,
      SSL3_CK_RSA_DES_40_CBC_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 #endif
 
 /* Cipher 09 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_RSA_DES_64_CBC_SHA,
      SSL3_CK_RSA_DES_64_CBC_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 0A */
     {
      1,
      SSL3_TXT_RSA_DES_192_CBC3_SHA,
      SSL3_CK_RSA_DES_192_CBC3_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* The DH ciphers */
 /* Cipher 0B */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      0,
      SSL3_TXT_DH_DSS_DES_40_CBC_SHA,
      SSL3_CK_DH_DSS_DES_40_CBC_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 #endif
 
 /* Cipher 0C */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      0,                         /* not implemented (non-ephemeral DH) */
      SSL3_TXT_DH_DSS_DES_64_CBC_SHA,
      SSL3_CK_DH_DSS_DES_64_CBC_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 0D */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      SSL3_TXT_DH_DSS_DES_192_CBC3_SHA,
      SSL3_CK_DH_DSS_DES_192_CBC3_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Cipher 0E */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      0,                         /* not implemented (non-ephemeral DH) */
      SSL3_TXT_DH_RSA_DES_40_CBC_SHA,
      SSL3_CK_DH_RSA_DES_40_CBC_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 #endif
 
 /* Cipher 0F */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      0,                         /* not implemented (non-ephemeral DH) */
      SSL3_TXT_DH_RSA_DES_64_CBC_SHA,
      SSL3_CK_DH_RSA_DES_64_CBC_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 10 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      SSL3_TXT_DH_RSA_DES_192_CBC3_SHA,
      SSL3_CK_DH_RSA_DES_192_CBC3_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* The Ephemeral DH ciphers */
 /* Cipher 11 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_EDH_DSS_DES_40_CBC_SHA,
      SSL3_CK_EDH_DSS_DES_40_CBC_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 #endif
 
 /* Cipher 12 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_EDH_DSS_DES_64_CBC_SHA,
      SSL3_CK_EDH_DSS_DES_64_CBC_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 13 */
     {
      1,
      SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA,
      SSL3_CK_EDH_DSS_DES_192_CBC3_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Cipher 14 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_EDH_RSA_DES_40_CBC_SHA,
      SSL3_CK_EDH_RSA_DES_40_CBC_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 #endif
 
 /* Cipher 15 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_EDH_RSA_DES_64_CBC_SHA,
      SSL3_CK_EDH_RSA_DES_64_CBC_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 16 */
     {
      1,
      SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA,
      SSL3_CK_EDH_RSA_DES_192_CBC3_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Cipher 17 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_ADH_RC4_40_MD5,
      SSL3_CK_ADH_RC4_40_MD5,
      SSL_kEDH,
      SSL_aNULL,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 #endif
 
 /* Cipher 18 */
     {
      1,
      SSL3_TXT_ADH_RC4_128_MD5,
      SSL3_CK_ADH_RC4_128_MD5,
      SSL_kEDH,
      SSL_aNULL,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 19 */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_ADH_DES_40_CBC_SHA,
      SSL3_CK_ADH_DES_40_CBC_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 #endif
 
 /* Cipher 1A */
 #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_ADH_DES_64_CBC_SHA,
      SSL3_CK_ADH_DES_64_CBC_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 #endif
 
 /* Cipher 1B */
     {
      1,
      SSL3_TXT_ADH_DES_192_CBC_SHA,
      SSL3_CK_ADH_DES_192_CBC_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Fortezza ciphersuite from SSL 3.0 spec */
 #if 0
 /* Cipher 1C */
     {
      0,
      SSL3_TXT_FZA_DMS_NULL_SHA,
      SSL3_CK_FZA_DMS_NULL_SHA,
      SSL_kFZA,
      SSL_aFZA,
      SSL_eNULL,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_STRONG_NONE,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
 /* Cipher 1D */
     {
      0,
      SSL3_TXT_FZA_DMS_FZA_SHA,
      SSL3_CK_FZA_DMS_FZA_SHA,
      SSL_kFZA,
      SSL_aFZA,
      SSL_eFZA,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_STRONG_NONE,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
 /* Cipher 1E */
     {
      0,
      SSL3_TXT_FZA_DMS_RC4_SHA,
      SSL3_CK_FZA_DMS_RC4_SHA,
      SSL_kFZA,
      SSL_aFZA,
      SSL_RC4,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 #endif
 
 #ifndef OPENSSL_NO_KRB5
 /* The Kerberos ciphers*/
 /* Cipher 1E */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_DES_64_CBC_SHA,
      SSL3_CK_KRB5_DES_64_CBC_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 # endif
 
 /* Cipher 1F */
     {
      1,
      SSL3_TXT_KRB5_DES_192_CBC3_SHA,
      SSL3_CK_KRB5_DES_192_CBC3_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_3DES,
      SSL_SHA1,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Cipher 20 */
     {
      1,
      SSL3_TXT_KRB5_RC4_128_SHA,
      SSL3_CK_KRB5_RC4_128_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC4,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 21 */
     {
      1,
      SSL3_TXT_KRB5_IDEA_128_CBC_SHA,
      SSL3_CK_KRB5_IDEA_128_CBC_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_IDEA,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 22 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_DES_64_CBC_MD5,
      SSL3_CK_KRB5_DES_64_CBC_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_DES,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 # endif
 
 /* Cipher 23 */
     {
      1,
      SSL3_TXT_KRB5_DES_192_CBC3_MD5,
      SSL3_CK_KRB5_DES_192_CBC3_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_3DES,
      SSL_MD5,
      SSL_SSLV3,
-     SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
 /* Cipher 24 */
     {
      1,
      SSL3_TXT_KRB5_RC4_128_MD5,
      SSL3_CK_KRB5_RC4_128_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 25 */
     {
      1,
      SSL3_TXT_KRB5_IDEA_128_CBC_MD5,
      SSL3_CK_KRB5_IDEA_128_CBC_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_IDEA,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 26 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_DES_40_CBC_SHA,
      SSL3_CK_KRB5_DES_40_CBC_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_DES,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 # endif
 
 /* Cipher 27 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_RC2_40_CBC_SHA,
      SSL3_CK_KRB5_RC2_40_CBC_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC2,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 # endif
 
 /* Cipher 28 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_RC4_40_SHA,
      SSL3_CK_KRB5_RC4_40_SHA,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC4,
      SSL_SHA1,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 # endif
 
 /* Cipher 29 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_DES_40_CBC_MD5,
      SSL3_CK_KRB5_DES_40_CBC_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_DES,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      56,
      },
 # endif
 
 /* Cipher 2A */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_RC2_40_CBC_MD5,
      SSL3_CK_KRB5_RC2_40_CBC_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC2,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 # endif
 
 /* Cipher 2B */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      SSL3_TXT_KRB5_RC4_40_MD5,
      SSL3_CK_KRB5_RC4_40_MD5,
      SSL_kKRB5,
      SSL_aKRB5,
      SSL_RC4,
      SSL_MD5,
      SSL_SSLV3,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      40,
      128,
      },
 # endif
 #endif                          /* OPENSSL_NO_KRB5 */
 
 /* New AES ciphersuites */
 /* Cipher 2F */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_128_SHA,
      TLS1_CK_RSA_WITH_AES_128_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 /* Cipher 30 */
     {
      0,
      TLS1_TXT_DH_DSS_WITH_AES_128_SHA,
      TLS1_CK_DH_DSS_WITH_AES_128_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 /* Cipher 31 */
     {
      0,
      TLS1_TXT_DH_RSA_WITH_AES_128_SHA,
      TLS1_CK_DH_RSA_WITH_AES_128_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 /* Cipher 32 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_128_SHA,
      TLS1_CK_DHE_DSS_WITH_AES_128_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 /* Cipher 33 */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_128_SHA,
      TLS1_CK_DHE_RSA_WITH_AES_128_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 /* Cipher 34 */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_128_SHA,
      TLS1_CK_ADH_WITH_AES_128_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 /* Cipher 35 */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_256_SHA,
      TLS1_CK_RSA_WITH_AES_256_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 /* Cipher 36 */
     {
      0,
      TLS1_TXT_DH_DSS_WITH_AES_256_SHA,
      TLS1_CK_DH_DSS_WITH_AES_256_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
 /* Cipher 37 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_AES_256_SHA,
      TLS1_CK_DH_RSA_WITH_AES_256_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
 /* Cipher 38 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_256_SHA,
      TLS1_CK_DHE_DSS_WITH_AES_256_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
 /* Cipher 39 */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_256_SHA,
      TLS1_CK_DHE_RSA_WITH_AES_256_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 3A */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_256_SHA,
      TLS1_CK_ADH_WITH_AES_256_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* TLS v1.2 ciphersuites */
     /* Cipher 3B */
     {
      1,
      TLS1_TXT_RSA_WITH_NULL_SHA256,
      TLS1_CK_RSA_WITH_NULL_SHA256,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eNULL,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher 3C */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_128_SHA256,
      TLS1_CK_RSA_WITH_AES_128_SHA256,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 3D */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_256_SHA256,
      TLS1_CK_RSA_WITH_AES_256_SHA256,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 3E */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_DSS_WITH_AES_128_SHA256,
      TLS1_CK_DH_DSS_WITH_AES_128_SHA256,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 3F */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_AES_128_SHA256,
      TLS1_CK_DH_RSA_WITH_AES_128_SHA256,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 40 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256,
      TLS1_CK_DHE_DSS_WITH_AES_128_SHA256,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 #ifndef OPENSSL_NO_CAMELLIA
     /* Camellia ciphersuites from RFC4132 (128-bit portion) */
 
     /* Cipher 41 */
     {
      1,
      TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 42 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 43 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 44 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 45 */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 46 */
     {
      1,
      TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA,
      TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_CAMELLIA128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 #endif                          /* OPENSSL_NO_CAMELLIA */
 
 #if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES
     /* New TLS Export CipherSuites from expired ID */
 # if 0
     /* Cipher 60 */
     {
      1,
      TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5,
      TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC4,
      SSL_MD5,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      128,
      },
 
     /* Cipher 61 */
     {
      1,
      TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
      TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC2,
      SSL_MD5,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      128,
      },
 # endif
 
     /* Cipher 62 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA,
      TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_DES,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 # endif
 
     /* Cipher 63 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
      TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_DES,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      56,
      },
 # endif
 
     /* Cipher 64 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA,
      TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      128,
      },
 # endif
 
     /* Cipher 65 */
 # ifndef OPENSSL_NO_WEAK_SSL_CIPHERS
     {
      1,
      TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
      TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      56,
      128,
      },
 # endif
 
     /* Cipher 66 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA,
      TLS1_CK_DHE_DSS_WITH_RC4_128_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 #endif
 
     /* TLS v1.2 ciphersuites */
     /* Cipher 67 */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256,
      TLS1_CK_DHE_RSA_WITH_AES_128_SHA256,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 68 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_DSS_WITH_AES_256_SHA256,
      TLS1_CK_DH_DSS_WITH_AES_256_SHA256,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 69 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_AES_256_SHA256,
      TLS1_CK_DH_RSA_WITH_AES_256_SHA256,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 6A */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256,
      TLS1_CK_DHE_DSS_WITH_AES_256_SHA256,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 6B */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256,
      TLS1_CK_DHE_RSA_WITH_AES_256_SHA256,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 6C */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_128_SHA256,
      TLS1_CK_ADH_WITH_AES_128_SHA256,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 6D */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_256_SHA256,
      TLS1_CK_ADH_WITH_AES_256_SHA256,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES256,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* GOST Ciphersuites */
 
     {
      1,
      "GOST94-GOST89-GOST89",
      0x3000080,
      SSL_kGOST,
      SSL_aGOST94,
      SSL_eGOST2814789CNT,
      SSL_GOST89MAC,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC,
      256,
      256},
     {
      1,
      "GOST2001-GOST89-GOST89",
      0x3000081,
      SSL_kGOST,
      SSL_aGOST01,
      SSL_eGOST2814789CNT,
      SSL_GOST89MAC,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC,
      256,
      256},
     {
      1,
      "GOST94-NULL-GOST94",
      0x3000082,
      SSL_kGOST,
      SSL_aGOST94,
      SSL_eNULL,
      SSL_GOST94,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE,
      SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94,
      0,
      0},
     {
      1,
      "GOST2001-NULL-GOST94",
      0x3000083,
      SSL_kGOST,
      SSL_aGOST01,
      SSL_eNULL,
      SSL_GOST94,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE,
      SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94,
      0,
      0},
 
 #ifndef OPENSSL_NO_CAMELLIA
     /* Camellia ciphersuites from RFC4132 (256-bit portion) */
 
     /* Cipher 84 */
     {
      1,
      TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
     /* Cipher 85 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 86 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 87 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 88 */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher 89 */
     {
      1,
      TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA,
      TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_CAMELLIA256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 #endif                          /* OPENSSL_NO_CAMELLIA */
 
 #ifndef OPENSSL_NO_PSK
     /* Cipher 8A */
     {
      1,
      TLS1_TXT_PSK_WITH_RC4_128_SHA,
      TLS1_CK_PSK_WITH_RC4_128_SHA,
      SSL_kPSK,
      SSL_aPSK,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 8B */
     {
      1,
      TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA,
      TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA,
      SSL_kPSK,
      SSL_aPSK,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher 8C */
     {
      1,
      TLS1_TXT_PSK_WITH_AES_128_CBC_SHA,
      TLS1_CK_PSK_WITH_AES_128_CBC_SHA,
      SSL_kPSK,
      SSL_aPSK,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 8D */
     {
      1,
      TLS1_TXT_PSK_WITH_AES_256_CBC_SHA,
      TLS1_CK_PSK_WITH_AES_256_CBC_SHA,
      SSL_kPSK,
      SSL_aPSK,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 #endif                          /* OPENSSL_NO_PSK */
 
 #ifndef OPENSSL_NO_SEED
     /* SEED ciphersuites from RFC4162 */
 
     /* Cipher 96 */
     {
      1,
      TLS1_TXT_RSA_WITH_SEED_SHA,
      TLS1_CK_RSA_WITH_SEED_SHA,
      SSL_kRSA,
      SSL_aRSA,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 97 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_DSS_WITH_SEED_SHA,
      TLS1_CK_DH_DSS_WITH_SEED_SHA,
      SSL_kDHd,
      SSL_aDH,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 98 */
     {
      0,                         /* not implemented (non-ephemeral DH) */
      TLS1_TXT_DH_RSA_WITH_SEED_SHA,
      TLS1_CK_DH_RSA_WITH_SEED_SHA,
      SSL_kDHr,
      SSL_aDH,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 99 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_SEED_SHA,
      TLS1_CK_DHE_DSS_WITH_SEED_SHA,
      SSL_kEDH,
      SSL_aDSS,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 9A */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_SEED_SHA,
      TLS1_CK_DHE_RSA_WITH_SEED_SHA,
      SSL_kEDH,
      SSL_aRSA,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher 9B */
     {
      1,
      TLS1_TXT_ADH_WITH_SEED_SHA,
      TLS1_CK_ADH_WITH_SEED_SHA,
      SSL_kEDH,
      SSL_aNULL,
      SSL_SEED,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
 #endif                          /* OPENSSL_NO_SEED */
 
     /* GCM ciphersuites from RFC5288 */
 
     /* Cipher 9C */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_RSA_WITH_AES_128_GCM_SHA256,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher 9D */
     {
      1,
      TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_RSA_WITH_AES_256_GCM_SHA384,
      SSL_kRSA,
      SSL_aRSA,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher 9E */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher 9F */
     {
      1,
      TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384,
      SSL_kEDH,
      SSL_aRSA,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher A0 */
     {
      0,
      TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher A1 */
     {
      0,
      TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384,
      SSL_kDHr,
      SSL_aDH,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher A2 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256,
      TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher A3 */
     {
      1,
      TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384,
      TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384,
      SSL_kEDH,
      SSL_aDSS,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher A4 */
     {
      0,
      TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256,
      TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher A5 */
     {
      0,
      TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384,
      TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384,
      SSL_kDHd,
      SSL_aDH,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher A6 */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256,
      TLS1_CK_ADH_WITH_AES_128_GCM_SHA256,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher A7 */
     {
      1,
      TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384,
      TLS1_CK_ADH_WITH_AES_256_GCM_SHA384,
      SSL_kEDH,
      SSL_aNULL,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
 #ifndef OPENSSL_NO_ECDH
     /* Cipher C001 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA,
      TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_eNULL,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher C002 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA,
      TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C003 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
      TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C004 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
      TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C005 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
      TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C006 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA,
      TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_eNULL,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher C007 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA,
      TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C008 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
      TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C009 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C00A */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C00B */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_NULL_SHA,
      TLS1_CK_ECDH_RSA_WITH_NULL_SHA,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_eNULL,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher C00C */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA,
      TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C00D */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA,
      TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C00E */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA,
      TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C00F */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA,
      TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C010 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA,
      TLS1_CK_ECDHE_RSA_WITH_NULL_SHA,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_eNULL,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher C011 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA,
      TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C012 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
      TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C013 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA,
      TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C014 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA,
      TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C015 */
     {
      1,
      TLS1_TXT_ECDH_anon_WITH_NULL_SHA,
      TLS1_CK_ECDH_anon_WITH_NULL_SHA,
      SSL_kEECDH,
      SSL_aNULL,
      SSL_eNULL,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      0,
      0,
      },
 
     /* Cipher C016 */
     {
      1,
      TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA,
      TLS1_CK_ECDH_anon_WITH_RC4_128_SHA,
      SSL_kEECDH,
      SSL_aNULL,
      SSL_RC4,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C017 */
     {
      1,
      TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA,
      TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA,
      SSL_kEECDH,
      SSL_aNULL,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+     SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C018 */
     {
      1,
      TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA,
      TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA,
      SSL_kEECDH,
      SSL_aNULL,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C019 */
     {
      1,
      TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA,
      TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA,
      SSL_kEECDH,
      SSL_aNULL,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 #endif                          /* OPENSSL_NO_ECDH */
 
 #ifndef OPENSSL_NO_SRP
     /* Cipher C01A */
     {
      1,
      TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
      TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA,
      SSL_kSRP,
      SSL_aSRP,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C01B */
     {
      1,
      TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
      TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA,
      SSL_kSRP,
      SSL_aRSA,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C01C */
     {
      1,
      TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
      TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA,
      SSL_kSRP,
      SSL_aDSS,
      SSL_3DES,
      SSL_SHA1,
      SSL_TLSV1,
-     SSL_NOT_EXP | SSL_HIGH,
+     SSL_NOT_EXP | SSL_MEDIUM,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      112,
      168,
      },
 
     /* Cipher C01D */
     {
      1,
      TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA,
      TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA,
      SSL_kSRP,
      SSL_aSRP,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C01E */
     {
      1,
      TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
      TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA,
      SSL_kSRP,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C01F */
     {
      1,
      TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
      TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,
      SSL_kSRP,
      SSL_aDSS,
      SSL_AES128,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      128,
      128,
      },
 
     /* Cipher C020 */
     {
      1,
      TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA,
      TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA,
      SSL_kSRP,
      SSL_aSRP,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C021 */
     {
      1,
      TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
      TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA,
      SSL_kSRP,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 
     /* Cipher C022 */
     {
      1,
      TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
      TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,
      SSL_kSRP,
      SSL_aDSS,
      SSL_AES256,
      SSL_SHA1,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
 #endif                          /* OPENSSL_NO_SRP */
 #ifndef OPENSSL_NO_ECDH
 
     /* HMAC based TLS v1.2 ciphersuites from RFC5289 */
 
     /* Cipher C023 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C024 */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES256,
      SSL_SHA384,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C025 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256,
      TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C026 */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384,
      TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES256,
      SSL_SHA384,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C027 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256,
      TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C028 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384,
      TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES256,
      SSL_SHA384,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C029 */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256,
      TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES128,
      SSL_SHA256,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C02A */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384,
      TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES256,
      SSL_SHA384,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* GCM based TLS v1.2 ciphersuites from RFC5289 */
 
     /* Cipher C02B */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C02C */
     {
      1,
      TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
      SSL_kEECDH,
      SSL_aECDSA,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C02D */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C02E */
     {
      1,
      TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384,
      SSL_kECDHe,
      SSL_aECDH,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C02F */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C030 */
     {
      1,
      TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
      SSL_kEECDH,
      SSL_aRSA,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
     /* Cipher C031 */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256,
      TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES128GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256,
      128,
      128,
      },
 
     /* Cipher C032 */
     {
      1,
      TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384,
      TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384,
      SSL_kECDHr,
      SSL_aECDH,
      SSL_AES256GCM,
      SSL_AEAD,
      SSL_TLSV1_2,
      SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
      SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384,
      256,
      256,
      },
 
 #endif                          /* OPENSSL_NO_ECDH */
 
 #ifdef TEMP_GOST_TLS
 /* Cipher FF00 */
     {
      1,
      "GOST-MD5",
      0x0300ff00,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eGOST2814789CNT,
      SSL_MD5,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256,
      },
     {
      1,
      "GOST-GOST94",
      0x0300ff01,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eGOST2814789CNT,
      SSL_GOST94,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256},
     {
      1,
      "GOST-GOST89MAC",
      0x0300ff02,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eGOST2814789CNT,
      SSL_GOST89MAC,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
      256,
      256},
     {
      1,
      "GOST-GOST89STREAM",
      0x0300ff03,
      SSL_kRSA,
      SSL_aRSA,
      SSL_eGOST2814789CNT,
      SSL_GOST89MAC,
      SSL_TLSV1,
      SSL_NOT_EXP | SSL_HIGH,
      SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF | TLS1_STREAM_MAC,
      256,
      256},
 #endif
 
 /* end of list */
 };
 
 SSL3_ENC_METHOD SSLv3_enc_data = {
     ssl3_enc,
     n_ssl3_mac,
     ssl3_setup_key_block,
     ssl3_generate_master_secret,
     ssl3_change_cipher_state,
     ssl3_final_finish_mac,
     MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
     ssl3_cert_verify_mac,
     SSL3_MD_CLIENT_FINISHED_CONST, 4,
     SSL3_MD_SERVER_FINISHED_CONST, 4,
     ssl3_alert_code,
     (int (*)(SSL *, unsigned char *, size_t, const char *,
              size_t, const unsigned char *, size_t,
              int use_context))ssl_undefined_function,
 };
 
 long ssl3_default_timeout(void)
 {
     /*
      * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for
      * http, the cache would over fill
      */
     return (60 * 60 * 2);
 }
 
 int ssl3_num_ciphers(void)
 {
     return (SSL3_NUM_CIPHERS);
 }
 
 const SSL_CIPHER *ssl3_get_cipher(unsigned int u)
 {
     if (u < SSL3_NUM_CIPHERS)
         return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u]));
     else
         return (NULL);
 }
 
 int ssl3_pending(const SSL *s)
 {
     if (s->rstate == SSL_ST_READ_BODY)
         return 0;
 
     return (s->s3->rrec.type ==
             SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0;
 }
 
 int ssl3_new(SSL *s)
 {
     SSL3_STATE *s3;
 
     if ((s3 = OPENSSL_malloc(sizeof *s3)) == NULL)
         goto err;
     memset(s3, 0, sizeof *s3);
     memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num));
     memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num));
 
     s->s3 = s3;
 
 #ifndef OPENSSL_NO_SRP
     SSL_SRP_CTX_init(s);
 #endif
     s->method->ssl_clear(s);
     return (1);
  err:
     return (0);
 }
 
 void ssl3_free(SSL *s)
 {
     if (s == NULL || s->s3 == NULL)
         return;
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
     if (s->s3->client_opaque_prf_input != NULL)
         OPENSSL_free(s->s3->client_opaque_prf_input);
     if (s->s3->server_opaque_prf_input != NULL)
         OPENSSL_free(s->s3->server_opaque_prf_input);
 #endif
 
     ssl3_cleanup_key_block(s);
     if (s->s3->rbuf.buf != NULL)
         ssl3_release_read_buffer(s);
     if (s->s3->wbuf.buf != NULL)
         ssl3_release_write_buffer(s);
     if (s->s3->rrec.comp != NULL)
         OPENSSL_free(s->s3->rrec.comp);
 #ifndef OPENSSL_NO_DH
     if (s->s3->tmp.dh != NULL)
         DH_free(s->s3->tmp.dh);
 #endif
 #ifndef OPENSSL_NO_ECDH
     if (s->s3->tmp.ecdh != NULL)
         EC_KEY_free(s->s3->tmp.ecdh);
 #endif
 
     if (s->s3->tmp.ca_names != NULL)
         sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
     if (s->s3->handshake_buffer) {
         BIO_free(s->s3->handshake_buffer);
     }
     if (s->s3->handshake_dgst)
         ssl3_free_digest_list(s);
 #ifndef OPENSSL_NO_SRP
     SSL_SRP_CTX_free(s);
 #endif
     OPENSSL_cleanse(s->s3, sizeof *s->s3);
     OPENSSL_free(s->s3);
     s->s3 = NULL;
 }
 
 void ssl3_clear(SSL *s)
 {
     unsigned char *rp, *wp;
     size_t rlen, wlen;
     int init_extra;
 
 #ifdef TLSEXT_TYPE_opaque_prf_input
     if (s->s3->client_opaque_prf_input != NULL)
         OPENSSL_free(s->s3->client_opaque_prf_input);
     s->s3->client_opaque_prf_input = NULL;
     if (s->s3->server_opaque_prf_input != NULL)
         OPENSSL_free(s->s3->server_opaque_prf_input);
     s->s3->server_opaque_prf_input = NULL;
 #endif
 
     ssl3_cleanup_key_block(s);
     if (s->s3->tmp.ca_names != NULL)
         sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
 
     if (s->s3->rrec.comp != NULL) {
         OPENSSL_free(s->s3->rrec.comp);
         s->s3->rrec.comp = NULL;
     }
 #ifndef OPENSSL_NO_DH
     if (s->s3->tmp.dh != NULL) {
         DH_free(s->s3->tmp.dh);
         s->s3->tmp.dh = NULL;
     }
 #endif
 #ifndef OPENSSL_NO_ECDH
     if (s->s3->tmp.ecdh != NULL) {
         EC_KEY_free(s->s3->tmp.ecdh);
         s->s3->tmp.ecdh = NULL;
     }
 #endif
 #ifndef OPENSSL_NO_TLSEXT
 # ifndef OPENSSL_NO_EC
     s->s3->is_probably_safari = 0;
 # endif                         /* !OPENSSL_NO_EC */
 #endif                          /* !OPENSSL_NO_TLSEXT */
 
     rp = s->s3->rbuf.buf;
     wp = s->s3->wbuf.buf;
     rlen = s->s3->rbuf.len;
     wlen = s->s3->wbuf.len;
     init_extra = s->s3->init_extra;
     if (s->s3->handshake_buffer) {
         BIO_free(s->s3->handshake_buffer);
         s->s3->handshake_buffer = NULL;
     }
     if (s->s3->handshake_dgst) {
         ssl3_free_digest_list(s);
     }
     memset(s->s3, 0, sizeof *s->s3);
     s->s3->rbuf.buf = rp;
     s->s3->wbuf.buf = wp;
     s->s3->rbuf.len = rlen;
     s->s3->wbuf.len = wlen;
     s->s3->init_extra = init_extra;
 
     ssl_free_wbio_buffer(s);
 
     s->packet_length = 0;
     s->s3->renegotiate = 0;
     s->s3->total_renegotiations = 0;
     s->s3->num_renegotiations = 0;
     s->s3->in_read_app_data = 0;
     s->version = SSL3_VERSION;
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     if (s->next_proto_negotiated) {
         OPENSSL_free(s->next_proto_negotiated);
         s->next_proto_negotiated = NULL;
         s->next_proto_negotiated_len = 0;
     }
 #endif
 }
 
 #ifndef OPENSSL_NO_SRP
 static char *MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg)
 {
     return BUF_strdup(s->srp_ctx.info);
 }
 #endif
 
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
     int ret = 0;
 
 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
     if (
 # ifndef OPENSSL_NO_RSA
            cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB ||
 # endif
 # ifndef OPENSSL_NO_DSA
            cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB ||
 # endif
            0) {
         if (!ssl_cert_inst(&s->cert)) {
             SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE);
             return (0);
         }
     }
 #endif
 
     switch (cmd) {
     case SSL_CTRL_GET_SESSION_REUSED:
         ret = s->hit;
         break;
     case SSL_CTRL_GET_CLIENT_CERT_REQUEST:
         break;
     case SSL_CTRL_GET_NUM_RENEGOTIATIONS:
         ret = s->s3->num_renegotiations;
         break;
     case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS:
         ret = s->s3->num_renegotiations;
         s->s3->num_renegotiations = 0;
         break;
     case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS:
         ret = s->s3->total_renegotiations;
         break;
     case SSL_CTRL_GET_FLAGS:
         ret = (int)(s->s3->flags);
         break;
 #ifndef OPENSSL_NO_RSA
     case SSL_CTRL_NEED_TMP_RSA:
         if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) &&
             ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
              (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) >
               (512 / 8))))
             ret = 1;
         break;
     case SSL_CTRL_SET_TMP_RSA:
         {
             RSA *rsa = (RSA *)parg;
             if (rsa == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
                 return (ret);
             }
             if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB);
                 return (ret);
             }
             if (s->cert->rsa_tmp != NULL)
                 RSA_free(s->cert->rsa_tmp);
             s->cert->rsa_tmp = rsa;
             ret = 1;
         }
         break;
     case SSL_CTRL_SET_TMP_RSA_CB:
         {
             SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (ret);
         }
         break;
 #endif
 #ifndef OPENSSL_NO_DH
     case SSL_CTRL_SET_TMP_DH:
         {
             DH *dh = (DH *)parg;
             if (dh == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
                 return (ret);
             }
             if ((dh = DHparams_dup(dh)) == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB);
                 return (ret);
             }
             if (s->cert->dh_tmp != NULL)
                 DH_free(s->cert->dh_tmp);
             s->cert->dh_tmp = dh;
             ret = 1;
         }
         break;
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (ret);
         }
         break;
 #endif
 #ifndef OPENSSL_NO_ECDH
     case SSL_CTRL_SET_TMP_ECDH:
         {
             EC_KEY *ecdh = NULL;
 
             if (parg == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER);
                 return (ret);
             }
             if (!EC_KEY_up_ref((EC_KEY *)parg)) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB);
                 return (ret);
             }
             ecdh = (EC_KEY *)parg;
             if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) {
                 if (!EC_KEY_generate_key(ecdh)) {
                     EC_KEY_free(ecdh);
                     SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB);
                     return (ret);
                 }
             }
             if (s->cert->ecdh_tmp != NULL)
                 EC_KEY_free(s->cert->ecdh_tmp);
             s->cert->ecdh_tmp = ecdh;
             ret = 1;
         }
         break;
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (ret);
         }
         break;
 #endif                          /* !OPENSSL_NO_ECDH */
 #ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_HOSTNAME:
         if (larg == TLSEXT_NAMETYPE_host_name) {
             size_t len;
 
             if (s->tlsext_hostname != NULL)
                 OPENSSL_free(s->tlsext_hostname);
             s->tlsext_hostname = NULL;
 
             ret = 1;
             if (parg == NULL)
                 break;
             len = strlen((char *)parg);
             if (len == 0 || len > TLSEXT_MAXLEN_host_name) {
                 SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
                 return 0;
             }
             if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) {
                 SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR);
                 return 0;
             }
         } else {
             SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE);
             return 0;
         }
         break;
     case SSL_CTRL_SET_TLSEXT_DEBUG_ARG:
         s->tlsext_debug_arg = parg;
         ret = 1;
         break;
 
 # ifdef TLSEXT_TYPE_opaque_prf_input
     case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT:
         if (larg > 12288) {     /* actual internal limit is 2^16 for the
                                  * complete hello message * (including the
                                  * cert chain and everything) */
             SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG);
             break;
         }
         if (s->tlsext_opaque_prf_input != NULL)
             OPENSSL_free(s->tlsext_opaque_prf_input);
         if ((size_t)larg == 0)
             s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte
                                                              * just to get
                                                              * non-NULL */
         else
             s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg);
         if (s->tlsext_opaque_prf_input != NULL) {
             s->tlsext_opaque_prf_input_len = (size_t)larg;
             ret = 1;
         } else
             s->tlsext_opaque_prf_input_len = 0;
         break;
 # endif
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE:
         s->tlsext_status_type = larg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS:
         *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts;
         ret = 1;
         break;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS:
         s->tlsext_ocsp_exts = parg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS:
         *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids;
         ret = 1;
         break;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS:
         s->tlsext_ocsp_ids = parg;
         ret = 1;
         break;
 
     case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP:
         *(unsigned char **)parg = s->tlsext_ocsp_resp;
         return s->tlsext_ocsp_resplen;
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP:
         if (s->tlsext_ocsp_resp)
             OPENSSL_free(s->tlsext_ocsp_resp);
         s->tlsext_ocsp_resp = parg;
         s->tlsext_ocsp_resplen = larg;
         ret = 1;
         break;
 
 # ifndef OPENSSL_NO_HEARTBEATS
     case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT:
         if (SSL_version(s) == DTLS1_VERSION
             || SSL_version(s) == DTLS1_BAD_VER)
             ret = dtls1_heartbeat(s);
         else
             ret = tls1_heartbeat(s);
         break;
 
     case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING:
         ret = s->tlsext_hb_pending;
         break;
 
     case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS:
         if (larg)
             s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
         else
             s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS;
         ret = 1;
         break;
 # endif
 
 #endif                          /* !OPENSSL_NO_TLSEXT */
 
     case SSL_CTRL_CHECK_PROTO_VERSION:
         /*
          * For library-internal use; checks that the current protocol is the
          * highest enabled version (according to s->ctx->method, as version
          * negotiation may have changed s->method).
          */
         if (s->version == s->ctx->method->version)
             return 1;
         /*
          * Apparently we're using a version-flexible SSL_METHOD (not at its
          * highest protocol version).
          */
         if (s->ctx->method->version == SSLv23_method()->version) {
 #if TLS_MAX_VERSION != TLS1_2_VERSION
 # error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
 #endif
             if (!(s->options & SSL_OP_NO_TLSv1_2))
                 return s->version == TLS1_2_VERSION;
             if (!(s->options & SSL_OP_NO_TLSv1_1))
                 return s->version == TLS1_1_VERSION;
             if (!(s->options & SSL_OP_NO_TLSv1))
                 return s->version == TLS1_VERSION;
             if (!(s->options & SSL_OP_NO_SSLv3))
                 return s->version == SSL3_VERSION;
             if (!(s->options & SSL_OP_NO_SSLv2))
                 return s->version == SSL2_VERSION;
         }
         return 0;               /* Unexpected state; fail closed. */
 
     default:
         break;
     }
     return (ret);
 }
 
 long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
 {
     int ret = 0;
 
 #if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA)
     if (
 # ifndef OPENSSL_NO_RSA
            cmd == SSL_CTRL_SET_TMP_RSA_CB ||
 # endif
 # ifndef OPENSSL_NO_DSA
            cmd == SSL_CTRL_SET_TMP_DH_CB ||
 # endif
            0) {
         if (!ssl_cert_inst(&s->cert)) {
             SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE);
             return (0);
         }
     }
 #endif
 
     switch (cmd) {
 #ifndef OPENSSL_NO_RSA
     case SSL_CTRL_SET_TMP_RSA_CB:
         {
             s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_DH
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_ECDH
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_DEBUG_CB:
         s->tlsext_debug_cb = (void (*)(SSL *, int, int,
                                        unsigned char *, int, void *))fp;
         break;
 #endif
     default:
         break;
     }
     return (ret);
 }
 
 long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
 {
     CERT *cert;
 
     cert = ctx->cert;
 
     switch (cmd) {
 #ifndef OPENSSL_NO_RSA
     case SSL_CTRL_NEED_TMP_RSA:
         if ((cert->rsa_tmp == NULL) &&
             ((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) ||
              (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) >
               (512 / 8)))
             )
             return (1);
         else
             return (0);
         /* break; */
     case SSL_CTRL_SET_TMP_RSA:
         {
             RSA *rsa;
             int i;
 
             rsa = (RSA *)parg;
             i = 1;
             if (rsa == NULL)
                 i = 0;
             else {
                 if ((rsa = RSAPrivateKey_dup(rsa)) == NULL)
                     i = 0;
             }
             if (!i) {
                 SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB);
                 return (0);
             } else {
                 if (cert->rsa_tmp != NULL)
                     RSA_free(cert->rsa_tmp);
                 cert->rsa_tmp = rsa;
                 return (1);
             }
         }
         /* break; */
     case SSL_CTRL_SET_TMP_RSA_CB:
         {
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (0);
         }
         break;
 #endif
 #ifndef OPENSSL_NO_DH
     case SSL_CTRL_SET_TMP_DH:
         {
             DH *new = NULL, *dh;
 
             dh = (DH *)parg;
             if ((new = DHparams_dup(dh)) == NULL) {
                 SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB);
                 return 0;
             }
             if (cert->dh_tmp != NULL)
                 DH_free(cert->dh_tmp);
             cert->dh_tmp = new;
             return 1;
         }
         /*
          * break;
          */
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (0);
         }
         break;
 #endif
 #ifndef OPENSSL_NO_ECDH
     case SSL_CTRL_SET_TMP_ECDH:
         {
             EC_KEY *ecdh = NULL;
 
             if (parg == NULL) {
                 SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB);
                 return 0;
             }
             ecdh = EC_KEY_dup((EC_KEY *)parg);
             if (ecdh == NULL) {
                 SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_EC_LIB);
                 return 0;
             }
             if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) {
                 if (!EC_KEY_generate_key(ecdh)) {
                     EC_KEY_free(ecdh);
                     SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB);
                     return 0;
                 }
             }
 
             if (cert->ecdh_tmp != NULL) {
                 EC_KEY_free(cert->ecdh_tmp);
             }
             cert->ecdh_tmp = ecdh;
             return 1;
         }
         /* break; */
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
             return (0);
         }
         break;
 #endif                          /* !OPENSSL_NO_ECDH */
 #ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG:
         ctx->tlsext_servername_arg = parg;
         break;
     case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
     case SSL_CTRL_GET_TLSEXT_TICKET_KEYS:
         {
             unsigned char *keys = parg;
             if (!keys)
                 return 48;
             if (larg != 48) {
                 SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
                 return 0;
             }
             if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) {
                 memcpy(ctx->tlsext_tick_key_name, keys, 16);
                 memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16);
                 memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16);
             } else {
                 memcpy(keys, ctx->tlsext_tick_key_name, 16);
                 memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16);
                 memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16);
             }
             return 1;
         }
 
 # ifdef TLSEXT_TYPE_opaque_prf_input
     case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG:
         ctx->tlsext_opaque_prf_input_callback_arg = parg;
         return 1;
 # endif
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG:
         ctx->tlsext_status_arg = parg;
         return 1;
         break;
 
 # ifndef OPENSSL_NO_SRP
     case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         if (ctx->srp_ctx.login != NULL)
             OPENSSL_free(ctx->srp_ctx.login);
         ctx->srp_ctx.login = NULL;
         if (parg == NULL)
             break;
         if (strlen((const char *)parg) > 255
             || strlen((const char *)parg) < 1) {
             SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME);
             return 0;
         }
         if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) {
             SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR);
             return 0;
         }
         break;
     case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD:
         ctx->srp_ctx.SRP_give_srp_client_pwd_callback =
             srp_password_from_info_cb;
         ctx->srp_ctx.info = parg;
         break;
     case SSL_CTRL_SET_SRP_ARG:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         ctx->srp_ctx.SRP_cb_arg = parg;
         break;
 
     case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH:
         ctx->srp_ctx.strength = larg;
         break;
 # endif
 #endif                          /* !OPENSSL_NO_TLSEXT */
 
         /* A Thawte special :-) */
     case SSL_CTRL_EXTRA_CHAIN_CERT:
         if (ctx->extra_certs == NULL) {
             if ((ctx->extra_certs = sk_X509_new_null()) == NULL)
                 return (0);
         }
         sk_X509_push(ctx->extra_certs, (X509 *)parg);
         break;
 
     case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
         *(STACK_OF(X509) **)parg = ctx->extra_certs;
         break;
 
     case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
         if (ctx->extra_certs) {
             sk_X509_pop_free(ctx->extra_certs, X509_free);
             ctx->extra_certs = NULL;
         }
         break;
 
     default:
         return (0);
     }
     return (1);
 }
 
 long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
 {
     CERT *cert;
 
     cert = ctx->cert;
 
     switch (cmd) {
 #ifndef OPENSSL_NO_RSA
     case SSL_CTRL_SET_TMP_RSA_CB:
         {
             cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_DH
     case SSL_CTRL_SET_TMP_DH_CB:
         {
             cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_ECDH
     case SSL_CTRL_SET_TMP_ECDH_CB:
         {
             cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp;
         }
         break;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
     case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB:
         ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp;
         break;
 
 # ifdef TLSEXT_TYPE_opaque_prf_input
     case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB:
         ctx->tlsext_opaque_prf_input_callback =
             (int (*)(SSL *, void *, size_t, void *))fp;
         break;
 # endif
 
     case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB:
         ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp;
         break;
 
     case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB:
         ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *,
                                              unsigned char *,
                                              EVP_CIPHER_CTX *,
                                              HMAC_CTX *, int))fp;
         break;
 
 # ifndef OPENSSL_NO_SRP
     case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp;
         break;
     case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         ctx->srp_ctx.TLS_ext_srp_username_callback =
             (int (*)(SSL *, int *, void *))fp;
         break;
     case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB:
         ctx->srp_ctx.srp_Mask |= SSL_kSRP;
         ctx->srp_ctx.SRP_give_srp_client_pwd_callback =
             (char *(*)(SSL *, void *))fp;
         break;
 # endif
 #endif
 
     default:
         return (0);
     }
     return (1);
 }
 
 /*
  * This function needs to check if the ciphers required are actually
  * available
  */
 const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p)
 {
     SSL_CIPHER c;
     const SSL_CIPHER *cp;
     unsigned long id;
 
     id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1];
     c.id = id;
     cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS);
 #ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES
     if (cp == NULL)
         fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]);
 #endif
     if (cp == NULL || cp->valid == 0)
         return NULL;
     else
         return cp;
 }
 
 int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p)
 {
     long l;
 
     if (p != NULL) {
         l = c->id;
         if ((l & 0xff000000) != 0x03000000)
             return (0);
         p[0] = ((unsigned char)(l >> 8L)) & 0xFF;
         p[1] = ((unsigned char)(l)) & 0xFF;
     }
     return (2);
 }
 
 SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
                                STACK_OF(SSL_CIPHER) *srvr)
 {
     SSL_CIPHER *c, *ret = NULL;
     STACK_OF(SSL_CIPHER) *prio, *allow;
     int i, ii, ok;
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC)
     unsigned int j;
     int ec_ok, ec_nid;
     unsigned char ec_search1 = 0, ec_search2 = 0;
 #endif
     CERT *cert;
     unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a;
 
     /* Let's see which ciphers we can support */
     cert = s->cert;
 
 #if 0
     /*
      * Do not set the compare functions, because this may lead to a
      * reordering by "id". We want to keep the original ordering. We may pay
      * a price in performance during sk_SSL_CIPHER_find(), but would have to
      * pay with the price of sk_SSL_CIPHER_dup().
      */
     sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp);
     sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp);
 #endif
 
 #ifdef CIPHER_DEBUG
     fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr),
             (void *)srvr);
     for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) {
         c = sk_SSL_CIPHER_value(srvr, i);
         fprintf(stderr, "%p:%s\n", (void *)c, c->name);
     }
     fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt),
             (void *)clnt);
     for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) {
         c = sk_SSL_CIPHER_value(clnt, i);
         fprintf(stderr, "%p:%s\n", (void *)c, c->name);
     }
 #endif
 
     if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
         prio = srvr;
         allow = clnt;
     } else {
         prio = clnt;
         allow = srvr;
     }
 
     for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) {
         c = sk_SSL_CIPHER_value(prio, i);
 
         /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
         if ((c->algorithm_ssl & SSL_TLSV1_2) &&
             (TLS1_get_version(s) < TLS1_2_VERSION))
             continue;
 
         ssl_set_cert_masks(cert, c);
         mask_k = cert->mask_k;
         mask_a = cert->mask_a;
         emask_k = cert->export_mask_k;
         emask_a = cert->export_mask_a;
 #ifndef OPENSSL_NO_SRP
         if (s->srp_ctx.srp_Mask & SSL_kSRP) {
             mask_k |= SSL_kSRP;
             emask_k |= SSL_kSRP;
             mask_a |= SSL_aSRP;
             emask_a |= SSL_aSRP;
         }
 #endif
 
 #ifdef KSSL_DEBUG
         /*
          * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n",
          * i,c->algorithms);
          */
 #endif                          /* KSSL_DEBUG */
 
         alg_k = c->algorithm_mkey;
         alg_a = c->algorithm_auth;
 
 #ifndef OPENSSL_NO_KRB5
         if (alg_k & SSL_kKRB5) {
             if (!kssl_keytab_is_available(s->kssl_ctx))
                 continue;
         }
 #endif                          /* OPENSSL_NO_KRB5 */
 #ifndef OPENSSL_NO_PSK
         /* with PSK there must be server callback set */
         if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL)
             continue;
 #endif                          /* OPENSSL_NO_PSK */
 
         if (SSL_C_IS_EXPORT(c)) {
             ok = (alg_k & emask_k) && (alg_a & emask_a);
 #ifdef CIPHER_DEBUG
             fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n",
                     ok, alg_k, alg_a, emask_k, emask_a, (void *)c, c->name);
 #endif
         } else {
             ok = (alg_k & mask_k) && (alg_a & mask_a);
 #ifdef CIPHER_DEBUG
             fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k,
                     alg_a, mask_k, mask_a, (void *)c, c->name);
 #endif
         }
 
 #ifndef OPENSSL_NO_TLSEXT
 # ifndef OPENSSL_NO_EC
         if (
                /*
                 * if we are considering an ECC cipher suite that uses our
                 * certificate
                 */
                (alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
                /* and we have an ECC certificate */
                && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
                /*
                 * and the client specified a Supported Point Formats
                 * extension
                 */
                && ((s->session->tlsext_ecpointformatlist_length > 0)
                    && (s->session->tlsext_ecpointformatlist != NULL))
                /* and our certificate's point is compressed */
                && ((s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL)
                    && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key !=
                        NULL)
                    && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->
                        key->public_key != NULL)
                    && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->
                        key->public_key->data != NULL)
                    &&
                    ((*
                      (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->
                       key->public_key->data) == POINT_CONVERSION_COMPRESSED)
                     ||
                     (*
                      (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->
                       key->public_key->data) ==
                      POINT_CONVERSION_COMPRESSED + 1)
                    )
                )
             ) {
             ec_ok = 0;
             /*
              * if our certificate's curve is over a field type that the
              * client does not support then do not allow this cipher suite to
              * be negotiated
              */
             if ((s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
                 && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group !=
                     NULL)
                 && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->
                     group->meth != NULL)
                 &&
                 (EC_METHOD_get_field_type
                  (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->
                   group->meth) == NID_X9_62_prime_field)
                 ) {
                 for (j = 0; j < s->session->tlsext_ecpointformatlist_length;
                      j++) {
                     if (s->session->tlsext_ecpointformatlist[j] ==
                         TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) {
                         ec_ok = 1;
                         break;
                     }
                 }
             } else
                 if (EC_METHOD_get_field_type
                     (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->
                      group->meth) == NID_X9_62_characteristic_two_field) {
                 for (j = 0; j < s->session->tlsext_ecpointformatlist_length;
                      j++) {
                     if (s->session->tlsext_ecpointformatlist[j] ==
                         TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) {
                         ec_ok = 1;
                         break;
                     }
                 }
             }
             ok = ok && ec_ok;
         }
         if (
                /*
                 * if we are considering an ECC cipher suite that uses our
                 * certificate
                 */
                (alg_a & SSL_aECDSA || alg_a & SSL_aECDH)
                /* and we have an ECC certificate */
                && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL)
                /*
                 * and the client specified an EllipticCurves extension
                 */
                && ((s->session->tlsext_ellipticcurvelist_length > 0)
                    && (s->session->tlsext_ellipticcurvelist != NULL))
             ) {
             ec_ok = 0;
             if ((s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL)
                 && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group !=
                     NULL)
                 ) {
                 ec_nid =
                     EC_GROUP_get_curve_name(s->cert->
                                             pkeys[SSL_PKEY_ECC].privatekey->
                                             pkey.ec->group);
                 if ((ec_nid == 0)
                     && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.
                         ec->group->meth != NULL)
                     ) {
                     if (EC_METHOD_get_field_type
                         (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.
                          ec->group->meth) == NID_X9_62_prime_field) {
                         ec_search1 = 0xFF;
                         ec_search2 = 0x01;
                     } else
                         if (EC_METHOD_get_field_type
                             (s->cert->pkeys[SSL_PKEY_ECC].privatekey->
                              pkey.ec->group->meth) ==
                             NID_X9_62_characteristic_two_field) {
                         ec_search1 = 0xFF;
                         ec_search2 = 0x02;
                     }
                 } else {
                     ec_search1 = 0x00;
                     ec_search2 = tls1_ec_nid2curve_id(ec_nid);
                 }
                 if ((ec_search1 != 0) || (ec_search2 != 0)) {
                     for (j = 0;
                          j < s->session->tlsext_ellipticcurvelist_length / 2;
                          j++) {
                         if ((s->session->tlsext_ellipticcurvelist[2 * j] ==
                              ec_search1)
                             && (s->session->tlsext_ellipticcurvelist[2 * j +
                                                                      1] ==
                                 ec_search2)) {
                             ec_ok = 1;
                             break;
                         }
                     }
                 }
             }
             ok = ok && ec_ok;
         }
 #  ifndef OPENSSL_NO_ECDH
         if (
                /*
                 * if we are considering an ECC cipher suite that uses an
                 * ephemeral EC key
                 */
                (alg_k & SSL_kEECDH)
                /* and we have an ephemeral EC key */
                && (s->cert->ecdh_tmp != NULL)
                /*
                 * and the client specified an EllipticCurves extension
                 */
                && ((s->session->tlsext_ellipticcurvelist_length > 0)
                    && (s->session->tlsext_ellipticcurvelist != NULL))
             ) {
             ec_ok = 0;
             if (s->cert->ecdh_tmp->group != NULL) {
                 ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group);
                 if ((ec_nid == 0)
                     && (s->cert->ecdh_tmp->group->meth != NULL)
                     ) {
                     if (EC_METHOD_get_field_type
                         (s->cert->ecdh_tmp->group->meth) ==
                         NID_X9_62_prime_field) {
                         ec_search1 = 0xFF;
                         ec_search2 = 0x01;
                     } else
                         if (EC_METHOD_get_field_type
                             (s->cert->ecdh_tmp->group->meth) ==
                             NID_X9_62_characteristic_two_field) {
                         ec_search1 = 0xFF;
                         ec_search2 = 0x02;
                     }
                 } else {
                     ec_search1 = 0x00;
                     ec_search2 = tls1_ec_nid2curve_id(ec_nid);
                 }
                 if ((ec_search1 != 0) || (ec_search2 != 0)) {
                     for (j = 0;
                          j < s->session->tlsext_ellipticcurvelist_length / 2;
                          j++) {
                         if ((s->session->tlsext_ellipticcurvelist[2 * j] ==
                              ec_search1)
                             && (s->session->tlsext_ellipticcurvelist[2 * j +
                                                                      1] ==
                                 ec_search2)) {
                             ec_ok = 1;
                             break;
                         }
                     }
                 }
             }
             ok = ok && ec_ok;
         }
 #  endif                        /* OPENSSL_NO_ECDH */
 # endif                         /* OPENSSL_NO_EC */
 #endif                          /* OPENSSL_NO_TLSEXT */
 
         if (!ok)
             continue;
         ii = sk_SSL_CIPHER_find(allow, c);
         if (ii >= 0) {
 #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT)
             if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA)
                 && s->s3->is_probably_safari) {
                 if (!ret)
                     ret = sk_SSL_CIPHER_value(allow, ii);
                 continue;
             }
 #endif
             ret = sk_SSL_CIPHER_value(allow, ii);
             break;
         }
     }
     return (ret);
 }
 
 int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
 {
     int ret = 0;
     unsigned long alg_k;
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_GOST
     if (s->version >= TLS1_VERSION) {
         if (alg_k & SSL_kGOST) {
             p[ret++] = TLS_CT_GOST94_SIGN;
             p[ret++] = TLS_CT_GOST01_SIGN;
             return (ret);
         }
     }
 #endif
 
 #ifndef OPENSSL_NO_DH
     if (alg_k & (SSL_kDHr | SSL_kEDH)) {
 # ifndef OPENSSL_NO_RSA
         p[ret++] = SSL3_CT_RSA_FIXED_DH;
 # endif
 # ifndef OPENSSL_NO_DSA
         p[ret++] = SSL3_CT_DSS_FIXED_DH;
 # endif
     }
     if ((s->version == SSL3_VERSION) &&
         (alg_k & (SSL_kEDH | SSL_kDHd | SSL_kDHr))) {
 # ifndef OPENSSL_NO_RSA
         p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH;
 # endif
 # ifndef OPENSSL_NO_DSA
         p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH;
 # endif
     }
 #endif                          /* !OPENSSL_NO_DH */
 #ifndef OPENSSL_NO_RSA
     p[ret++] = SSL3_CT_RSA_SIGN;
 #endif
 #ifndef OPENSSL_NO_DSA
     p[ret++] = SSL3_CT_DSS_SIGN;
 #endif
 #ifndef OPENSSL_NO_ECDH
     if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) {
         p[ret++] = TLS_CT_RSA_FIXED_ECDH;
         p[ret++] = TLS_CT_ECDSA_FIXED_ECDH;
     }
 #endif
 
 #ifndef OPENSSL_NO_ECDSA
     /*
      * ECDSA certs can be used with RSA cipher suites as well so we don't
      * need to check for SSL_kECDH or SSL_kEECDH
      */
     if (s->version >= TLS1_VERSION) {
         p[ret++] = TLS_CT_ECDSA_SIGN;
     }
 #endif
     return (ret);
 }
 
 int ssl3_shutdown(SSL *s)
 {
     int ret;
 
     /*
      * Don't do anything much if we have not done the handshake or we don't
      * want to send messages :-)
      */
     if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) {
         s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
         return (1);
     }
 
     if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
         s->shutdown |= SSL_SENT_SHUTDOWN;
 #if 1
         ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
 #endif
         /*
          * our shutdown alert has been sent now, and if it still needs to be
          * written, s->s3->alert_dispatch will be true
          */
         if (s->s3->alert_dispatch)
             return (-1);        /* return WANT_WRITE */
     } else if (s->s3->alert_dispatch) {
         /* resend it if not sent */
 #if 1
         ret = s->method->ssl_dispatch_alert(s);
         if (ret == -1) {
             /*
              * we only get to return -1 here the 2nd/Nth invocation, we must
              * have already signalled return 0 upon a previous invoation,
              * return WANT_WRITE
              */
             return (ret);
         }
 #endif
     } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
         /*
          * If we are waiting for a close from our peer, we are closed
          */
         s->method->ssl_read_bytes(s, 0, NULL, 0, 0);
         if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
             return (-1);        /* return WANT_READ */
         }
     }
 
     if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) &&
         !s->s3->alert_dispatch)
         return (1);
     else
         return (0);
 }
 
 int ssl3_write(SSL *s, const void *buf, int len)
 {
     int ret, n;
 
 #if 0
     if (s->shutdown & SSL_SEND_SHUTDOWN) {
         s->rwstate = SSL_NOTHING;
         return (0);
     }
 #endif
     clear_sys_error();
     if (s->s3->renegotiate)
         ssl3_renegotiate_check(s);
 
     /*
      * This is an experimental flag that sends the last handshake message in
      * the same packet as the first use data - used to see if it helps the
      * TCP protocol during session-id reuse
      */
     /* The second test is because the buffer may have been removed */
     if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) {
         /* First time through, we write into the buffer */
         if (s->s3->delay_buf_pop_ret == 0) {
             ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len);
             if (ret <= 0)
                 return (ret);
 
             s->s3->delay_buf_pop_ret = ret;
         }
 
         s->rwstate = SSL_WRITING;
         n = BIO_flush(s->wbio);
         if (n <= 0)
             return (n);
         s->rwstate = SSL_NOTHING;
 
         /* We have flushed the buffer, so remove it */
         ssl_free_wbio_buffer(s);
         s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER;
 
         ret = s->s3->delay_buf_pop_ret;
         s->s3->delay_buf_pop_ret = 0;
     } else {
         ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA,
                                          buf, len);
         if (ret <= 0)
             return (ret);
     }
 
     return (ret);
 }
 
 static int ssl3_read_internal(SSL *s, void *buf, int len, int peek)
 {
     int ret;
 
     clear_sys_error();
     if (s->s3->renegotiate)
         ssl3_renegotiate_check(s);
     s->s3->in_read_app_data = 1;
     ret =
         s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len,
                                   peek);
     if ((ret == -1) && (s->s3->in_read_app_data == 2)) {
         /*
          * ssl3_read_bytes decided to call s->handshake_func, which called
          * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes
          * actually found application data and thinks that application data
          * makes sense here; so disable handshake processing and try to read
          * application data again.
          */
         s->in_handshake++;
         ret =
             s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len,
                                       peek);
         s->in_handshake--;
     } else
         s->s3->in_read_app_data = 0;
 
     return (ret);
 }
 
 int ssl3_read(SSL *s, void *buf, int len)
 {
     return ssl3_read_internal(s, buf, len, 0);
 }
 
 int ssl3_peek(SSL *s, void *buf, int len)
 {
     return ssl3_read_internal(s, buf, len, 1);
 }
 
 int ssl3_renegotiate(SSL *s)
 {
     if (s->handshake_func == NULL)
         return (1);
 
     if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
         return (0);
 
     s->s3->renegotiate = 1;
     return (1);
 }
 
 int ssl3_renegotiate_check(SSL *s)
 {
     int ret = 0;
 
     if (s->s3->renegotiate) {
         if ((s->s3->rbuf.left == 0) &&
             (s->s3->wbuf.left == 0) && !SSL_in_init(s)) {
             /*
              * if we are the server, and we have sent a 'RENEGOTIATE'
              * message, we need to go to SSL_ST_ACCEPT.
              */
             /* SSL_ST_ACCEPT */
             s->state = SSL_ST_RENEGOTIATE;
             s->s3->renegotiate = 0;
             s->s3->num_renegotiations++;
             s->s3->total_renegotiations++;
             ret = 1;
         }
     }
     return (ret);
 }
 
 /*
  * If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch
  * to new SHA256 PRF and handshake macs
  */
 long ssl_get_algorithm2(SSL *s)
 {
     long alg2 = s->s3->tmp.new_cipher->algorithm2;
     if (s->method->version == TLS1_2_VERSION &&
         alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
         return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
     return alg2;
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/s3_srvr.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/s3_srvr.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/s3_srvr.c	(revision 306191)
@@ -1,3649 +1,3652 @@
 /* ssl/s3_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-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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  *
  * Portions of the attached software ("Contribution") are developed by
  * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
  *
  * The Contribution is licensed pursuant to the OpenSSL open source
  * license provided above.
  *
  * ECC cipher suite support in OpenSSL originally written by
  * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories.
  *
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #define REUSE_CIPHER_BUG
 #define NETSCAPE_HANG_BUG
 
 #include <stdio.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
 #include "../crypto/constant_time_locl.h"
 #include <openssl/buffer.h>
 #include <openssl/rand.h>
 #include <openssl/objects.h>
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 #include <openssl/x509.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 #include <openssl/bn.h>
 #ifndef OPENSSL_NO_KRB5
 # include <openssl/krb5_asn.h>
 #endif
 #include <openssl/md5.h>
 
 #ifndef OPENSSL_NO_SSL3_METHOD
 static const SSL_METHOD *ssl3_get_server_method(int ver);
 
 static const SSL_METHOD *ssl3_get_server_method(int ver)
 {
     if (ver == SSL3_VERSION)
         return (SSLv3_server_method());
     else
         return (NULL);
 }
 
 IMPLEMENT_ssl3_meth_func(SSLv3_server_method,
                          ssl3_accept,
                          ssl_undefined_function, ssl3_get_server_method)
 #endif
 #ifndef OPENSSL_NO_SRP
 static int ssl_check_srp_ext_ClientHello(SSL *s, int *al)
 {
     int ret = SSL_ERROR_NONE;
 
     *al = SSL_AD_UNRECOGNIZED_NAME;
 
     if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) &&
         (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) {
         if (s->srp_ctx.login == NULL) {
             /*
              * RFC 5054 says SHOULD reject, we do so if There is no srp
              * login name
              */
             ret = SSL3_AL_FATAL;
             *al = SSL_AD_UNKNOWN_PSK_IDENTITY;
         } else {
             ret = SSL_srp_server_param_with_username(s, al);
         }
     }
     return ret;
 }
 #endif
 
 int ssl3_accept(SSL *s)
 {
     BUF_MEM *buf;
     unsigned long alg_k, Time = (unsigned long)time(NULL);
     void (*cb) (const SSL *ssl, int type, int val) = NULL;
     int ret = -1;
     int new_state, state, skip = 0;
 
     RAND_add(&Time, sizeof(Time), 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_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET);
         return (-1);
     }
 #ifndef OPENSSL_NO_HEARTBEATS
     /*
      * If we're awaiting a HeartbeatResponse, pretend we already got and
      * don't await it anymore, because Heartbeats don't make sense during
      * handshakes anyway.
      */
     if (s->tlsext_hb_pending) {
         s->tlsext_hb_pending = 0;
         s->tlsext_hb_seq++;
     }
 #endif
 
     for (;;) {
         state = s->state;
 
         switch (s->state) {
         case SSL_ST_RENEGOTIATE:
             s->renegotiate = 1;
             /* s->state=SSL_ST_ACCEPT; */
 
         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);
 
             if ((s->version >> 8) != 3) {
                 SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
                 s->state = SSL_ST_ERR;
                 return -1;
             }
             s->type = SSL_ST_ACCEPT;
 
             if (s->init_buf == NULL) {
                 if ((buf = BUF_MEM_new()) == NULL) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) {
                     BUF_MEM_free(buf);
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
                 s->init_buf = buf;
             }
 
             if (!ssl3_setup_buffers(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             s->init_num = 0;
             s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
             s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
             /*
              * Should have been reset by ssl3_get_finished, too.
              */
             s->s3->change_cipher_spec = 0;
 
             if (s->state != SSL_ST_RENEGOTIATE) {
                 /*
                  * Ok, we now need to push on a buffering BIO so that the
                  * output is sent in a way that TCP likes :-)
                  */
                 if (!ssl_init_wbio_buffer(s, 1)) {
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
 
                 ssl3_init_finished_mac(s);
                 s->state = SSL3_ST_SR_CLNT_HELLO_A;
                 s->ctx->stats.sess_accept++;
             } else if (!s->s3->send_connection_binding &&
                        !(s->options &
                          SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
                 /*
                  * Server attempting to renegotiate with client that doesn't
                  * support secure renegotiation.
                  */
                 SSLerr(SSL_F_SSL3_ACCEPT,
                        SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             } else {
                 /*
                  * s->state == SSL_ST_RENEGOTIATE, we will just send a
                  * HelloRequest
                  */
                 s->ctx->stats.sess_accept_renegotiate++;
                 s->state = SSL3_ST_SW_HELLO_REQ_A;
             }
             break;
 
         case SSL3_ST_SW_HELLO_REQ_A:
         case SSL3_ST_SW_HELLO_REQ_B:
 
             s->shutdown = 0;
             ret = ssl3_send_hello_request(s);
             if (ret <= 0)
                 goto end;
             s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C;
             s->state = SSL3_ST_SW_FLUSH;
             s->init_num = 0;
 
             ssl3_init_finished_mac(s);
             break;
 
         case SSL3_ST_SW_HELLO_REQ_C:
             s->state = SSL_ST_OK;
             break;
 
         case SSL3_ST_SR_CLNT_HELLO_A:
         case SSL3_ST_SR_CLNT_HELLO_B:
         case SSL3_ST_SR_CLNT_HELLO_C:
 
             s->shutdown = 0;
             if (s->rwstate != SSL_X509_LOOKUP) {
                 ret = ssl3_get_client_hello(s);
                 if (ret <= 0)
                     goto end;
             }
 #ifndef OPENSSL_NO_SRP
             {
                 int al;
                 if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) {
                     /*
                      * callback indicates firther work to be done
                      */
                     s->rwstate = SSL_X509_LOOKUP;
                     goto end;
                 }
                 if (ret != SSL_ERROR_NONE) {
                     ssl3_send_alert(s, SSL3_AL_FATAL, al);
                     /*
                      * This is not really an error but the only means to for
                      * a client to detect whether srp is supported.
                      */
                     if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY)
                         SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT);
                     ret = -1;
                     s->state = SSL_ST_ERR;
                     goto end;
                 }
             }
 #endif
 
             s->renegotiate = 2;
             s->state = SSL3_ST_SW_SRVR_HELLO_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_SRVR_HELLO_A:
         case SSL3_ST_SW_SRVR_HELLO_B:
             ret = ssl3_send_server_hello(s);
             if (ret <= 0)
                 goto end;
 #ifndef OPENSSL_NO_TLSEXT
             if (s->hit) {
                 if (s->tlsext_ticket_expected)
                     s->state = SSL3_ST_SW_SESSION_TICKET_A;
                 else
                     s->state = SSL3_ST_SW_CHANGE_A;
             }
 #else
             if (s->hit)
                 s->state = SSL3_ST_SW_CHANGE_A;
 #endif
             else
                 s->state = SSL3_ST_SW_CERT_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_A:
         case SSL3_ST_SW_CERT_B:
             /* Check if it is anon DH or anon ECDH, */
             /* normal PSK or KRB5 or SRP */
             if (!
                 (s->s3->tmp.
                  new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 |
                                                SSL_aSRP))
 && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 ret = ssl3_send_server_certificate(s);
                 if (ret <= 0)
                     goto end;
 #ifndef OPENSSL_NO_TLSEXT
                 if (s->tlsext_status_expected)
                     s->state = SSL3_ST_SW_CERT_STATUS_A;
                 else
                     s->state = SSL3_ST_SW_KEY_EXCH_A;
             } else {
                 skip = 1;
                 s->state = SSL3_ST_SW_KEY_EXCH_A;
             }
 #else
             } else
                 skip = 1;
 
             s->state = SSL3_ST_SW_KEY_EXCH_A;
 #endif
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_KEY_EXCH_A:
         case SSL3_ST_SW_KEY_EXCH_B:
             alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
             /*
              * clear this, it may get reset by
              * send_server_key_exchange
              */
             s->s3->tmp.use_rsa_tmp = 0;
 
             /*
              * only send if a DH key exchange, fortezza or RSA but we have a
              * sign only certificate PSK: may send PSK identity hints For
              * ECC ciphersuites, we send a serverKeyExchange message only if
              * the cipher suite is either ECDH-anon or ECDHE. In other cases,
              * the server certificate contains the server's public key for
              * key exchange.
              */
             if (0
                 /*
                  * PSK: send ServerKeyExchange if PSK identity hint if
                  * provided
                  */
 #ifndef OPENSSL_NO_PSK
                 || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint)
 #endif
 #ifndef OPENSSL_NO_SRP
                 /* SRP: send ServerKeyExchange */
                 || (alg_k & SSL_kSRP)
 #endif
                 || (alg_k & (SSL_kDHr | SSL_kDHd | SSL_kEDH))
                 || (alg_k & SSL_kEECDH)
                 || ((alg_k & SSL_kRSA)
                     && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL
                         || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)
                             && EVP_PKEY_size(s->cert->pkeys
                                              [SSL_PKEY_RSA_ENC].privatekey) *
                             8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)
                         )
                     )
                 )
                 ) {
                 ret = ssl3_send_server_key_exchange(s);
                 if (ret <= 0)
                     goto end;
             } else
                 skip = 1;
 
             s->state = SSL3_ST_SW_CERT_REQ_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_REQ_A:
         case SSL3_ST_SW_CERT_REQ_B:
             if (                /* don't request cert unless asked for it: */
                    !(s->verify_mode & SSL_VERIFY_PEER) ||
                    /*
                     * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
                     * during re-negotiation:
                     */
                    ((s->session->peer != NULL) &&
                     (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
                    /*
                     * never request cert in anonymous ciphersuites (see
                     * section "Certificate request" in SSL 3 drafts and in
                     * RFC 2246):
                     */
                    ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) &&
                     /*
                      * ... except when the application insists on
                      * verification (against the specs, but s3_clnt.c accepts
                      * this for SSL 3)
                      */
                     !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) ||
                    /*
                     * never request cert in Kerberos ciphersuites
                     */
                    (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) ||
                    /* don't request certificate for SRP auth */
                    (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP)
                    /*
                     * With normal PSK Certificates and Certificate Requests
                     * are omitted
                     */
                    || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
                 /* no cert request */
                 skip = 1;
                 s->s3->tmp.cert_request = 0;
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
                 if (s->s3->handshake_buffer) {
                     if (!ssl3_digest_cached_records(s)) {
                         s->state = SSL_ST_ERR;
                         return -1;
                     }
                 }
             } else {
                 s->s3->tmp.cert_request = 1;
                 ret = ssl3_send_certificate_request(s);
                 if (ret <= 0)
                     goto end;
 #ifndef NETSCAPE_HANG_BUG
                 s->state = SSL3_ST_SW_SRVR_DONE_A;
 #else
                 s->state = SSL3_ST_SW_FLUSH;
                 s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
 #endif
                 s->init_num = 0;
             }
             break;
 
         case SSL3_ST_SW_SRVR_DONE_A:
         case SSL3_ST_SW_SRVR_DONE_B:
             ret = ssl3_send_server_done(s);
             if (ret <= 0)
                 goto end;
             s->s3->tmp.next_state = SSL3_ST_SR_CERT_A;
             s->state = SSL3_ST_SW_FLUSH;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_FLUSH:
 
             /*
              * This code originally checked to see if any data was pending
              * using BIO_CTRL_INFO and then flushed. This caused problems as
              * documented in PR#1939. The proposed fix doesn't completely
              * resolve this issue as buggy implementations of
              * BIO_CTRL_PENDING still exist. So instead we just flush
              * unconditionally.
              */
 
             s->rwstate = SSL_WRITING;
             if (BIO_flush(s->wbio) <= 0) {
                 ret = -1;
                 goto end;
             }
             s->rwstate = SSL_NOTHING;
 
             s->state = s->s3->tmp.next_state;
             break;
 
         case SSL3_ST_SR_CERT_A:
         case SSL3_ST_SR_CERT_B:
             /* Check for second client hello (MS SGC) */
             ret = ssl3_check_client_hello(s);
             if (ret <= 0)
                 goto end;
             if (ret == 2)
                 s->state = SSL3_ST_SR_CLNT_HELLO_C;
             else {
                 if (s->s3->tmp.cert_request) {
                     ret = ssl3_get_client_certificate(s);
                     if (ret <= 0)
                         goto end;
                 }
                 s->init_num = 0;
                 s->state = SSL3_ST_SR_KEY_EXCH_A;
             }
             break;
 
         case SSL3_ST_SR_KEY_EXCH_A:
         case SSL3_ST_SR_KEY_EXCH_B:
             ret = ssl3_get_client_key_exchange(s);
             if (ret <= 0)
                 goto end;
             if (ret == 2) {
                 /*
                  * For the ECDH ciphersuites when the client sends its ECDH
                  * pub key in a certificate, the CertificateVerify message is
                  * not sent. Also for GOST ciphersuites when the client uses
                  * its key from the certificate for key exchange.
                  */
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                 s->state = SSL3_ST_SR_FINISHED_A;
 #else
                 if (s->s3->next_proto_neg_seen)
                     s->state = SSL3_ST_SR_NEXT_PROTO_A;
                 else
                     s->state = SSL3_ST_SR_FINISHED_A;
 #endif
                 s->init_num = 0;
             } else if (TLS1_get_version(s) >= TLS1_2_VERSION) {
                 s->state = SSL3_ST_SR_CERT_VRFY_A;
                 s->init_num = 0;
                 if (!s->session->peer)
                     break;
                 /*
                  * For TLS v1.2 freeze the handshake buffer at this point and
                  * digest cached records.
                  */
                 if (!s->s3->handshake_buffer) {
                     SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR);
                     s->state = SSL_ST_ERR;
                     return -1;
                 }
                 s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE;
                 if (!ssl3_digest_cached_records(s)) {
                     s->state = SSL_ST_ERR;
                     return -1;
                 }
             } else {
                 int offset = 0;
                 int dgst_num;
 
                 s->state = SSL3_ST_SR_CERT_VRFY_A;
                 s->init_num = 0;
 
                 /*
                  * We need to get hashes here so if there is a client cert,
                  * it can be verified FIXME - digest processing for
                  * CertificateVerify should be generalized. But it is next
                  * step
                  */
                 if (s->s3->handshake_buffer) {
                     if (!ssl3_digest_cached_records(s)) {
                         s->state = SSL_ST_ERR;
                         return -1;
                     }
                 }
                 for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++)
                     if (s->s3->handshake_dgst[dgst_num]) {
                         int dgst_size;
 
                         s->method->ssl3_enc->cert_verify_mac(s,
                                                              EVP_MD_CTX_type
                                                              (s->
                                                               s3->handshake_dgst
                                                               [dgst_num]),
                                                              &(s->s3->
                                                                tmp.cert_verify_md
                                                                [offset]));
                         dgst_size =
                             EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]);
                         if (dgst_size < 0) {
                             s->state = SSL_ST_ERR;
                             ret = -1;
                             goto end;
                         }
                         offset += dgst_size;
                     }
             }
             break;
 
         case SSL3_ST_SR_CERT_VRFY_A:
         case SSL3_ST_SR_CERT_VRFY_B:
             ret = ssl3_get_cert_verify(s);
             if (ret <= 0)
                 goto end;
 
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
             s->state = SSL3_ST_SR_FINISHED_A;
 #else
             if (s->s3->next_proto_neg_seen)
                 s->state = SSL3_ST_SR_NEXT_PROTO_A;
             else
                 s->state = SSL3_ST_SR_FINISHED_A;
 #endif
             s->init_num = 0;
             break;
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
         case SSL3_ST_SR_NEXT_PROTO_A:
         case SSL3_ST_SR_NEXT_PROTO_B:
             /*
              * Enable CCS for NPN. Receiving a CCS clears the flag, so make
              * sure not to re-enable it to ban duplicates. This *should* be the
              * first time we have received one - but we check anyway to be
              * cautious.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
              * the client's Finished message is read.
              */
             if (!s->s3->change_cipher_spec)
                 s->s3->flags |= SSL3_FLAGS_CCS_OK;
 
             ret = ssl3_get_next_proto(s);
             if (ret <= 0)
                 goto end;
             s->init_num = 0;
             s->state = SSL3_ST_SR_FINISHED_A;
             break;
 #endif
 
         case SSL3_ST_SR_FINISHED_A:
         case SSL3_ST_SR_FINISHED_B:
             /*
              * Enable CCS for handshakes without NPN. In NPN the CCS flag has
              * already been set. Receiving a CCS clears the flag, so make
              * sure not to re-enable it to ban duplicates.
              * s->s3->change_cipher_spec is set when a CCS is
              * processed in s3_pkt.c, and remains set until
              * the client's Finished message is read.
              */
             if (!s->s3->change_cipher_spec)
                 s->s3->flags |= SSL3_FLAGS_CCS_OK;
             ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A,
                                     SSL3_ST_SR_FINISHED_B);
             if (ret <= 0)
                 goto end;
             if (s->hit)
                 s->state = SSL_ST_OK;
 #ifndef OPENSSL_NO_TLSEXT
             else if (s->tlsext_ticket_expected)
                 s->state = SSL3_ST_SW_SESSION_TICKET_A;
 #endif
             else
                 s->state = SSL3_ST_SW_CHANGE_A;
             s->init_num = 0;
             break;
 
 #ifndef OPENSSL_NO_TLSEXT
         case SSL3_ST_SW_SESSION_TICKET_A:
         case SSL3_ST_SW_SESSION_TICKET_B:
             ret = ssl3_send_newsession_ticket(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_CHANGE_A;
             s->init_num = 0;
             break;
 
         case SSL3_ST_SW_CERT_STATUS_A:
         case SSL3_ST_SW_CERT_STATUS_B:
             ret = ssl3_send_cert_status(s);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_KEY_EXCH_A;
             s->init_num = 0;
             break;
 
 #endif
 
         case SSL3_ST_SW_CHANGE_A:
         case SSL3_ST_SW_CHANGE_B:
 
             s->session->cipher = s->s3->tmp.new_cipher;
             if (!s->method->ssl3_enc->setup_key_block(s)) {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             ret = ssl3_send_change_cipher_spec(s,
                                                SSL3_ST_SW_CHANGE_A,
                                                SSL3_ST_SW_CHANGE_B);
 
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_FINISHED_A;
             s->init_num = 0;
 
             if (!s->method->ssl3_enc->change_cipher_state(s,
                                                           SSL3_CHANGE_CIPHER_SERVER_WRITE))
             {
                 ret = -1;
                 s->state = SSL_ST_ERR;
                 goto end;
             }
 
             break;
 
         case SSL3_ST_SW_FINISHED_A:
         case SSL3_ST_SW_FINISHED_B:
             ret = ssl3_send_finished(s,
                                      SSL3_ST_SW_FINISHED_A,
                                      SSL3_ST_SW_FINISHED_B,
                                      s->method->
                                      ssl3_enc->server_finished_label,
                                      s->method->
                                      ssl3_enc->server_finished_label_len);
             if (ret <= 0)
                 goto end;
             s->state = SSL3_ST_SW_FLUSH;
             if (s->hit) {
 #if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG)
                 s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
 #else
                 if (s->s3->next_proto_neg_seen) {
                     s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A;
                 } else
                     s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A;
 #endif
             } else
                 s->s3->tmp.next_state = SSL_ST_OK;
             s->init_num = 0;
             break;
 
         case SSL_ST_OK:
             /* clean a few things up */
             ssl3_cleanup_key_block(s);
 
             BUF_MEM_free(s->init_buf);
             s->init_buf = NULL;
 
             /* remove buffering on output */
             ssl_free_wbio_buffer(s);
 
             s->init_num = 0;
 
             if (s->renegotiate == 2) { /* skipped if we just sent a
                                         * HelloRequest */
                 s->renegotiate = 0;
                 s->new_session = 0;
 
                 ssl_update_cache(s, SSL_SESS_CACHE_SERVER);
 
                 s->ctx->stats.sess_accept_good++;
                 /* s->server=1; */
                 s->handshake_func = ssl3_accept;
 
                 if (cb != NULL)
                     cb(s, SSL_CB_HANDSHAKE_DONE, 1);
             }
 
             ret = 1;
             goto end;
             /* break; */
 
         case SSL_ST_ERR:
         default:
             SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE);
             ret = -1;
             goto end;
             /* break; */
         }
 
         if (!s->s3->tmp.reuse_message && !skip) {
             if (s->debug) {
                 if ((ret = BIO_flush(s->wbio)) <= 0)
                     goto end;
             }
 
             if ((cb != NULL) && (s->state != state)) {
                 new_state = s->state;
                 s->state = state;
                 cb(s, SSL_CB_ACCEPT_LOOP, 1);
                 s->state = new_state;
             }
         }
         skip = 0;
     }
  end:
     /* BIO_flush(s->wbio); */
 
     s->in_handshake--;
     if (cb != NULL)
         cb(s, SSL_CB_ACCEPT_EXIT, ret);
     return (ret);
 }
 
 int ssl3_send_hello_request(SSL *s)
 {
     unsigned char *p;
 
     if (s->state == SSL3_ST_SW_HELLO_REQ_A) {
         p = (unsigned char *)s->init_buf->data;
         *(p++) = SSL3_MT_HELLO_REQUEST;
         *(p++) = 0;
         *(p++) = 0;
         *(p++) = 0;
 
         s->state = SSL3_ST_SW_HELLO_REQ_B;
         /* number of bytes to write */
         s->init_num = 4;
         s->init_off = 0;
     }
 
     /* SSL3_ST_SW_HELLO_REQ_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int ssl3_check_client_hello(SSL *s)
 {
     int ok;
     long n;
 
     /*
      * this function is called when we really expect a Certificate message,
      * so permit appropriate message length
      */
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CERT_A,
                                    SSL3_ST_SR_CERT_B,
                                    -1, s->max_cert_list, &ok);
     if (!ok)
         return ((int)n);
     s->s3->tmp.reuse_message = 1;
     if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) {
         /*
          * We only allow the client to restart the handshake once per
          * negotiation.
          */
         if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) {
             SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO,
                    SSL_R_MULTIPLE_SGC_RESTARTS);
             return -1;
         }
         /*
          * Throw away what we have done so far in the current handshake,
          * which will now be aborted. (A full SSL_clear would be too much.)
          */
 #ifndef OPENSSL_NO_DH
         if (s->s3->tmp.dh != NULL) {
             DH_free(s->s3->tmp.dh);
             s->s3->tmp.dh = NULL;
         }
 #endif
 #ifndef OPENSSL_NO_ECDH
         if (s->s3->tmp.ecdh != NULL) {
             EC_KEY_free(s->s3->tmp.ecdh);
             s->s3->tmp.ecdh = NULL;
         }
 #endif
         s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
         return 2;
     }
     return 1;
 }
 
 int ssl3_get_client_hello(SSL *s)
 {
     int i, j, ok, al, ret = -1, cookie_valid = 0;
     unsigned int cookie_len;
     long n;
     unsigned long id;
     unsigned char *p, *d, *q;
     SSL_CIPHER *c;
 #ifndef OPENSSL_NO_COMP
     SSL_COMP *comp = NULL;
 #endif
     STACK_OF(SSL_CIPHER) *ciphers = NULL;
 
     /*
      * We do this so that we will respond with our native type. If we are
      * TLSv1 and we get SSLv3, we will respond with TLSv1, This down
      * switching should be handled by a different method. If we are SSLv3, we
      * will respond with SSLv3, even if prompted with TLSv1.
      */
     if (s->state == SSL3_ST_SR_CLNT_HELLO_A) {
         s->state = SSL3_ST_SR_CLNT_HELLO_B;
     }
     s->first_packet = 1;
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CLNT_HELLO_B,
                                    SSL3_ST_SR_CLNT_HELLO_C,
                                    SSL3_MT_CLIENT_HELLO,
                                    SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 
     if (!ok)
         return ((int)n);
     s->first_packet = 0;
     d = p = (unsigned char *)s->init_msg;
 
     /*
      * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte
      * for session id length
      */
     if (n < 2 + SSL3_RANDOM_SIZE + 1) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
         goto f_err;
     }
 
     /*
      * use version from inside client hello, not from record header (may
      * differ: see RFC 2246, Appendix E, second paragraph)
      */
     s->client_version = (((int)p[0]) << 8) | (int)p[1];
     p += 2;
 
     if ((s->version == DTLS1_VERSION && s->client_version > s->version) ||
         (s->version != DTLS1_VERSION && s->client_version < s->version)) {
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER);
         if ((s->client_version >> 8) == SSL3_VERSION_MAJOR &&
             !s->enc_write_ctx && !s->write_hash) {
             /*
              * similar to ssl3_get_record, send alert using remote version
              * number
              */
             s->version = s->client_version;
         }
         al = SSL_AD_PROTOCOL_VERSION;
         goto f_err;
     }
 
     /*
      * If we require cookies and this ClientHello doesn't contain one, just
      * return since we do not want to allocate any memory yet. So check
      * cookie length...
      */
     if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) {
         unsigned int session_length, cookie_length;
 
         session_length = *(p + SSL3_RANDOM_SIZE);
 
-        if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+        if (SSL3_RANDOM_SIZE + session_length + 1 >= (d + n) - p) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1);
 
         if (cookie_length == 0)
             return 1;
     }
 
     /* load the client random */
     memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE);
     p += SSL3_RANDOM_SIZE;
 
     /* get the session-id */
     j = *(p++);
 
-    if (p + j > d + n) {
+    if ((d + n) - p < j) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
         goto f_err;
     }
 
     if ((j < 0) || (j > SSL_MAX_SSL_SESSION_ID_LENGTH)) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
 
     s->hit = 0;
     /*
      * Versions before 0.9.7 always allow clients to resume sessions in
      * renegotiation. 0.9.7 and later allow this by default, but optionally
      * ignore resumption requests with flag
      * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather
      * than a change to default behavior so that applications relying on this
      * for security won't even compile against older library versions).
      * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to
      * request renegotiation but not a new session (s->new_session remains
      * unset): for servers, this essentially just means that the
      * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored.
      */
     if ((s->new_session
          && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) {
         if (!ssl_get_new_session(s, 1))
             goto err;
     } else {
         i = ssl_get_prev_session(s, p, j, d + n);
         /*
          * Only resume if the session's version matches the negotiated
          * version.
          * RFC 5246 does not provide much useful advice on resumption
          * with a different protocol version. It doesn't forbid it but
          * the sanity of such behaviour would be questionable.
          * In practice, clients do not accept a version mismatch and
          * will abort the handshake with an error.
          */
         if (i == 1 && s->version == s->session->ssl_version) { /* previous
                                                                 * session */
             s->hit = 1;
         } else if (i == -1)
             goto err;
         else {                  /* i == 0 */
 
             if (!ssl_get_new_session(s, 1))
                 goto err;
         }
     }
 
     p += j;
 
     if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) {
         /* cookie stuff */
-        if (p + 1 > d + n) {
+        if ((d + n) - p < 1) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
         cookie_len = *(p++);
 
-        if (p + cookie_len > d + n) {
+        if ((d + n ) - p < cookie_len) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
             goto f_err;
         }
 
         /*
          * The ClientHello may contain a cookie even if the
          * HelloVerify message has not been sent--make sure that it
          * does not cause an overflow.
          */
         if (cookie_len > sizeof(s->d1->rcvd_cookie)) {
             /* too much data */
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
             goto f_err;
         }
 
         /* verify the cookie if appropriate option is set. */
         if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) {
             memcpy(s->d1->rcvd_cookie, p, cookie_len);
 
             if (s->ctx->app_verify_cookie_cb != NULL) {
                 if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie,
                                                  cookie_len) == 0) {
                     al = SSL_AD_HANDSHAKE_FAILURE;
                     SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
                            SSL_R_COOKIE_MISMATCH);
                     goto f_err;
                 }
                 /* else cookie verification succeeded */
             }
             /* default verification */
             else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie,
                             s->d1->cookie_len) != 0) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH);
                 goto f_err;
             }
             cookie_valid = 1;
         }
 
         p += cookie_len;
     }
 
-    if (p + 2 > d + n) {
+    if ((d + n ) - p < 2) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
         goto f_err;
     }
     n2s(p, i);
 
     if (i == 0) {
         al = SSL_AD_ILLEGAL_PARAMETER;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED);
         goto f_err;
     }
 
     /* i bytes of cipher data + 1 byte for compression length later */
-    if ((p + i + 1) > (d + n)) {
+    if ((d + n) - p < i + 1) {
         /* not enough data */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
     if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) {
         goto err;
     }
     p += i;
 
     /* If it is a hit, check that the cipher is in the list */
     if (s->hit) {
         j = 0;
         id = s->session->cipher->id;
 
 #ifdef CIPHER_DEBUG
         fprintf(stderr, "client sent %d ciphers\n",
                 sk_SSL_CIPHER_num(ciphers));
 #endif
         for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
             c = sk_SSL_CIPHER_value(ciphers, i);
 #ifdef CIPHER_DEBUG
             fprintf(stderr, "client [%2d of %2d]:%s\n",
                     i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c));
 #endif
             if (c->id == id) {
                 j = 1;
                 break;
             }
         }
         /*
          * Disabled because it can be used in a ciphersuite downgrade attack:
          * CVE-2010-4180.
          */
 #if 0
         if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
             && (sk_SSL_CIPHER_num(ciphers) == 1)) {
             /*
              * Special case as client bug workaround: the previously used
              * cipher may not be in the current list, the client instead
              * might be trying to continue using a cipher that before wasn't
              * chosen due to server preferences.  We'll have to reject the
              * connection if the cipher is not enabled, though.
              */
             c = sk_SSL_CIPHER_value(ciphers, 0);
             if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) {
                 s->session->cipher = c;
                 j = 1;
             }
         }
 #endif
         if (j == 0) {
             /*
              * we need to have the cipher in the cipher list if we are asked
              * to reuse it
              */
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
                    SSL_R_REQUIRED_CIPHER_MISSING);
             goto f_err;
         }
     }
 
     /* compression */
     i = *(p++);
-    if ((p + i) > (d + n)) {
+    if ((d + n) - p < i) {
         /* not enough data */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
     q = p;
     for (j = 0; j < i; j++) {
         if (p[j] == 0)
             break;
     }
 
     p += i;
     if (j >= i) {
         /* no compress */
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED);
         goto f_err;
     }
 #ifndef OPENSSL_NO_TLSEXT
     /* TLS extensions */
     if (s->version >= SSL3_VERSION) {
         if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) {
             /* 'al' set by ssl_parse_clienthello_tlsext */
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT);
             goto f_err;
         }
     }
     if (ssl_check_clienthello_tlsext_early(s) <= 0) {
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
         goto err;
     }
 
     /*
      * Check if we want to use external pre-shared secret for this handshake
      * for not reused session only. We need to generate server_random before
      * calling tls_session_secret_cb in order to allow SessionTicket
      * processing to use it in key derivation.
      */
     {
         unsigned char *pos;
         pos = s->s3->server_random;
         if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) {
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
     }
 
     if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) {
         SSL_CIPHER *pref_cipher = NULL;
 
         s->session->master_key_length = sizeof(s->session->master_key);
         if (s->tls_session_secret_cb(s, s->session->master_key,
                                      &s->session->master_key_length, ciphers,
                                      &pref_cipher,
                                      s->tls_session_secret_cb_arg)) {
             s->hit = 1;
             s->session->ciphers = ciphers;
             s->session->verify_result = X509_V_OK;
 
             ciphers = NULL;
 
             /* check if some cipher was preferred by call back */
             pref_cipher =
                 pref_cipher ? pref_cipher : ssl3_choose_cipher(s,
                                                                s->
                                                                session->ciphers,
                                                                SSL_get_ciphers
                                                                (s));
             if (pref_cipher == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER);
                 goto f_err;
             }
 
             s->session->cipher = pref_cipher;
 
             if (s->cipher_list)
                 sk_SSL_CIPHER_free(s->cipher_list);
 
             if (s->cipher_list_by_id)
                 sk_SSL_CIPHER_free(s->cipher_list_by_id);
 
             s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers);
             s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers);
         }
     }
 #endif
 
     /*
      * Worst case, we will use the NULL compression, but if we have other
      * options, we will now look for them.  We have i-1 compression
      * algorithms from the client, starting at q.
      */
     s->s3->tmp.new_compression = NULL;
 #ifndef OPENSSL_NO_COMP
     /* This only happens if we have a cache hit */
     if (s->session->compress_meth != 0) {
         int m, comp_id = s->session->compress_meth;
         /* Perform sanity checks on resumed compression algorithm */
         /* Can't disable compression */
         if (s->options & SSL_OP_NO_COMPRESSION) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
                    SSL_R_INCONSISTENT_COMPRESSION);
             goto f_err;
         }
         /* Look for resumed compression method */
         for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) {
             comp = sk_SSL_COMP_value(s->ctx->comp_methods, m);
             if (comp_id == comp->id) {
                 s->s3->tmp.new_compression = comp;
                 break;
             }
         }
         if (s->s3->tmp.new_compression == NULL) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
                    SSL_R_INVALID_COMPRESSION_ALGORITHM);
             goto f_err;
         }
         /* Look for resumed method in compression list */
         for (m = 0; m < i; m++) {
             if (q[m] == comp_id)
                 break;
         }
         if (m >= i) {
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
                    SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING);
             goto f_err;
         }
     } else if (s->hit)
         comp = NULL;
     else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) {
         /* See if we have a match */
         int m, nn, o, v, done = 0;
 
         nn = sk_SSL_COMP_num(s->ctx->comp_methods);
         for (m = 0; m < nn; m++) {
             comp = sk_SSL_COMP_value(s->ctx->comp_methods, m);
             v = comp->id;
             for (o = 0; o < i; o++) {
                 if (v == q[o]) {
                     done = 1;
                     break;
                 }
             }
             if (done)
                 break;
         }
         if (done)
             s->s3->tmp.new_compression = comp;
         else
             comp = NULL;
     }
 #else
     /*
      * If compression is disabled we'd better not try to resume a session
      * using compression.
      */
     if (s->session->compress_meth != 0) {
         al = SSL_AD_INTERNAL_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION);
         goto f_err;
     }
 #endif
 
     /*
      * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher
      */
 
     if (!s->hit) {
 #ifdef OPENSSL_NO_COMP
         s->session->compress_meth = 0;
 #else
         s->session->compress_meth = (comp == NULL) ? 0 : comp->id;
 #endif
         if (s->session->ciphers != NULL)
             sk_SSL_CIPHER_free(s->session->ciphers);
         s->session->ciphers = ciphers;
         if (ciphers == NULL) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR);
             goto f_err;
         }
         ciphers = NULL;
         c = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s));
 
         if (c == NULL) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER);
             goto f_err;
         }
         s->s3->tmp.new_cipher = c;
     } else {
         /* Session-id reuse */
 #ifdef REUSE_CIPHER_BUG
         STACK_OF(SSL_CIPHER) *sk;
         SSL_CIPHER *nc = NULL;
         SSL_CIPHER *ec = NULL;
 
         if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) {
             sk = s->session->ciphers;
             for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
                 c = sk_SSL_CIPHER_value(sk, i);
                 if (c->algorithm_enc & SSL_eNULL)
                     nc = c;
                 if (SSL_C_IS_EXPORT(c))
                     ec = c;
             }
             if (nc != NULL)
                 s->s3->tmp.new_cipher = nc;
             else if (ec != NULL)
                 s->s3->tmp.new_cipher = ec;
             else
                 s->s3->tmp.new_cipher = s->session->cipher;
         } else
 #endif
             s->s3->tmp.new_cipher = s->session->cipher;
     }
 
     if (TLS1_get_version(s) < TLS1_2_VERSION
         || !(s->verify_mode & SSL_VERIFY_PEER)) {
         if (!ssl3_digest_cached_records(s)) {
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
     }
 
     /*-
      * we now have the following setup.
      * client_random
      * cipher_list          - our prefered list of ciphers
      * ciphers              - the clients prefered list of ciphers
      * compression          - basically ignored right now
      * ssl version is set   - sslv3
      * s->session           - The ssl session has been setup.
      * s->hit               - session reuse flag
      * s->tmp.new_cipher    - the new cipher to use.
      */
 
     /* Handles TLS extensions that we couldn't check earlier */
     if (s->version >= SSL3_VERSION) {
         if (ssl_check_clienthello_tlsext_late(s) <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
             goto err;
         }
     }
 
     ret = cookie_valid ? 2 : 1;
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
         s->state = SSL_ST_ERR;
     }
 
     if (ciphers != NULL)
         sk_SSL_CIPHER_free(ciphers);
     return ret;
 }
 
 int ssl3_send_server_hello(SSL *s)
 {
     unsigned char *buf;
     unsigned char *p, *d;
     int i, sl;
     unsigned long l;
 
     if (s->state == SSL3_ST_SW_SRVR_HELLO_A) {
         buf = (unsigned char *)s->init_buf->data;
 #ifdef OPENSSL_NO_TLSEXT
         p = s->s3->server_random;
         if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) {
             s->state = SSL_ST_ERR;
             return -1;
         }
 #endif
         /* Do the message type and length last */
         d = p = &(buf[4]);
 
         *(p++) = s->version >> 8;
         *(p++) = s->version & 0xff;
 
         /* Random stuff */
         memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
         p += SSL3_RANDOM_SIZE;
 
         /*-
          * There are several cases for the session ID to send
          * back in the server hello:
          * - For session reuse from the session cache,
          *   we send back the old session ID.
          * - If stateless session reuse (using a session ticket)
          *   is successful, we send back the client's "session ID"
          *   (which doesn't actually identify the session).
          * - If it is a new session, we send back the new
          *   session ID.
          * - However, if we want the new session to be single-use,
          *   we send back a 0-length session ID.
          * s->hit is non-zero in either case of session reuse,
          * so the following won't overwrite an ID that we're supposed
          * to send back.
          */
         if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
             && !s->hit)
             s->session->session_id_length = 0;
 
         sl = s->session->session_id_length;
         if (sl > (int)sizeof(s->session->session_id)) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             s->state = SSL_ST_ERR;
             return -1;
         }
         *(p++) = sl;
         memcpy(p, s->session->session_id, sl);
         p += sl;
 
         /* put the cipher */
         i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p);
         p += i;
 
         /* put the compression method */
 #ifdef OPENSSL_NO_COMP
         *(p++) = 0;
 #else
         if (s->s3->tmp.new_compression == NULL)
             *(p++) = 0;
         else
             *(p++) = s->s3->tmp.new_compression->id;
 #endif
 #ifndef OPENSSL_NO_TLSEXT
         if (ssl_prepare_serverhello_tlsext(s) <= 0) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT);
             s->state = SSL_ST_ERR;
             return -1;
         }
         if ((p =
              ssl_add_serverhello_tlsext(s, p,
                                         buf + SSL3_RT_MAX_PLAIN_LENGTH)) ==
             NULL) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR);
             s->state = SSL_ST_ERR;
             return -1;
         }
 #endif
         /* do the header */
         l = (p - d);
         d = buf;
         *(d++) = SSL3_MT_SERVER_HELLO;
         l2n3(l, d);
 
         s->state = SSL3_ST_SW_SRVR_HELLO_B;
         /* number of bytes to write */
         s->init_num = p - buf;
         s->init_off = 0;
     }
 
     /* SSL3_ST_SW_SRVR_HELLO_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int ssl3_send_server_done(SSL *s)
 {
     unsigned char *p;
 
     if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
         p = (unsigned char *)s->init_buf->data;
 
         /* do the header */
         *(p++) = SSL3_MT_SERVER_DONE;
         *(p++) = 0;
         *(p++) = 0;
         *(p++) = 0;
 
         s->state = SSL3_ST_SW_SRVR_DONE_B;
         /* number of bytes to write */
         s->init_num = 4;
         s->init_off = 0;
     }
 
     /* SSL3_ST_SW_SRVR_DONE_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 int ssl3_send_server_key_exchange(SSL *s)
 {
 #ifndef OPENSSL_NO_RSA
     unsigned char *q;
     int j, num;
     RSA *rsa;
     unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH];
     unsigned int u;
 #endif
 #ifndef OPENSSL_NO_DH
     DH *dh = NULL, *dhp;
 #endif
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *ecdh = NULL, *ecdhp;
     unsigned char *encodedPoint = NULL;
     int encodedlen = 0;
     int curve_id = 0;
     BN_CTX *bn_ctx = NULL;
 #endif
     EVP_PKEY *pkey;
     const EVP_MD *md = NULL;
     unsigned char *p, *d;
     int al, i;
     unsigned long type;
     int n;
     CERT *cert;
     BIGNUM *r[4];
     int nr[4], kn;
     BUF_MEM *buf;
     EVP_MD_CTX md_ctx;
 
     EVP_MD_CTX_init(&md_ctx);
     if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
         type = s->s3->tmp.new_cipher->algorithm_mkey;
         cert = s->cert;
 
         buf = s->init_buf;
 
         r[0] = r[1] = r[2] = r[3] = NULL;
         n = 0;
 #ifndef OPENSSL_NO_RSA
         if (type & SSL_kRSA) {
             rsa = cert->rsa_tmp;
             if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) {
                 rsa = s->cert->rsa_tmp_cb(s,
                                           SSL_C_IS_EXPORT(s->s3->
                                                           tmp.new_cipher),
                                           SSL_C_EXPORT_PKEYLENGTH(s->s3->
                                                                   tmp.new_cipher));
                 if (rsa == NULL) {
                     al = SSL_AD_HANDSHAKE_FAILURE;
                     SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                            SSL_R_ERROR_GENERATING_TMP_RSA_KEY);
                     goto f_err;
                 }
                 RSA_up_ref(rsa);
                 cert->rsa_tmp = rsa;
             }
             if (rsa == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_RSA_KEY);
                 goto f_err;
             }
             r[0] = rsa->n;
             r[1] = rsa->e;
             s->s3->tmp.use_rsa_tmp = 1;
         } else
 #endif
 #ifndef OPENSSL_NO_DH
         if (type & SSL_kEDH) {
             dhp = cert->dh_tmp;
             if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL))
                 dhp = s->cert->dh_tmp_cb(s,
                                          SSL_C_IS_EXPORT(s->s3->
                                                          tmp.new_cipher),
                                          SSL_C_EXPORT_PKEYLENGTH(s->s3->
                                                                  tmp.new_cipher));
             if (dhp == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_DH_KEY);
                 goto f_err;
             }
 
             if (s->s3->tmp.dh != NULL) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             if ((dh = DHparams_dup(dhp)) == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
 
             s->s3->tmp.dh = dh;
             if (!DH_generate_key(dh)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB);
                 goto err;
             }
             r[0] = dh->p;
             r[1] = dh->g;
             r[2] = dh->pub_key;
         } else
 #endif
 #ifndef OPENSSL_NO_ECDH
         if (type & SSL_kEECDH) {
             const EC_GROUP *group;
 
             ecdhp = cert->ecdh_tmp;
             if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) {
                 ecdhp = s->cert->ecdh_tmp_cb(s,
                                              SSL_C_IS_EXPORT(s->s3->
                                                              tmp.new_cipher),
                                              SSL_C_EXPORT_PKEYLENGTH(s->
                                                                      s3->tmp.new_cipher));
             }
             if (ecdhp == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_ECDH_KEY);
                 goto f_err;
             }
 
             if (s->s3->tmp.ecdh != NULL) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_INTERNAL_ERROR);
                 goto err;
             }
 
             /* Duplicate the ECDH structure. */
             if (ecdhp == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
             if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             s->s3->tmp.ecdh = ecdh;
             if ((EC_KEY_get0_public_key(ecdh) == NULL) ||
                 (EC_KEY_get0_private_key(ecdh) == NULL) ||
                 (s->options & SSL_OP_SINGLE_ECDH_USE)) {
                 if (!EC_KEY_generate_key(ecdh)) {
                     SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                            ERR_R_ECDH_LIB);
                     goto err;
                 }
             }
 
             if (((group = EC_KEY_get0_group(ecdh)) == NULL) ||
                 (EC_KEY_get0_public_key(ecdh) == NULL) ||
                 (EC_KEY_get0_private_key(ecdh) == NULL)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) &&
                 (EC_GROUP_get_degree(group) > 163)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER);
                 goto err;
             }
 
             /*
              * XXX: For now, we only support ephemeral ECDH keys over named
              * (not generic) curves. For supported named curves, curve_id is
              * non-zero.
              */
             if ((curve_id =
                  tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group)))
                 == 0) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
                 goto err;
             }
 
             /*
              * Encode the public key. First check the size of encoding and
              * allocate memory accordingly.
              */
             encodedlen = EC_POINT_point2oct(group,
                                             EC_KEY_get0_public_key(ecdh),
                                             POINT_CONVERSION_UNCOMPRESSED,
                                             NULL, 0, NULL);
 
             encodedPoint = (unsigned char *)
                 OPENSSL_malloc(encodedlen * sizeof(unsigned char));
             bn_ctx = BN_CTX_new();
             if ((encodedPoint == NULL) || (bn_ctx == NULL)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             encodedlen = EC_POINT_point2oct(group,
                                             EC_KEY_get0_public_key(ecdh),
                                             POINT_CONVERSION_UNCOMPRESSED,
                                             encodedPoint, encodedlen, bn_ctx);
 
             if (encodedlen == 0) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
                 goto err;
             }
 
             BN_CTX_free(bn_ctx);
             bn_ctx = NULL;
 
             /*
              * XXX: For now, we only support named (not generic) curves in
              * ECDH ephemeral key exchanges. In this situation, we need four
              * additional bytes to encode the entire ServerECDHParams
              * structure.
              */
             n = 4 + encodedlen;
 
             /*
              * We'll generate the serverKeyExchange message explicitly so we
              * can set these to NULLs
              */
             r[0] = NULL;
             r[1] = NULL;
             r[2] = NULL;
             r[3] = NULL;
         } else
 #endif                          /* !OPENSSL_NO_ECDH */
 #ifndef OPENSSL_NO_PSK
         if (type & SSL_kPSK) {
             /*
              * reserve size for record length and PSK identity hint
              */
             n += 2 + strlen(s->ctx->psk_identity_hint);
         } else
 #endif                          /* !OPENSSL_NO_PSK */
 #ifndef OPENSSL_NO_SRP
         if (type & SSL_kSRP) {
             if ((s->srp_ctx.N == NULL) ||
                 (s->srp_ctx.g == NULL) ||
                 (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_MISSING_SRP_PARAM);
                 goto err;
             }
             r[0] = s->srp_ctx.N;
             r[1] = s->srp_ctx.g;
             r[2] = s->srp_ctx.s;
             r[3] = s->srp_ctx.B;
         } else
 #endif
         {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                    SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
             goto f_err;
         }
         for (i = 0; i < 4 && r[i] != NULL; i++) {
             nr[i] = BN_num_bytes(r[i]);
 #ifndef OPENSSL_NO_SRP
             if ((i == 2) && (type & SSL_kSRP))
                 n += 1 + nr[i];
             else
 #endif
                 n += 2 + nr[i];
         }
 
         if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP))
             && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) {
             if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md))
                 == NULL) {
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
             kn = EVP_PKEY_size(pkey);
         } else {
             pkey = NULL;
             kn = 0;
         }
 
         if (!BUF_MEM_grow_clean(buf, n + 4 + kn)) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF);
             goto err;
         }
         d = (unsigned char *)s->init_buf->data;
         p = &(d[4]);
 
         for (i = 0; i < 4 && r[i] != NULL; i++) {
 #ifndef OPENSSL_NO_SRP
             if ((i == 2) && (type & SSL_kSRP)) {
                 *p = nr[i];
                 p++;
             } else
 #endif
                 s2n(nr[i], p);
             BN_bn2bin(r[i], p);
             p += nr[i];
         }
 
 #ifndef OPENSSL_NO_ECDH
         if (type & SSL_kEECDH) {
             /*
              * XXX: For now, we only support named (not generic) curves. In
              * this situation, the serverKeyExchange message has: [1 byte
              * CurveType], [2 byte CurveName] [1 byte length of encoded
              * point], followed by the actual encoded point itself
              */
             *p = NAMED_CURVE_TYPE;
             p += 1;
             *p = 0;
             p += 1;
             *p = curve_id;
             p += 1;
             *p = encodedlen;
             p += 1;
             memcpy((unsigned char *)p,
                    (unsigned char *)encodedPoint, encodedlen);
             OPENSSL_free(encodedPoint);
             encodedPoint = NULL;
             p += encodedlen;
         }
 #endif
 
 #ifndef OPENSSL_NO_PSK
         if (type & SSL_kPSK) {
             /* copy PSK identity hint */
             s2n(strlen(s->ctx->psk_identity_hint), p);
             strncpy((char *)p, s->ctx->psk_identity_hint,
                     strlen(s->ctx->psk_identity_hint));
             p += strlen(s->ctx->psk_identity_hint);
         }
 #endif
 
         /* not anonymous */
         if (pkey != NULL) {
             /*
              * n is the length of the params, they start at &(d[4]) and p
              * points to the space at the end.
              */
 #ifndef OPENSSL_NO_RSA
             if (pkey->type == EVP_PKEY_RSA
                 && TLS1_get_version(s) < TLS1_2_VERSION) {
                 q = md_buf;
                 j = 0;
                 for (num = 2; num > 0; num--) {
                     EVP_MD_CTX_set_flags(&md_ctx,
                                          EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
                     if (EVP_DigestInit_ex(&md_ctx,
                                           (num == 2) ? s->ctx->md5
                                                      : s->ctx->sha1,
                                           NULL) <= 0
                         || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]),
                                             SSL3_RANDOM_SIZE) <= 0
                         || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]),
                                             SSL3_RANDOM_SIZE) <= 0
                         || EVP_DigestUpdate(&md_ctx, &(d[4]), n) <= 0
                         || EVP_DigestFinal_ex(&md_ctx, q,
                                               (unsigned int *)&i) <= 0) {
                         SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                                ERR_LIB_EVP);
                         al = SSL_AD_INTERNAL_ERROR;
                         goto f_err;
                     }
                     q += i;
                     j += i;
                 }
                 if (RSA_sign(NID_md5_sha1, md_buf, j,
                              &(p[2]), &u, pkey->pkey.rsa) <= 0) {
                     SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA);
                     goto err;
                 }
                 s2n(u, p);
                 n += u + 2;
             } else
 #endif
             if (md) {
                 /*
                  * For TLS1.2 and later send signature algorithm
                  */
                 if (TLS1_get_version(s) >= TLS1_2_VERSION) {
                     if (!tls12_get_sigandhash(p, pkey, md)) {
                         /* Should never happen */
                         al = SSL_AD_INTERNAL_ERROR;
                         SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                                ERR_R_INTERNAL_ERROR);
                         goto f_err;
                     }
                     p += 2;
                 }
 #ifdef SSL_DEBUG
                 fprintf(stderr, "Using hash %s\n", EVP_MD_name(md));
 #endif
                 if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0
                         || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]),
                                           SSL3_RANDOM_SIZE) <= 0
                         || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]),
                                           SSL3_RANDOM_SIZE) <= 0
                         || EVP_SignUpdate(&md_ctx, &(d[4]), n) <= 0
                         || EVP_SignFinal(&md_ctx, &(p[2]),
                                          (unsigned int *)&i, pkey) <= 0) {
                     SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP);
                     al = SSL_AD_INTERNAL_ERROR;
                     goto f_err;
                 }
                 s2n(i, p);
                 n += i + 2;
                 if (TLS1_get_version(s) >= TLS1_2_VERSION)
                     n += 2;
             } else {
                 /* Is this error check actually needed? */
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
                        SSL_R_UNKNOWN_PKEY_TYPE);
                 goto f_err;
             }
         }
 
         *(d++) = SSL3_MT_SERVER_KEY_EXCHANGE;
         l2n3(n, d);
 
         /*
          * we should now have things packed up, so lets send it off
          */
         s->init_num = n + 4;
         s->init_off = 0;
     }
 
     s->state = SSL3_ST_SW_KEY_EXCH_B;
     EVP_MD_CTX_cleanup(&md_ctx);
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
 #ifndef OPENSSL_NO_ECDH
     if (encodedPoint != NULL)
         OPENSSL_free(encodedPoint);
     BN_CTX_free(bn_ctx);
 #endif
     EVP_MD_CTX_cleanup(&md_ctx);
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_send_certificate_request(SSL *s)
 {
     unsigned char *p, *d;
     int i, j, nl, off, n;
     STACK_OF(X509_NAME) *sk = NULL;
     X509_NAME *name;
     BUF_MEM *buf;
 
     if (s->state == SSL3_ST_SW_CERT_REQ_A) {
         buf = s->init_buf;
 
         d = p = (unsigned char *)&(buf->data[4]);
 
         /* get the list of acceptable cert types */
         p++;
         n = ssl3_get_req_cert_type(s, p);
         d[0] = n;
         p += n;
         n++;
 
         if (TLS1_get_version(s) >= TLS1_2_VERSION) {
             nl = tls12_get_req_sig_algs(s, p + 2);
             s2n(nl, p);
             p += nl + 2;
             n += nl + 2;
         }
 
         off = n;
         p += 2;
         n += 2;
 
         sk = SSL_get_client_CA_list(s);
         nl = 0;
         if (sk != NULL) {
             for (i = 0; i < sk_X509_NAME_num(sk); i++) {
                 name = sk_X509_NAME_value(sk, i);
                 j = i2d_X509_NAME(name, NULL);
                 if (!BUF_MEM_grow_clean(buf, 4 + n + j + 2)) {
                     SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,
                            ERR_R_BUF_LIB);
                     goto err;
                 }
                 p = (unsigned char *)&(buf->data[4 + n]);
                 if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) {
                     s2n(j, p);
                     i2d_X509_NAME(name, &p);
                     n += 2 + j;
                     nl += 2 + j;
                 } else {
                     d = p;
                     i2d_X509_NAME(name, &p);
                     j -= 2;
                     s2n(j, d);
                     j += 2;
                     n += j;
                     nl += j;
                 }
             }
         }
         /* else no CA names */
         p = (unsigned char *)&(buf->data[4 + off]);
         s2n(nl, p);
 
         d = (unsigned char *)buf->data;
         *(d++) = SSL3_MT_CERTIFICATE_REQUEST;
         l2n3(n, d);
 
         /*
          * we should now have things packed up, so lets send it off
          */
 
         s->init_num = n + 4;
         s->init_off = 0;
 #ifdef NETSCAPE_HANG_BUG
         if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) {
             SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB);
             goto err;
         }
         p = (unsigned char *)s->init_buf->data + s->init_num;
 
         /* do the header */
         *(p++) = SSL3_MT_SERVER_DONE;
         *(p++) = 0;
         *(p++) = 0;
         *(p++) = 0;
         s->init_num += 4;
 #endif
 
         s->state = SSL3_ST_SW_CERT_REQ_B;
     }
 
     /* SSL3_ST_SW_CERT_REQ_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_client_key_exchange(SSL *s)
 {
     int i, al, ok;
     long n;
     unsigned long alg_k;
     unsigned char *p;
 #ifndef OPENSSL_NO_RSA
     RSA *rsa = NULL;
     EVP_PKEY *pkey = NULL;
 #endif
 #ifndef OPENSSL_NO_DH
     BIGNUM *pub = NULL;
     DH *dh_srvr;
 #endif
 #ifndef OPENSSL_NO_KRB5
     KSSL_ERR kssl_err;
 #endif                          /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
     EC_KEY *srvr_ecdh = NULL;
     EVP_PKEY *clnt_pub_pkey = NULL;
     EC_POINT *clnt_ecpoint = NULL;
     BN_CTX *bn_ctx = NULL;
 #endif
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_KEY_EXCH_A,
                                    SSL3_ST_SR_KEY_EXCH_B,
                                    SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok);
 
     if (!ok)
         return ((int)n);
     p = (unsigned char *)s->init_msg;
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
 
 #ifndef OPENSSL_NO_RSA
     if (alg_k & SSL_kRSA) {
         unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
         int decrypt_len;
         unsigned char decrypt_good, version_good;
         size_t j;
 
         /* FIX THIS UP EAY EAY EAY EAY */
         if (s->s3->tmp.use_rsa_tmp) {
             if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL))
                 rsa = s->cert->rsa_tmp;
             /*
              * Don't do a callback because rsa_tmp should be sent already
              */
             if (rsa == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_RSA_PKEY);
                 goto f_err;
 
             }
         } else {
             pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
             if ((pkey == NULL) ||
                 (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_MISSING_RSA_CERTIFICATE);
                 goto f_err;
             }
             rsa = pkey->pkey.rsa;
         }
 
         /* TLS and [incidentally] DTLS{0xFEFF} */
         if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) {
             n2s(p, i);
             if (n != i + 2) {
                 if (!(s->options & SSL_OP_TLS_D5_BUG)) {
                     al = SSL_AD_DECODE_ERROR;
                     SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                            SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
                     goto f_err;
                 } else
                     p -= 2;
             } else
                 n = i;
         }
 
         /*
          * Reject overly short RSA ciphertext because we want to be sure
          * that the buffer size makes it safe to iterate over the entire
          * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
          * actual expected size is larger due to RSA padding, but the
          * bound is sufficient to be safe.
          */
         if (n < SSL_MAX_MASTER_KEY_LENGTH) {
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
             goto f_err;
         }
 
         /*
          * We must not leak whether a decryption failure occurs because of
          * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246,
          * section 7.4.7.1). The code follows that advice of the TLS RFC and
          * generates a random premaster secret for the case that the decrypt
          * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
          */
 
-        /*
-         * should be RAND_bytes, but we cannot work around a failure.
-         */
-        if (RAND_pseudo_bytes(rand_premaster_secret,
-                              sizeof(rand_premaster_secret)) <= 0)
+        if (RAND_bytes(rand_premaster_secret,
+                       sizeof(rand_premaster_secret)) <= 0)
             goto err;
         decrypt_len =
             RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING);
         ERR_clear_error();
 
         /*
          * decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. decrypt_good will
          * be 0xff if so and zero otherwise.
          */
         decrypt_good =
             constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH);
 
         /*
          * If the version in the decrypted pre-master secret is correct then
          * version_good will be 0xff, otherwise it'll be zero. The
          * Klima-Pokorny-Rosa extension of Bleichenbacher's attack
          * (http://eprint.iacr.org/2003/052/) exploits the version number
          * check as a "bad version oracle". Thus version checks are done in
          * constant time and are treated like any other decryption error.
          */
         version_good =
             constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8));
         version_good &=
             constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff));
 
         /*
          * The premaster secret must contain the same version number as the
          * ClientHello to detect version rollback attacks (strangely, the
          * protocol does not offer such protection for DH ciphersuites).
          * However, buggy clients exist that send the negotiated protocol
          * version instead if the server does not support the requested
          * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such
          * clients.
          */
         if (s->options & SSL_OP_TLS_ROLLBACK_BUG) {
             unsigned char workaround_good;
             workaround_good =
                 constant_time_eq_8(p[0], (unsigned)(s->version >> 8));
             workaround_good &=
                 constant_time_eq_8(p[1], (unsigned)(s->version & 0xff));
             version_good |= workaround_good;
         }
 
         /*
          * Both decryption and version must be good for decrypt_good to
          * remain non-zero (0xff).
          */
         decrypt_good &= version_good;
 
         /*
          * Now copy rand_premaster_secret over from p using
          * decrypt_good_mask. If decryption failed, then p does not
          * contain valid plaintext, however, a check above guarantees
          * it is still sufficiently large to read from.
          */
         for (j = 0; j < sizeof(rand_premaster_secret); j++) {
             p[j] = constant_time_select_8(decrypt_good, p[j],
                                           rand_premaster_secret[j]);
         }
 
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         p,
                                                         sizeof
                                                         (rand_premaster_secret));
         OPENSSL_cleanse(p, sizeof(rand_premaster_secret));
     } else
 #endif
 #ifndef OPENSSL_NO_DH
     if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) {
         n2s(p, i);
         if (n != i + 2) {
             if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
                 goto err;
             } else {
                 p -= 2;
                 i = (int)n;
             }
         }
 
         if (n == 0L) {          /* the parameters are in the cert */
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_UNABLE_TO_DECODE_DH_CERTS);
             goto f_err;
         } else {
             if (s->s3->tmp.dh == NULL) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_DH_KEY);
                 goto f_err;
             } else
                 dh_srvr = s->s3->tmp.dh;
         }
 
         pub = BN_bin2bn(p, i, NULL);
         if (pub == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB);
             goto err;
         }
 
         i = DH_compute_key(p, pub, dh_srvr);
 
         if (i <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
             BN_clear_free(pub);
             goto err;
         }
 
         DH_free(s->s3->tmp.dh);
         s->s3->tmp.dh = NULL;
 
         BN_clear_free(pub);
         pub = NULL;
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         p, i);
         OPENSSL_cleanse(p, i);
     } else
 #endif
 #ifndef OPENSSL_NO_KRB5
     if (alg_k & SSL_kKRB5) {
         krb5_error_code krb5rc;
         krb5_data enc_ticket;
         krb5_data authenticator;
         krb5_data enc_pms;
         KSSL_CTX *kssl_ctx = s->kssl_ctx;
         EVP_CIPHER_CTX ciph_ctx;
         const EVP_CIPHER *enc = NULL;
         unsigned char iv[EVP_MAX_IV_LENGTH];
         unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH];
         int padl, outl;
         krb5_timestamp authtime = 0;
         krb5_ticket_times ttimes;
         int kerr = 0;
 
         EVP_CIPHER_CTX_init(&ciph_ctx);
 
         if (!kssl_ctx)
             kssl_ctx = kssl_ctx_new();
 
         n2s(p, i);
         enc_ticket.length = i;
 
         if (n < (long)(enc_ticket.length + 6)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto err;
         }
 
         enc_ticket.data = (char *)p;
         p += enc_ticket.length;
 
         n2s(p, i);
         authenticator.length = i;
 
         if (n < (long)(enc_ticket.length + authenticator.length + 6)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto err;
         }
 
         authenticator.data = (char *)p;
         p += authenticator.length;
 
         n2s(p, i);
         enc_pms.length = i;
         enc_pms.data = (char *)p;
         p += enc_pms.length;
 
         /*
          * Note that the length is checked again below, ** after decryption
          */
         if (enc_pms.length > sizeof pms) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto err;
         }
 
         if (n != (long)(enc_ticket.length + authenticator.length +
                         enc_pms.length + 6)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto err;
         }
 
         if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes,
                                     &kssl_err)) != 0) {
 # ifdef KSSL_DEBUG
             fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n",
                     krb5rc, kssl_err.reason);
             if (kssl_err.text)
                 fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
 # endif                         /* KSSL_DEBUG */
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
             goto err;
         }
 
         /*
          * Note: no authenticator is not considered an error, ** but will
          * return authtime == 0.
          */
         if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator,
                                          &authtime, &kssl_err)) != 0) {
 # ifdef KSSL_DEBUG
             fprintf(stderr, "kssl_check_authent rtn %d [%d]\n",
                     krb5rc, kssl_err.reason);
             if (kssl_err.text)
                 fprintf(stderr, "kssl_err text= %s\n", kssl_err.text);
 # endif                         /* KSSL_DEBUG */
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason);
             goto err;
         }
 
         if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc);
             goto err;
         }
 # ifdef KSSL_DEBUG
         kssl_ctx_show(kssl_ctx);
 # endif                         /* KSSL_DEBUG */
 
         enc = kssl_map_enc(kssl_ctx->enctype);
         if (enc == NULL)
             goto err;
 
         memset(iv, 0, sizeof iv); /* per RFC 1510 */
 
         if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             goto err;
         }
         if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl,
                                (unsigned char *)enc_pms.data, enc_pms.length))
         {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             kerr = 1;
             goto kclean;
         }
         if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             kerr = 1;
             goto kclean;
         }
         if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             kerr = 1;
             goto kclean;
         }
         outl += padl;
         if (outl > SSL_MAX_MASTER_KEY_LENGTH) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             kerr = 1;
             goto kclean;
         }
         if (!((pms[0] == (s->client_version >> 8))
               && (pms[1] == (s->client_version & 0xff)))) {
             /*
              * The premaster secret must contain the same version number as
              * the ClientHello to detect version rollback attacks (strangely,
              * the protocol does not offer such protection for DH
              * ciphersuites). However, buggy clients exist that send random
              * bytes instead of the protocol version. If
              * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients.
              * (Perhaps we should have a separate BUG value for the Kerberos
              * cipher)
              */
             if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_AD_DECODE_ERROR);
                 kerr = 1;
                 goto kclean;
             }
         }
 
         EVP_CIPHER_CTX_cleanup(&ciph_ctx);
 
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         pms, outl);
 
         if (kssl_ctx->client_princ) {
             size_t len = strlen(kssl_ctx->client_princ);
             if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) {
                 s->session->krb5_client_princ_len = len;
                 memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ,
                        len);
             }
         }
 
         /*- Was doing kssl_ctx_free() here,
          *  but it caused problems for apache.
          *  kssl_ctx = kssl_ctx_free(kssl_ctx);
          *  if (s->kssl_ctx)  s->kssl_ctx = NULL;
          */
 
  kclean:
         OPENSSL_cleanse(pms, sizeof(pms));
         if (kerr)
             goto err;
     } else
 #endif                          /* OPENSSL_NO_KRB5 */
 
 #ifndef OPENSSL_NO_ECDH
     if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) {
         int ret = 1;
         int field_size = 0;
         const EC_KEY *tkey;
         const EC_GROUP *group;
         const BIGNUM *priv_key;
 
         /* initialize structures for server's ECDH key pair */
         if ((srvr_ecdh = EC_KEY_new()) == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         /* Let's get server private key and group information */
         if (alg_k & (SSL_kECDHr | SSL_kECDHe)) {
             /* use the certificate */
             tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec;
         } else {
             /*
              * use the ephermeral values we saved when generating the
              * ServerKeyExchange msg.
              */
             tkey = s->s3->tmp.ecdh;
         }
 
         group = EC_KEY_get0_group(tkey);
         priv_key = EC_KEY_get0_private_key(tkey);
 
         if (!EC_KEY_set_group(srvr_ecdh, group) ||
             !EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
             goto err;
         }
 
         /* Let's get client's public key */
         if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         if (n == 0L) {
             /* Client Publickey was in Client Certificate */
 
             if (alg_k & SSL_kEECDH) {
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_MISSING_TMP_ECDH_KEY);
                 goto f_err;
             }
             if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer))
                  == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) {
                 /*
                  * XXX: For now, we do not support client authentication
                  * using ECDH certificates so this branch (n == 0L) of the
                  * code is never executed. When that support is added, we
                  * ought to ensure the key received in the certificate is
                  * authorized for key agreement. ECDH_compute_key implicitly
                  * checks that the two ECDH shares are for the same group.
                  */
                 al = SSL_AD_HANDSHAKE_FAILURE;
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        SSL_R_UNABLE_TO_DECODE_ECDH_CERTS);
                 goto f_err;
             }
 
             if (EC_POINT_copy(clnt_ecpoint,
                               EC_KEY_get0_public_key(clnt_pub_pkey->
                                                      pkey.ec)) == 0) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
             ret = 2;            /* Skip certificate verify processing */
         } else {
             /*
              * Get client's public key from encoded point in the
              * ClientKeyExchange message.
              */
             if ((bn_ctx = BN_CTX_new()) == NULL) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                        ERR_R_MALLOC_FAILURE);
                 goto err;
             }
 
             /* Get encoded point length */
             i = *p;
             p += 1;
             if (n != 1 + i) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
             if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) {
                 SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
                 goto err;
             }
             /*
              * p is pointing to somewhere in the buffer currently, so set it
              * to the start
              */
             p = (unsigned char *)s->init_buf->data;
         }
 
         /* Compute the shared pre-master secret */
         field_size = EC_GROUP_get_degree(group);
         if (field_size <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
             goto err;
         }
         i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh,
                              NULL);
         if (i <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB);
             goto err;
         }
 
         EVP_PKEY_free(clnt_pub_pkey);
         EC_POINT_free(clnt_ecpoint);
         EC_KEY_free(srvr_ecdh);
         BN_CTX_free(bn_ctx);
         EC_KEY_free(s->s3->tmp.ecdh);
         s->s3->tmp.ecdh = NULL;
 
         /* Compute the master secret */
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         p, i);
 
         OPENSSL_cleanse(p, i);
         return (ret);
     } else
 #endif
 #ifndef OPENSSL_NO_PSK
     if (alg_k & SSL_kPSK) {
         unsigned char *t = NULL;
         unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4];
         unsigned int pre_ms_len = 0, psk_len = 0;
         int psk_err = 1;
         char tmp_id[PSK_MAX_IDENTITY_LEN + 1];
 
         al = SSL_AD_HANDSHAKE_FAILURE;
 
         n2s(p, i);
         if (n != i + 2) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
             goto psk_err;
         }
         if (i > PSK_MAX_IDENTITY_LEN) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DATA_LENGTH_TOO_LONG);
             goto psk_err;
         }
         if (s->psk_server_callback == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_PSK_NO_SERVER_CB);
             goto psk_err;
         }
 
         /*
          * Create guaranteed NULL-terminated identity string for the callback
          */
         memcpy(tmp_id, p, i);
         memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i);
         psk_len = s->psk_server_callback(s, tmp_id,
                                          psk_or_pre_ms,
                                          sizeof(psk_or_pre_ms));
         OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1);
 
         if (psk_len > PSK_MAX_PSK_LEN) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto psk_err;
         } else if (psk_len == 0) {
             /*
              * PSK related to the given identity not found
              */
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_PSK_IDENTITY_NOT_FOUND);
             al = SSL_AD_UNKNOWN_PSK_IDENTITY;
             goto psk_err;
         }
 
         /* create PSK pre_master_secret */
         pre_ms_len = 2 + psk_len + 2 + psk_len;
         t = psk_or_pre_ms;
         memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len);
         s2n(psk_len, t);
         memset(t, 0, psk_len);
         t += psk_len;
         s2n(psk_len, t);
 
         if (s->session->psk_identity != NULL)
             OPENSSL_free(s->session->psk_identity);
         s->session->psk_identity = BUF_strndup((char *)p, i);
         if (s->session->psk_identity == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto psk_err;
         }
 
         if (s->session->psk_identity_hint != NULL)
             OPENSSL_free(s->session->psk_identity_hint);
         s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint);
         if (s->ctx->psk_identity_hint != NULL &&
             s->session->psk_identity_hint == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto psk_err;
         }
 
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         psk_or_pre_ms,
                                                         pre_ms_len);
         psk_err = 0;
  psk_err:
         OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms));
         if (psk_err != 0)
             goto f_err;
     } else
 #endif
 #ifndef OPENSSL_NO_SRP
     if (alg_k & SSL_kSRP) {
         int param_len;
 
         n2s(p, i);
         param_len = i + 2;
         if (param_len > n) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_BAD_SRP_A_LENGTH);
             goto f_err;
         }
         if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB);
             goto err;
         }
         if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0
             || BN_is_zero(s->srp_ctx.A)) {
             al = SSL_AD_ILLEGAL_PARAMETER;
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_BAD_SRP_PARAMETERS);
             goto f_err;
         }
         if (s->session->srp_username != NULL)
             OPENSSL_free(s->session->srp_username);
         s->session->srp_username = BUF_strdup(s->srp_ctx.login);
         if (s->session->srp_username == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
 
         if ((s->session->master_key_length =
              SRP_generate_server_master_secret(s,
                                                s->session->master_key)) < 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto err;
         }
 
         p += i;
     } else
 #endif                          /* OPENSSL_NO_SRP */
     if (alg_k & SSL_kGOST) {
         int ret = 0;
         EVP_PKEY_CTX *pkey_ctx;
         EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
         unsigned char premaster_secret[32], *start;
         size_t outlen = 32, inlen;
         unsigned long alg_a;
         int Ttag, Tclass;
         long Tlen;
 
         /* Get our certificate private key */
         alg_a = s->s3->tmp.new_cipher->algorithm_auth;
         if (alg_a & SSL_aGOST94)
             pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey;
         else if (alg_a & SSL_aGOST01)
             pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey;
 
         pkey_ctx = EVP_PKEY_CTX_new(pk, NULL);
         if (pkey_ctx == NULL) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
         if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
             goto gerr;
         }
         /*
          * If client certificate is present and is of the same type, maybe
          * use it for key exchange.  Don't mind errors from
          * EVP_PKEY_derive_set_peer, because it is completely valid to use a
          * client certificate for authorization only.
          */
         client_pub_pkey = X509_get_pubkey(s->session->peer);
         if (client_pub_pkey) {
             if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0)
                 ERR_clear_error();
         }
         /* Decrypt session key */
         if (ASN1_get_object
             ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass,
              n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE
             || Tclass != V_ASN1_UNIVERSAL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             goto gerr;
         }
         start = p;
         inlen = Tlen;
         if (EVP_PKEY_decrypt
             (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
                    SSL_R_DECRYPTION_FAILED);
             goto gerr;
         }
         /* Generate master secret */
         s->session->master_key_length =
             s->method->ssl3_enc->generate_master_secret(s,
                                                         s->
                                                         session->master_key,
                                                         premaster_secret, 32);
         OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret));
         /* Check if pubkey from client certificate was used */
         if (EVP_PKEY_CTX_ctrl
             (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0)
             ret = 2;
         else
             ret = 1;
  gerr:
         EVP_PKEY_free(client_pub_pkey);
         EVP_PKEY_CTX_free(pkey_ctx);
         if (ret)
             return ret;
         else
             goto err;
     } else {
         al = SSL_AD_HANDSHAKE_FAILURE;
         SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE);
         goto f_err;
     }
 
     return (1);
  f_err:
     ssl3_send_alert(s, SSL3_AL_FATAL, al);
 #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP)
  err:
 #endif
 #ifndef OPENSSL_NO_ECDH
     EVP_PKEY_free(clnt_pub_pkey);
     EC_POINT_free(clnt_ecpoint);
     if (srvr_ecdh != NULL)
         EC_KEY_free(srvr_ecdh);
     BN_CTX_free(bn_ctx);
 #endif
     s->state = SSL_ST_ERR;
     return (-1);
 }
 
 int ssl3_get_cert_verify(SSL *s)
 {
     EVP_PKEY *pkey = NULL;
     unsigned char *p;
     int al, ok, ret = 0;
     long n;
     int type = 0, i, j;
     X509 *peer;
     const EVP_MD *md = NULL;
     EVP_MD_CTX mctx;
     EVP_MD_CTX_init(&mctx);
 
     /*
      * We should only process a CertificateVerify message if we have received
      * a Certificate from the client. If so then |s->session->peer| will be non
      * NULL. In some instances a CertificateVerify message is not required even
      * if the peer has sent a Certificate (e.g. such as in the case of static
      * DH). In that case the ClientKeyExchange processing will skip the
      * CertificateVerify state so we should not arrive here.
      */
     if (s->session->peer == NULL) {
         ret = 1;
         goto end;
     }
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CERT_VRFY_A,
                                    SSL3_ST_SR_CERT_VRFY_B,
                                    SSL3_MT_CERTIFICATE_VERIFY,
                                    SSL3_RT_MAX_PLAIN_LENGTH, &ok);
 
     if (!ok)
         return ((int)n);
 
     peer = s->session->peer;
     pkey = X509_get_pubkey(peer);
     type = X509_certificate_type(peer, pkey);
 
     if (!(type & EVP_PKT_SIGN)) {
         SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
                SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE);
         al = SSL_AD_ILLEGAL_PARAMETER;
         goto f_err;
     }
 
     /* we now have a signature that we need to verify */
     p = (unsigned char *)s->init_msg;
     /* Check for broken implementations of GOST ciphersuites */
     /*
      * If key is GOST and n is exactly 64, it is bare signature without
      * length field
      */
     if (n == 64 && (pkey->type == NID_id_GostR3410_94 ||
                     pkey->type == NID_id_GostR3410_2001)) {
         i = 64;
     } else {
         if (TLS1_get_version(s) >= TLS1_2_VERSION) {
             int sigalg = tls12_get_sigid(pkey);
             /* Should never happen */
             if (sigalg == -1) {
                 SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
                 al = SSL_AD_INTERNAL_ERROR;
                 goto f_err;
             }
             /* Check key type is consistent with signature */
             if (sigalg != (int)p[1]) {
                 SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,
                        SSL_R_WRONG_SIGNATURE_TYPE);
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
             md = tls12_get_hash(p[0]);
             if (md == NULL) {
                 SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_UNKNOWN_DIGEST);
                 al = SSL_AD_DECODE_ERROR;
                 goto f_err;
             }
 #ifdef SSL_DEBUG
             fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md));
 #endif
             p += 2;
             n -= 2;
         }
         n2s(p, i);
         n -= 2;
         if (i > n) {
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH);
             al = SSL_AD_DECODE_ERROR;
             goto f_err;
         }
     }
     j = EVP_PKEY_size(pkey);
     if ((i > j) || (n > j) || (n <= 0)) {
         SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE);
         al = SSL_AD_DECODE_ERROR;
         goto f_err;
     }
 
     if (TLS1_get_version(s) >= TLS1_2_VERSION) {
         long hdatalen = 0;
         void *hdata;
         hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
         if (hdatalen <= 0) {
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
 #ifdef SSL_DEBUG
         fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n",
                 EVP_MD_name(md));
 #endif
         if (!EVP_VerifyInit_ex(&mctx, md, NULL)
             || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) {
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB);
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
 
         if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) {
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE);
             goto f_err;
         }
     } else
 #ifndef OPENSSL_NO_RSA
     if (pkey->type == EVP_PKEY_RSA) {
         i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md,
                        MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i,
                        pkey->pkey.rsa);
         if (i < 0) {
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT);
             goto f_err;
         }
         if (i == 0) {
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE);
             goto f_err;
         }
     } else
 #endif
 #ifndef OPENSSL_NO_DSA
     if (pkey->type == EVP_PKEY_DSA) {
         j = DSA_verify(pkey->save_type,
                        &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
                        SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa);
         if (j <= 0) {
             /* bad signature */
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE);
             goto f_err;
         }
     } else
 #endif
 #ifndef OPENSSL_NO_ECDSA
     if (pkey->type == EVP_PKEY_EC) {
         j = ECDSA_verify(pkey->save_type,
                          &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]),
                          SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec);
         if (j <= 0) {
             /* bad signature */
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
             goto f_err;
         }
     } else
 #endif
     if (pkey->type == NID_id_GostR3410_94
             || pkey->type == NID_id_GostR3410_2001) {
         unsigned char signature[64];
         int idx;
         EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL);
         if (pctx == NULL) {
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE);
             goto f_err;
         }
         if (EVP_PKEY_verify_init(pctx) <= 0) {
             EVP_PKEY_CTX_free(pctx);
             al = SSL_AD_INTERNAL_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
             goto f_err;
         }
         if (i != 64) {
             fprintf(stderr, "GOST signature length is %d", i);
         }
         for (idx = 0; idx < 64; idx++) {
             signature[63 - idx] = p[idx];
         }
         j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md,
                             32);
         EVP_PKEY_CTX_free(pctx);
         if (j <= 0) {
             al = SSL_AD_DECRYPT_ERROR;
             SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE);
             goto f_err;
         }
     } else {
         SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR);
         al = SSL_AD_UNSUPPORTED_CERTIFICATE;
         goto f_err;
     }
 
     ret = 1;
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
         s->state = SSL_ST_ERR;
     }
  end:
     if (s->s3->handshake_buffer) {
         BIO_free(s->s3->handshake_buffer);
         s->s3->handshake_buffer = NULL;
         s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE;
     }
     EVP_MD_CTX_cleanup(&mctx);
     EVP_PKEY_free(pkey);
     return (ret);
 }
 
 int ssl3_get_client_certificate(SSL *s)
 {
     int i, ok, al, ret = -1;
     X509 *x = NULL;
     unsigned long l, nc, llen, n;
     const unsigned char *p, *q;
     unsigned char *d;
     STACK_OF(X509) *sk = NULL;
 
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_CERT_A,
                                    SSL3_ST_SR_CERT_B,
                                    -1, s->max_cert_list, &ok);
 
     if (!ok)
         return ((int)n);
 
     if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
         if ((s->verify_mode & SSL_VERIFY_PEER) &&
             (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
             al = SSL_AD_HANDSHAKE_FAILURE;
             goto f_err;
         }
         /*
          * If tls asked for a client cert, the client must return a 0 list
          */
         if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
             al = SSL_AD_UNEXPECTED_MESSAGE;
             goto f_err;
         }
         s->s3->tmp.reuse_message = 1;
         return (1);
     }
 
     if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
         al = SSL_AD_UNEXPECTED_MESSAGE;
         SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE);
         goto f_err;
     }
     p = d = (unsigned char *)s->init_msg;
 
     if ((sk = sk_X509_new_null()) == NULL) {
         SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
 
     n2l3(p, llen);
     if (llen + 3 != n) {
         al = SSL_AD_DECODE_ERROR;
         SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH);
         goto f_err;
     }
     for (nc = 0; nc < llen;) {
+        if (nc + 3 > llen) {
+            al = SSL_AD_DECODE_ERROR;
+            SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+                   SSL_R_CERT_LENGTH_MISMATCH);
+            goto f_err;
+        }
         n2l3(p, l);
         if ((l + nc + 3) > llen) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_CERT_LENGTH_MISMATCH);
             goto f_err;
         }
 
         q = p;
         x = d2i_X509(NULL, &p, l);
         if (x == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB);
             goto err;
         }
         if (p != (q + l)) {
             al = SSL_AD_DECODE_ERROR;
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_CERT_LENGTH_MISMATCH);
             goto f_err;
         }
         if (!sk_X509_push(sk, x)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
         x = NULL;
         nc += l + 3;
     }
 
     if (sk_X509_num(sk) <= 0) {
         /* TLS does not mind 0 certs returned */
         if (s->version == SSL3_VERSION) {
             al = SSL_AD_HANDSHAKE_FAILURE;
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_NO_CERTIFICATES_RETURNED);
             goto f_err;
         }
         /* Fail for TLS only if we required a certificate */
         else if ((s->verify_mode & SSL_VERIFY_PEER) &&
                  (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
             al = SSL_AD_HANDSHAKE_FAILURE;
             goto f_err;
         }
         /* No client certificate so digest cached records */
         if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) {
             al = SSL_AD_INTERNAL_ERROR;
             goto f_err;
         }
     } else {
         i = ssl_verify_cert_chain(s, sk);
         if (i <= 0) {
             al = ssl_verify_alarm_type(s->verify_result);
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
                    SSL_R_NO_CERTIFICATE_RETURNED);
             goto f_err;
         }
     }
 
     if (s->session->peer != NULL) /* This should not be needed */
         X509_free(s->session->peer);
     s->session->peer = sk_X509_shift(sk);
     s->session->verify_result = s->verify_result;
 
     /*
      * With the current implementation, sess_cert will always be NULL when we
      * arrive here.
      */
     if (s->session->sess_cert == NULL) {
         s->session->sess_cert = ssl_sess_cert_new();
         if (s->session->sess_cert == NULL) {
             SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE);
             goto err;
         }
     }
     if (s->session->sess_cert->cert_chain != NULL)
         sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
     s->session->sess_cert->cert_chain = sk;
     /*
      * Inconsistency alert: cert_chain does *not* include the peer's own
      * certificate, while we do include it in s3_clnt.c
      */
 
     sk = NULL;
 
     ret = 1;
     if (0) {
  f_err:
         ssl3_send_alert(s, SSL3_AL_FATAL, al);
  err:
         s->state = SSL_ST_ERR;
     }
 
     if (x != NULL)
         X509_free(x);
     if (sk != NULL)
         sk_X509_pop_free(sk, X509_free);
     return (ret);
 }
 
 int ssl3_send_server_certificate(SSL *s)
 {
     unsigned long l;
     X509 *x;
 
     if (s->state == SSL3_ST_SW_CERT_A) {
         x = ssl_get_server_send_cert(s);
         if (x == NULL) {
             /* VRS: allow null cert if auth == KRB5 */
             if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) ||
                 (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) {
                 SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE,
                        ERR_R_INTERNAL_ERROR);
                 s->state = SSL_ST_ERR;
                 return (0);
             }
         }
 
         l = ssl3_output_cert_chain(s, x);
         if (!l) {
             SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR);
             s->state = SSL_ST_ERR;
             return (0);
         }
         s->state = SSL3_ST_SW_CERT_B;
         s->init_num = (int)l;
         s->init_off = 0;
     }
 
     /* SSL3_ST_SW_CERT_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 /* send a new session ticket (not necessarily for a new session) */
 int ssl3_send_newsession_ticket(SSL *s)
 {
     unsigned char *senc = NULL;
     EVP_CIPHER_CTX ctx;
     HMAC_CTX hctx;
 
     if (s->state == SSL3_ST_SW_SESSION_TICKET_A) {
         unsigned char *p, *macstart;
         const unsigned char *const_p;
         int len, slen_full, slen;
         SSL_SESSION *sess;
         unsigned int hlen;
         SSL_CTX *tctx = s->initial_ctx;
         unsigned char iv[EVP_MAX_IV_LENGTH];
         unsigned char key_name[16];
 
         /* get session encoding length */
         slen_full = i2d_SSL_SESSION(s->session, NULL);
         /*
          * Some length values are 16 bits, so forget it if session is too
          * long
          */
         if (slen_full == 0 || slen_full > 0xFF00) {
             s->state = SSL_ST_ERR;
             return -1;
         }
         senc = OPENSSL_malloc(slen_full);
         if (!senc) {
             s->state = SSL_ST_ERR;
             return -1;
         }
 
         EVP_CIPHER_CTX_init(&ctx);
         HMAC_CTX_init(&hctx);
 
         p = senc;
         if (!i2d_SSL_SESSION(s->session, &p))
             goto err;
 
         /*
          * create a fresh copy (not shared with other threads) to clean up
          */
         const_p = senc;
         sess = d2i_SSL_SESSION(NULL, &const_p, slen_full);
         if (sess == NULL)
             goto err;
         sess->session_id_length = 0; /* ID is irrelevant for the ticket */
 
         slen = i2d_SSL_SESSION(sess, NULL);
         if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */
             SSL_SESSION_free(sess);
             goto err;
         }
         p = senc;
         if (!i2d_SSL_SESSION(sess, &p)) {
             SSL_SESSION_free(sess);
             goto err;
         }
         SSL_SESSION_free(sess);
 
         /*-
          * Grow buffer if need be: the length calculation is as
          * follows 1 (size of message name) + 3 (message length
          * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) +
          * 16 (key name) + max_iv_len (iv length) +
          * session_length + max_enc_block_size (max encrypted session
          * length) + max_md_size (HMAC).
          */
         if (!BUF_MEM_grow(s->init_buf,
                           26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH +
                           EVP_MAX_MD_SIZE + slen))
             goto err;
 
         p = (unsigned char *)s->init_buf->data;
         /* do the header */
         *(p++) = SSL3_MT_NEWSESSION_TICKET;
         /* Skip message length for now */
         p += 3;
         /*
          * Initialize HMAC and cipher contexts. If callback present it does
          * all the work otherwise use generated values from parent ctx.
          */
         if (tctx->tlsext_ticket_key_cb) {
             if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
                                            &hctx, 1) < 0)
                 goto err;
         } else {
             if (RAND_bytes(iv, 16) <= 0)
                 goto err;
             if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                                     tctx->tlsext_tick_aes_key, iv))
                 goto err;
             if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
                               tlsext_tick_md(), NULL))
                 goto err;
             memcpy(key_name, tctx->tlsext_tick_key_name, 16);
         }
 
         /*
          * Ticket lifetime hint (advisory only): We leave this unspecified
          * for resumed session (for simplicity), and guess that tickets for
          * new sessions will live as long as their sessions.
          */
         l2n(s->hit ? 0 : s->session->timeout, p);
 
         /* Skip ticket length for now */
         p += 2;
         /* Output key name */
         macstart = p;
         memcpy(p, key_name, 16);
         p += 16;
         /* output IV */
         memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx));
         p += EVP_CIPHER_CTX_iv_length(&ctx);
         /* Encrypt session data */
         if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen))
             goto err;
         p += len;
         if (!EVP_EncryptFinal(&ctx, p, &len))
             goto err;
         p += len;
 
         if (!HMAC_Update(&hctx, macstart, p - macstart))
             goto err;
         if (!HMAC_Final(&hctx, p, &hlen))
             goto err;
 
         EVP_CIPHER_CTX_cleanup(&ctx);
         HMAC_CTX_cleanup(&hctx);
 
         p += hlen;
         /* Now write out lengths: p points to end of data written */
         /* Total length */
         len = p - (unsigned char *)s->init_buf->data;
         p = (unsigned char *)s->init_buf->data + 1;
         l2n3(len - 4, p);       /* Message length */
         p += 4;
         s2n(len - 10, p);       /* Ticket length */
 
         /* number of bytes to write */
         s->init_num = len;
         s->state = SSL3_ST_SW_SESSION_TICKET_B;
         s->init_off = 0;
         OPENSSL_free(senc);
     }
 
     /* SSL3_ST_SW_SESSION_TICKET_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
  err:
     if (senc)
         OPENSSL_free(senc);
     EVP_CIPHER_CTX_cleanup(&ctx);
     HMAC_CTX_cleanup(&hctx);
     s->state = SSL_ST_ERR;
     return -1;
 }
 
 int ssl3_send_cert_status(SSL *s)
 {
     if (s->state == SSL3_ST_SW_CERT_STATUS_A) {
         unsigned char *p;
         /*-
          * Grow buffer if need be: the length calculation is as
          * follows 1 (message type) + 3 (message length) +
          * 1 (ocsp response type) + 3 (ocsp response length)
          * + (ocsp response)
          */
         if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) {
             s->state = SSL_ST_ERR;
             return -1;
         }
 
         p = (unsigned char *)s->init_buf->data;
 
         /* do the header */
         *(p++) = SSL3_MT_CERTIFICATE_STATUS;
         /* message length */
         l2n3(s->tlsext_ocsp_resplen + 4, p);
         /* status type */
         *(p++) = s->tlsext_status_type;
         /* length of OCSP response */
         l2n3(s->tlsext_ocsp_resplen, p);
         /* actual response */
         memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
         /* number of bytes to write */
         s->init_num = 8 + s->tlsext_ocsp_resplen;
         s->state = SSL3_ST_SW_CERT_STATUS_B;
         s->init_off = 0;
     }
 
     /* SSL3_ST_SW_CERT_STATUS_B */
     return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message.
  * It sets the next_proto member in s if found
  */
 int ssl3_get_next_proto(SSL *s)
 {
     int ok;
     int proto_len, padding_len;
     long n;
     const unsigned char *p;
 
     /*
      * Clients cannot send a NextProtocol message if we didn't see the
      * extension in their ClientHello
      */
     if (!s->s3->next_proto_neg_seen) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO,
                SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
         s->state = SSL_ST_ERR;
         return -1;
     }
 
     /* See the payload format below */
     n = s->method->ssl_get_message(s,
                                    SSL3_ST_SR_NEXT_PROTO_A,
                                    SSL3_ST_SR_NEXT_PROTO_B,
                                    SSL3_MT_NEXT_PROTO, 514, &ok);
 
     if (!ok)
         return ((int)n);
 
     /*
      * s->state doesn't reflect whether ChangeCipherSpec has been received in
      * this handshake, but s->s3->change_cipher_spec does (will be reset by
      * ssl3_get_finished).
      */
     if (!s->s3->change_cipher_spec) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
         s->state = SSL_ST_ERR;
         return -1;
     }
 
     if (n < 2) {
         s->state = SSL_ST_ERR;
         return 0;               /* The body must be > 1 bytes long */
     }
 
     p = (unsigned char *)s->init_msg;
 
     /*-
      * The payload looks like:
      *   uint8 proto_len;
      *   uint8 proto[proto_len];
      *   uint8 padding_len;
      *   uint8 padding[padding_len];
      */
     proto_len = p[0];
     if (proto_len + 2 > s->init_num) {
         s->state = SSL_ST_ERR;
         return 0;
     }
     padding_len = p[proto_len + 1];
     if (proto_len + padding_len + 2 != s->init_num) {
         s->state = SSL_ST_ERR;
         return 0;
     }
 
     s->next_proto_negotiated = OPENSSL_malloc(proto_len);
     if (!s->next_proto_negotiated) {
         SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE);
         s->state = SSL_ST_ERR;
         return 0;
     }
     memcpy(s->next_proto_negotiated, p + 1, proto_len);
     s->next_proto_negotiated_len = proto_len;
 
     return 1;
 }
 # endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/ssl.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/ssl.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/ssl.h	(revision 306191)
@@ -1,2770 +1,2771 @@
 /* ssl/ssl.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.]
  */
 /* ====================================================================
  * 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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  * ECC cipher suite support in OpenSSL originally developed by
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #ifndef HEADER_SSL_H
 # define HEADER_SSL_H
 
 # include <openssl/e_os2.h>
 
 # ifndef OPENSSL_NO_COMP
 #  include <openssl/comp.h>
 # endif
 # ifndef OPENSSL_NO_BIO
 #  include <openssl/bio.h>
 # endif
 # ifndef OPENSSL_NO_DEPRECATED
 #  ifndef OPENSSL_NO_X509
 #   include <openssl/x509.h>
 #  endif
 #  include <openssl/crypto.h>
 #  include <openssl/lhash.h>
 #  include <openssl/buffer.h>
 # endif
 # include <openssl/pem.h>
 # include <openssl/hmac.h>
 
 # include <openssl/kssl.h>
 # include <openssl/safestack.h>
 # include <openssl/symhacks.h>
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 /* SSLeay version number for ASN.1 encoding of the session information */
 /*-
  * Version 0 - initial version
  * Version 1 - added the optional peer certificate
  */
 # define SSL_SESSION_ASN1_VERSION 0x0001
 
 /* text strings for the ciphers */
 # define SSL_TXT_NULL_WITH_MD5           SSL2_TXT_NULL_WITH_MD5
 # define SSL_TXT_RC4_128_WITH_MD5        SSL2_TXT_RC4_128_WITH_MD5
 # define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5
 # define SSL_TXT_RC2_128_CBC_WITH_MD5    SSL2_TXT_RC2_128_CBC_WITH_MD5
 # define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5
 # define SSL_TXT_IDEA_128_CBC_WITH_MD5   SSL2_TXT_IDEA_128_CBC_WITH_MD5
 # define SSL_TXT_DES_64_CBC_WITH_MD5     SSL2_TXT_DES_64_CBC_WITH_MD5
 # define SSL_TXT_DES_64_CBC_WITH_SHA     SSL2_TXT_DES_64_CBC_WITH_SHA
 # define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5
 # define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA
 
 /*
  * VRS Additional Kerberos5 entries
  */
 # define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
 # define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
 # define SSL_TXT_KRB5_RC4_128_SHA      SSL3_TXT_KRB5_RC4_128_SHA
 # define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA
 # define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
 # define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
 # define SSL_TXT_KRB5_RC4_128_MD5      SSL3_TXT_KRB5_RC4_128_MD5
 # define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5
 
 # define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
 # define SSL_TXT_KRB5_RC2_40_CBC_SHA   SSL3_TXT_KRB5_RC2_40_CBC_SHA
 # define SSL_TXT_KRB5_RC4_40_SHA       SSL3_TXT_KRB5_RC4_40_SHA
 # define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
 # define SSL_TXT_KRB5_RC2_40_CBC_MD5   SSL3_TXT_KRB5_RC2_40_CBC_MD5
 # define SSL_TXT_KRB5_RC4_40_MD5       SSL3_TXT_KRB5_RC4_40_MD5
 
 # define SSL_TXT_KRB5_DES_40_CBC_SHA   SSL3_TXT_KRB5_DES_40_CBC_SHA
 # define SSL_TXT_KRB5_DES_40_CBC_MD5   SSL3_TXT_KRB5_DES_40_CBC_MD5
 # define SSL_TXT_KRB5_DES_64_CBC_SHA   SSL3_TXT_KRB5_DES_64_CBC_SHA
 # define SSL_TXT_KRB5_DES_64_CBC_MD5   SSL3_TXT_KRB5_DES_64_CBC_MD5
 # define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA
 # define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5
 # define SSL_MAX_KRB5_PRINCIPAL_LENGTH  256
 
 # define SSL_MAX_SSL_SESSION_ID_LENGTH           32
 # define SSL_MAX_SID_CTX_LENGTH                  32
 
 # define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES     (512/8)
 # define SSL_MAX_KEY_ARG_LENGTH                  8
 # define SSL_MAX_MASTER_KEY_LENGTH               48
 
 /* These are used to specify which ciphers to use and not to use */
 
 # define SSL_TXT_EXP40           "EXPORT40"
 # define SSL_TXT_EXP56           "EXPORT56"
 # define SSL_TXT_LOW             "LOW"
 # define SSL_TXT_MEDIUM          "MEDIUM"
 # define SSL_TXT_HIGH            "HIGH"
 # define SSL_TXT_FIPS            "FIPS"
 
 # define SSL_TXT_kFZA            "kFZA"/* unused! */
 # define SSL_TXT_aFZA            "aFZA"/* unused! */
 # define SSL_TXT_eFZA            "eFZA"/* unused! */
 # define SSL_TXT_FZA             "FZA"/* unused! */
 
 # define SSL_TXT_aNULL           "aNULL"
 # define SSL_TXT_eNULL           "eNULL"
 # define SSL_TXT_NULL            "NULL"
 
 # define SSL_TXT_kRSA            "kRSA"
 # define SSL_TXT_kDHr            "kDHr"/* no such ciphersuites supported! */
 # define SSL_TXT_kDHd            "kDHd"/* no such ciphersuites supported! */
 # define SSL_TXT_kDH             "kDH"/* no such ciphersuites supported! */
 # define SSL_TXT_kEDH            "kEDH"
 # define SSL_TXT_kKRB5           "kKRB5"
 # define SSL_TXT_kECDHr          "kECDHr"
 # define SSL_TXT_kECDHe          "kECDHe"
 # define SSL_TXT_kECDH           "kECDH"
 # define SSL_TXT_kEECDH          "kEECDH"
 # define SSL_TXT_kPSK            "kPSK"
 # define SSL_TXT_kGOST           "kGOST"
 # define SSL_TXT_kSRP            "kSRP"
 
 # define SSL_TXT_aRSA            "aRSA"
 # define SSL_TXT_aDSS            "aDSS"
 # define SSL_TXT_aDH             "aDH"/* no such ciphersuites supported! */
 # define SSL_TXT_aECDH           "aECDH"
 # define SSL_TXT_aKRB5           "aKRB5"
 # define SSL_TXT_aECDSA          "aECDSA"
 # define SSL_TXT_aPSK            "aPSK"
 # define SSL_TXT_aGOST94 "aGOST94"
 # define SSL_TXT_aGOST01 "aGOST01"
 # define SSL_TXT_aGOST  "aGOST"
 # define SSL_TXT_aSRP            "aSRP"
 
 # define SSL_TXT_DSS             "DSS"
 # define SSL_TXT_DH              "DH"
 # define SSL_TXT_EDH             "EDH"/* same as "kEDH:-ADH" */
 # define SSL_TXT_ADH             "ADH"
 # define SSL_TXT_RSA             "RSA"
 # define SSL_TXT_ECDH            "ECDH"
 # define SSL_TXT_EECDH           "EECDH"/* same as "kEECDH:-AECDH" */
 # define SSL_TXT_AECDH           "AECDH"
 # define SSL_TXT_ECDSA           "ECDSA"
 # define SSL_TXT_KRB5            "KRB5"
 # define SSL_TXT_PSK             "PSK"
 # define SSL_TXT_SRP             "SRP"
 
 # define SSL_TXT_DES             "DES"
 # define SSL_TXT_3DES            "3DES"
 # define SSL_TXT_RC4             "RC4"
 # define SSL_TXT_RC2             "RC2"
 # define SSL_TXT_IDEA            "IDEA"
 # define SSL_TXT_SEED            "SEED"
 # define SSL_TXT_AES128          "AES128"
 # define SSL_TXT_AES256          "AES256"
 # define SSL_TXT_AES             "AES"
 # define SSL_TXT_AES_GCM         "AESGCM"
 # define SSL_TXT_CAMELLIA128     "CAMELLIA128"
 # define SSL_TXT_CAMELLIA256     "CAMELLIA256"
 # define SSL_TXT_CAMELLIA        "CAMELLIA"
 
 # define SSL_TXT_MD5             "MD5"
 # define SSL_TXT_SHA1            "SHA1"
 # define SSL_TXT_SHA             "SHA"/* same as "SHA1" */
 # define SSL_TXT_GOST94          "GOST94"
 # define SSL_TXT_GOST89MAC               "GOST89MAC"
 # define SSL_TXT_SHA256          "SHA256"
 # define SSL_TXT_SHA384          "SHA384"
 
 # define SSL_TXT_SSLV2           "SSLv2"
 # define SSL_TXT_SSLV3           "SSLv3"
 # define SSL_TXT_TLSV1           "TLSv1"
 # define SSL_TXT_TLSV1_1         "TLSv1.1"
 # define SSL_TXT_TLSV1_2         "TLSv1.2"
 
 # define SSL_TXT_EXP             "EXP"
 # define SSL_TXT_EXPORT          "EXPORT"
 
 # define SSL_TXT_ALL             "ALL"
 
 /*-
  * COMPLEMENTOF* definitions. These identifiers are used to (de-select)
  * ciphers normally not being used.
  * Example: "RC4" will activate all ciphers using RC4 including ciphers
  * without authentication, which would normally disabled by DEFAULT (due
  * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT"
  * will make sure that it is also disabled in the specific selection.
  * COMPLEMENTOF* identifiers are portable between version, as adjustments
  * to the default cipher setup will also be included here.
  *
  * COMPLEMENTOFDEFAULT does not experience the same special treatment that
  * DEFAULT gets, as only selection is being done and no sorting as needed
  * for DEFAULT.
  */
 # define SSL_TXT_CMPALL          "COMPLEMENTOFALL"
 # define SSL_TXT_CMPDEF          "COMPLEMENTOFDEFAULT"
 
 /*
  * The following cipher list is used by default. It also is substituted when
  * an application-defined cipher list string starts with 'DEFAULT'.
  */
 # define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2"
 /*
  * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always
  * starts with a reasonable order, and all we have to do for DEFAULT is
  * throwing out anonymous and unencrypted ciphersuites! (The latter are not
  * actually enabled by ALL, but "ALL:RSA" would enable some of them.)
  */
 
 /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
 # define SSL_SENT_SHUTDOWN       1
 # define SSL_RECEIVED_SHUTDOWN   2
 
 #ifdef __cplusplus
 }
 #endif
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 # if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2)
 #  define OPENSSL_NO_SSL2
 # endif
 
 # define SSL_FILETYPE_ASN1       X509_FILETYPE_ASN1
 # define SSL_FILETYPE_PEM        X509_FILETYPE_PEM
 
 /*
  * This is needed to stop compilers complaining about the 'struct ssl_st *'
  * function parameters used to prototype callbacks in SSL_CTX.
  */
 typedef struct ssl_st *ssl_crock_st;
 typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT;
 typedef struct ssl_method_st SSL_METHOD;
 typedef struct ssl_cipher_st SSL_CIPHER;
 typedef struct ssl_session_st SSL_SESSION;
 
 DECLARE_STACK_OF(SSL_CIPHER)
 
 /* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/
 typedef struct srtp_protection_profile_st {
     const char *name;
     unsigned long id;
 } SRTP_PROTECTION_PROFILE;
 
 DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
 
 typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s,
                                              const unsigned char *data,
                                              int len, void *arg);
 typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret,
                                          int *secret_len,
                                          STACK_OF(SSL_CIPHER) *peer_ciphers,
                                          SSL_CIPHER **cipher, void *arg);
 
 # ifndef OPENSSL_NO_SSL_INTERN
 
 /* used to hold info on the particular ciphers used */
 struct ssl_cipher_st {
     int valid;
     const char *name;           /* text name */
     unsigned long id;           /* id, 4 bytes, first is version */
     /*
      * changed in 0.9.9: these four used to be portions of a single value
      * 'algorithms'
      */
     unsigned long algorithm_mkey; /* key exchange algorithm */
     unsigned long algorithm_auth; /* server authentication */
     unsigned long algorithm_enc; /* symmetric encryption */
     unsigned long algorithm_mac; /* symmetric authentication */
     unsigned long algorithm_ssl; /* (major) protocol version */
     unsigned long algo_strength; /* strength and export flags */
     unsigned long algorithm2;   /* Extra flags */
     int strength_bits;          /* Number of bits really used */
     int alg_bits;               /* Number of bits for algorithm */
 };
 
 /* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */
 struct ssl_method_st {
     int version;
     int (*ssl_new) (SSL *s);
     void (*ssl_clear) (SSL *s);
     void (*ssl_free) (SSL *s);
     int (*ssl_accept) (SSL *s);
     int (*ssl_connect) (SSL *s);
     int (*ssl_read) (SSL *s, void *buf, int len);
     int (*ssl_peek) (SSL *s, void *buf, int len);
     int (*ssl_write) (SSL *s, const void *buf, int len);
     int (*ssl_shutdown) (SSL *s);
     int (*ssl_renegotiate) (SSL *s);
     int (*ssl_renegotiate_check) (SSL *s);
     long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long
                              max, int *ok);
     int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len,
                            int peek);
     int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len);
     int (*ssl_dispatch_alert) (SSL *s);
     long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg);
     long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg);
     const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr);
     int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr);
     int (*ssl_pending) (const SSL *s);
     int (*num_ciphers) (void);
     const SSL_CIPHER *(*get_cipher) (unsigned ncipher);
     const struct ssl_method_st *(*get_ssl_method) (int version);
     long (*get_timeout) (void);
     struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */
     int (*ssl_version) (void);
     long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void));
     long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void));
 };
 
 /*-
  * Lets make this into an ASN.1 type structure as follows
  * SSL_SESSION_ID ::= SEQUENCE {
  *      version                 INTEGER,        -- structure version number
  *      SSLversion              INTEGER,        -- SSL version number
  *      Cipher                  OCTET STRING,   -- the 3 byte cipher ID
  *      Session_ID              OCTET STRING,   -- the Session ID
  *      Master_key              OCTET STRING,   -- the master key
  *      KRB5_principal          OCTET STRING    -- optional Kerberos principal
  *      Key_Arg [ 0 ] IMPLICIT  OCTET STRING,   -- the optional Key argument
  *      Time [ 1 ] EXPLICIT     INTEGER,        -- optional Start Time
  *      Timeout [ 2 ] EXPLICIT  INTEGER,        -- optional Timeout ins seconds
  *      Peer [ 3 ] EXPLICIT     X509,           -- optional Peer Certificate
  *      Session_ID_context [ 4 ] EXPLICIT OCTET STRING,   -- the Session ID context
  *      Verify_result [ 5 ] EXPLICIT INTEGER,   -- X509_V_... code for `Peer'
  *      HostName [ 6 ] EXPLICIT OCTET STRING,   -- optional HostName from servername TLS extension
  *      PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint
  *      PSK_identity [ 8 ] EXPLICIT OCTET STRING,  -- optional PSK identity
  *      Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket
  *      Ticket [10]             EXPLICIT OCTET STRING, -- session ticket (clients only)
  *      Compression_meth [11]   EXPLICIT OCTET STRING, -- optional compression method
  *      SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username
  *      }
  * Look in ssl/ssl_asn1.c for more details
  * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-).
  */
 struct ssl_session_st {
     int ssl_version;            /* what ssl version session info is being
                                  * kept in here? */
     /* only really used in SSLv2 */
     unsigned int key_arg_length;
     unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH];
     int master_key_length;
     unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH];
     /* session_id - valid? */
     unsigned int session_id_length;
     unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
     /*
      * this is used to determine whether the session is being reused in the
      * appropriate context. It is up to the application to set this, via
      * SSL_new
      */
     unsigned int sid_ctx_length;
     unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
 #  ifndef OPENSSL_NO_KRB5
     unsigned int krb5_client_princ_len;
     unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH];
 #  endif                        /* OPENSSL_NO_KRB5 */
 #  ifndef OPENSSL_NO_PSK
     char *psk_identity_hint;
     char *psk_identity;
 #  endif
     /*
      * Used to indicate that session resumption is not allowed. Applications
      * can also set this bit for a new session via not_resumable_session_cb
      * to disable session caching and tickets.
      */
     int not_resumable;
     /* The cert is the certificate used to establish this connection */
     struct sess_cert_st /* SESS_CERT */ *sess_cert;
     /*
      * This is the cert for the other end. On clients, it will be the same as
      * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is
      * not retained in the external representation of sessions, see
      * ssl_asn1.c).
      */
     X509 *peer;
     /*
      * when app_verify_callback accepts a session where the peer's
      * certificate is not ok, we must remember the error for session reuse:
      */
     long verify_result;         /* only for servers */
     int references;
     long timeout;
     long time;
     unsigned int compress_meth; /* Need to lookup the method */
     const SSL_CIPHER *cipher;
     unsigned long cipher_id;    /* when ASN.1 loaded, this needs to be used
                                  * to load the 'cipher' structure */
     STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */
     CRYPTO_EX_DATA ex_data;     /* application specific data */
     /*
      * These are used to make removal of session-ids more efficient and to
      * implement a maximum cache size.
      */
     struct ssl_session_st *prev, *next;
 #  ifndef OPENSSL_NO_TLSEXT
     char *tlsext_hostname;
 #   ifndef OPENSSL_NO_EC
     size_t tlsext_ecpointformatlist_length;
     unsigned char *tlsext_ecpointformatlist; /* peer's list */
     size_t tlsext_ellipticcurvelist_length;
     unsigned char *tlsext_ellipticcurvelist; /* peer's list */
 #   endif                       /* OPENSSL_NO_EC */
     /* RFC4507 info */
     unsigned char *tlsext_tick; /* Session ticket */
     size_t tlsext_ticklen;      /* Session ticket length */
     long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
 #  endif
 #  ifndef OPENSSL_NO_SRP
     char *srp_username;
 #  endif
 };
 
 # endif
 
 # define SSL_OP_MICROSOFT_SESS_ID_BUG                    0x00000001L
 # define SSL_OP_NETSCAPE_CHALLENGE_BUG                   0x00000002L
 /* Allow initial connection to servers that don't support RI */
 # define SSL_OP_LEGACY_SERVER_CONNECT                    0x00000004L
 # define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG         0x00000008L
 # define SSL_OP_TLSEXT_PADDING                           0x00000010L
 # define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER               0x00000020L
 # define SSL_OP_SAFARI_ECDHE_ECDSA_BUG                   0x00000040L
 # define SSL_OP_SSLEAY_080_CLIENT_DH_BUG                 0x00000080L
 # define SSL_OP_TLS_D5_BUG                               0x00000100L
 # define SSL_OP_TLS_BLOCK_PADDING_BUG                    0x00000200L
 
 /* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */
 # define SSL_OP_MSIE_SSLV2_RSA_PADDING                   0x0
 /* Refers to ancient SSLREF and SSLv2, retained for compatibility */
 # define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG              0x0
 
 /*
  * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in
  * OpenSSL 0.9.6d.  Usually (depending on the application protocol) the
  * workaround is not needed.  Unfortunately some broken SSL/TLS
  * implementations cannot handle it at all, which is why we include it in
  * SSL_OP_ALL.
  */
 /* added in 0.9.6e */
 # define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS              0x00000800L
 
 /*
  * SSL_OP_ALL: various bug workarounds that should be rather harmless.  This
  * used to be 0x000FFFFFL before 0.9.7.
  */
 # define SSL_OP_ALL                                      0x80000BFFL
 
 /* DTLS options */
 # define SSL_OP_NO_QUERY_MTU                 0x00001000L
 /* Turn on Cookie Exchange (on relevant for servers) */
 # define SSL_OP_COOKIE_EXCHANGE              0x00002000L
 /* Don't use RFC4507 ticket extension */
 # define SSL_OP_NO_TICKET                    0x00004000L
 /* Use Cisco's "speshul" version of DTLS_BAD_VER (as client)  */
 # define SSL_OP_CISCO_ANYCONNECT             0x00008000L
 
 /* As server, disallow session resumption on renegotiation */
 # define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION   0x00010000L
 /* Don't use compression even if supported */
 # define SSL_OP_NO_COMPRESSION                           0x00020000L
 /* Permit unsafe legacy renegotiation */
 # define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION        0x00040000L
 /* If set, always create a new key when using tmp_ecdh parameters */
 # define SSL_OP_SINGLE_ECDH_USE                          0x00080000L
 /* Does nothing: retained for compatibility */
 # define SSL_OP_SINGLE_DH_USE                            0x00100000L
 /* Does nothing: retained for compatibiity */
 # define SSL_OP_EPHEMERAL_RSA                            0x0
 /*
  * Set on servers to choose the cipher according to the server's preferences
  */
 # define SSL_OP_CIPHER_SERVER_PREFERENCE                 0x00400000L
 /*
  * If set, a server will allow a client to issue a SSLv3.0 version number as
  * latest version supported in the premaster secret, even when TLSv1.0
  * (version 3.1) was announced in the client hello. Normally this is
  * forbidden to prevent version rollback attacks.
  */
 # define SSL_OP_TLS_ROLLBACK_BUG                         0x00800000L
 
 # define SSL_OP_NO_SSLv2                                 0x01000000L
 # define SSL_OP_NO_SSLv3                                 0x02000000L
 # define SSL_OP_NO_TLSv1                                 0x04000000L
 # define SSL_OP_NO_TLSv1_2                               0x08000000L
 # define SSL_OP_NO_TLSv1_1                               0x10000000L
 
 /*
  * These next two were never actually used for anything since SSLeay zap so
  * we have some more flags.
  */
 /*
  * The next flag deliberately changes the ciphertest, this is a check for the
  * PKCS#1 attack
  */
 # define SSL_OP_PKCS1_CHECK_1                            0x0
 # define SSL_OP_PKCS1_CHECK_2                            0x0
 
 # define SSL_OP_NETSCAPE_CA_DN_BUG                       0x20000000L
 # define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG          0x40000000L
 /*
  * Make server add server-hello extension from early version of cryptopro
  * draft, when GOST ciphersuite is negotiated. Required for interoperability
  * with CryptoPro CSP 3.x
  */
 # define SSL_OP_CRYPTOPRO_TLSEXT_BUG                     0x80000000L
 
 /*
  * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
  * when just a single record has been written):
  */
 # define SSL_MODE_ENABLE_PARTIAL_WRITE       0x00000001L
 /*
  * Make it possible to retry SSL_write() with changed buffer location (buffer
  * contents must stay the same!); this is not the default to avoid the
  * misconception that non-blocking SSL_write() behaves like non-blocking
  * write():
  */
 # define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L
 /*
  * Never bother the application with retries if the transport is blocking:
  */
 # define SSL_MODE_AUTO_RETRY 0x00000004L
 /* Don't attempt to automatically build certificate chain */
 # define SSL_MODE_NO_AUTO_CHAIN 0x00000008L
 /*
  * Save RAM by releasing read and write buffers when they're empty. (SSL3 and
  * TLS only.) "Released" buffers are put onto a free-list in the context or
  * just freed (depending on the context's setting for freelist_max_len).
  */
 # define SSL_MODE_RELEASE_BUFFERS 0x00000010L
 /*
  * Send the current time in the Random fields of the ClientHello and
  * ServerHello records for compatibility with hypothetical implementations
  * that require it.
  */
 # define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L
 # define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L
 /*
  * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications
  * that reconnect with a downgraded protocol version; see
  * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your
  * application attempts a normal handshake. Only use this in explicit
  * fallback retries, following the guidance in
  * draft-ietf-tls-downgrade-scsv-00.
  */
 # define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L
 
 /*
  * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they
  * cannot be used to clear bits.
  */
 
 # define SSL_CTX_set_options(ctx,op) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
 # define SSL_CTX_clear_options(ctx,op) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
 # define SSL_CTX_get_options(ctx) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL)
 # define SSL_set_options(ssl,op) \
         SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL)
 # define SSL_clear_options(ssl,op) \
         SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL)
 # define SSL_get_options(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL)
 
 # define SSL_CTX_set_mode(ctx,op) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
 # define SSL_CTX_clear_mode(ctx,op) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL)
 # define SSL_CTX_get_mode(ctx) \
         SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL)
 # define SSL_clear_mode(ssl,op) \
         SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL)
 # define SSL_set_mode(ssl,op) \
         SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL)
 # define SSL_get_mode(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL)
 # define SSL_set_mtu(ssl, mtu) \
         SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL)
 # define DTLS_set_link_mtu(ssl, mtu) \
         SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL)
 # define DTLS_get_link_min_mtu(ssl) \
         SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL)
 
 # define SSL_get_secure_renegotiation_support(ssl) \
         SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL)
 
 # ifndef OPENSSL_NO_HEARTBEATS
 #  define SSL_heartbeat(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL)
 # endif
 
 void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
                               void (*cb) (int write_p, int version,
                                           int content_type, const void *buf,
                                           size_t len, SSL *ssl, void *arg));
 void SSL_set_msg_callback(SSL *ssl,
                           void (*cb) (int write_p, int version,
                                       int content_type, const void *buf,
                                       size_t len, SSL *ssl, void *arg));
 # define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 # define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg))
 
 # ifndef OPENSSL_NO_SRP
 
 #  ifndef OPENSSL_NO_SSL_INTERN
 
 typedef struct srp_ctx_st {
     /* param for all the callbacks */
     void *SRP_cb_arg;
     /* set client Hello login callback */
     int (*TLS_ext_srp_username_callback) (SSL *, int *, void *);
     /* set SRP N/g param callback for verification */
     int (*SRP_verify_param_callback) (SSL *, void *);
     /* set SRP client passwd callback */
     char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *);
     char *login;
     BIGNUM *N, *g, *s, *B, *A;
     BIGNUM *a, *b, *v;
     char *info;
     int strength;
     unsigned long srp_Mask;
 } SRP_CTX;
 
 #  endif
 
 /* see tls_srp.c */
 int SSL_SRP_CTX_init(SSL *s);
 int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx);
 int SSL_SRP_CTX_free(SSL *ctx);
 int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx);
 int SSL_srp_server_param_with_username(SSL *s, int *ad);
 int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key);
 int SRP_Calc_A_param(SSL *s);
 int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key);
 
 # endif
 
 # if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32)
 #  define SSL_MAX_CERT_LIST_DEFAULT 1024*30
                                           /* 30k max cert list :-) */
 # else
 #  define SSL_MAX_CERT_LIST_DEFAULT 1024*100
                                            /* 100k max cert list :-) */
 # endif
 
 # define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT      (1024*20)
 
 /*
  * This callback type is used inside SSL_CTX, SSL, and in the functions that
  * set them. It is used to override the generation of SSL/TLS session IDs in
  * a server. Return value should be zero on an error, non-zero to proceed.
  * Also, callbacks should themselves check if the id they generate is unique
  * otherwise the SSL handshake will fail with an error - callbacks can do
  * this using the 'ssl' value they're passed by;
  * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in
  * is set at the maximum size the session ID can be. In SSLv2 this is 16
  * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this
  * length to be less if desired, but under SSLv2 session IDs are supposed to
  * be fixed at 16 bytes so the id will be padded after the callback returns
  * in this case. It is also an error for the callback to set the size to
  * zero.
  */
 typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id,
                                unsigned int *id_len);
 
 typedef struct ssl_comp_st SSL_COMP;
 
 # ifndef OPENSSL_NO_SSL_INTERN
 
 struct ssl_comp_st {
     int id;
     const char *name;
 #  ifndef OPENSSL_NO_COMP
     COMP_METHOD *method;
 #  else
     char *method;
 #  endif
 };
 
 DECLARE_STACK_OF(SSL_COMP)
 DECLARE_LHASH_OF(SSL_SESSION);
 
 struct ssl_ctx_st {
     const SSL_METHOD *method;
     STACK_OF(SSL_CIPHER) *cipher_list;
     /* same as above but sorted for lookup */
     STACK_OF(SSL_CIPHER) *cipher_list_by_id;
     struct x509_store_st /* X509_STORE */ *cert_store;
     LHASH_OF(SSL_SESSION) *sessions;
     /*
      * Most session-ids that will be cached, default is
      * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited.
      */
     unsigned long session_cache_size;
     struct ssl_session_st *session_cache_head;
     struct ssl_session_st *session_cache_tail;
     /*
      * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT,
      * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which
      * means only SSL_accept which cache SSL_SESSIONS.
      */
     int session_cache_mode;
     /*
      * If timeout is not 0, it is the default timeout value set when
      * SSL_new() is called.  This has been put in to make life easier to set
      * things up
      */
     long session_timeout;
     /*
      * If this callback is not null, it will be called each time a session id
      * is added to the cache.  If this function returns 1, it means that the
      * callback will do a SSL_SESSION_free() when it has finished using it.
      * Otherwise, on 0, it means the callback has finished with it. If
      * remove_session_cb is not null, it will be called when a session-id is
      * removed from the cache.  After the call, OpenSSL will
      * SSL_SESSION_free() it.
      */
     int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess);
     void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess);
     SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl,
                                     unsigned char *data, int len, int *copy);
     struct {
         int sess_connect;       /* SSL new conn - started */
         int sess_connect_renegotiate; /* SSL reneg - requested */
         int sess_connect_good;  /* SSL new conne/reneg - finished */
         int sess_accept;        /* SSL new accept - started */
         int sess_accept_renegotiate; /* SSL reneg - requested */
         int sess_accept_good;   /* SSL accept/reneg - finished */
         int sess_miss;          /* session lookup misses */
         int sess_timeout;       /* reuse attempt on timeouted session */
         int sess_cache_full;    /* session removed due to full cache */
         int sess_hit;           /* session reuse actually done */
         int sess_cb_hit;        /* session-id that was not in the cache was
                                  * passed back via the callback.  This
                                  * indicates that the application is
                                  * supplying session-id's from other
                                  * processes - spooky :-) */
     } stats;
 
     int references;
 
     /* if defined, these override the X509_verify_cert() calls */
     int (*app_verify_callback) (X509_STORE_CTX *, void *);
     void *app_verify_arg;
     /*
      * before OpenSSL 0.9.7, 'app_verify_arg' was ignored
      * ('app_verify_callback' was called with just one argument)
      */
 
     /* Default password callback. */
     pem_password_cb *default_passwd_callback;
 
     /* Default password callback user data. */
     void *default_passwd_callback_userdata;
 
     /* get client cert callback */
     int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey);
 
     /* cookie generate callback */
     int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie,
                               unsigned int *cookie_len);
 
     /* verify cookie callback */
     int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie,
                                  unsigned int cookie_len);
 
     CRYPTO_EX_DATA ex_data;
 
     const EVP_MD *rsa_md5;      /* For SSLv2 - name is 'ssl2-md5' */
     const EVP_MD *md5;          /* For SSLv3/TLSv1 'ssl3-md5' */
     const EVP_MD *sha1;         /* For SSLv3/TLSv1 'ssl3->sha1' */
 
     STACK_OF(X509) *extra_certs;
     STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */
 
     /* Default values used when no per-SSL value is defined follow */
 
     /* used if SSL's info_callback is NULL */
     void (*info_callback) (const SSL *ssl, int type, int val);
 
     /* what we put in client cert requests */
     STACK_OF(X509_NAME) *client_CA;
 
     /*
      * Default values to use in SSL structures follow (these are copied by
      * SSL_new)
      */
 
     unsigned long options;
     unsigned long mode;
     long max_cert_list;
 
     struct cert_st /* CERT */ *cert;
     int read_ahead;
 
     /* callback that allows applications to peek at protocol messages */
     void (*msg_callback) (int write_p, int version, int content_type,
                           const void *buf, size_t len, SSL *ssl, void *arg);
     void *msg_callback_arg;
 
     int verify_mode;
     unsigned int sid_ctx_length;
     unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
     /* called 'verify_callback' in the SSL */
     int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx);
 
     /* Default generate session ID callback. */
     GEN_SESSION_CB generate_session_id;
 
     X509_VERIFY_PARAM *param;
 
 #  if 0
     int purpose;                /* Purpose setting */
     int trust;                  /* Trust setting */
 #  endif
 
     int quiet_shutdown;
 
     /*
      * Maximum amount of data to send in one fragment. actual record size can
      * be more than this due to padding and MAC overheads.
      */
     unsigned int max_send_fragment;
 
 #  ifndef OPENSSL_NO_ENGINE
     /*
      * Engine to pass requests for client certs to
      */
     ENGINE *client_cert_engine;
 #  endif
 
 #  ifndef OPENSSL_NO_TLSEXT
     /* TLS extensions servername callback */
     int (*tlsext_servername_callback) (SSL *, int *, void *);
     void *tlsext_servername_arg;
     /* RFC 4507 session ticket keys */
     unsigned char tlsext_tick_key_name[16];
     unsigned char tlsext_tick_hmac_key[16];
     unsigned char tlsext_tick_aes_key[16];
     /* Callback to support customisation of ticket key setting */
     int (*tlsext_ticket_key_cb) (SSL *ssl,
                                  unsigned char *name, unsigned char *iv,
                                  EVP_CIPHER_CTX *ectx,
                                  HMAC_CTX *hctx, int enc);
 
     /* certificate status request info */
     /* Callback for status request */
     int (*tlsext_status_cb) (SSL *ssl, void *arg);
     void *tlsext_status_arg;
 
     /* draft-rescorla-tls-opaque-prf-input-00.txt information */
     int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput,
                                              size_t len, void *arg);
     void *tlsext_opaque_prf_input_callback_arg;
 #  endif
 
 #  ifndef OPENSSL_NO_PSK
     char *psk_identity_hint;
     unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
                                          char *identity,
                                          unsigned int max_identity_len,
                                          unsigned char *psk,
                                          unsigned int max_psk_len);
     unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
                                          unsigned char *psk,
                                          unsigned int max_psk_len);
 #  endif
 
 #  ifndef OPENSSL_NO_BUF_FREELISTS
 #   define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32
     unsigned int freelist_max_len;
     struct ssl3_buf_freelist_st *wbuf_freelist;
     struct ssl3_buf_freelist_st *rbuf_freelist;
 #  endif
 #  ifndef OPENSSL_NO_SRP
     SRP_CTX srp_ctx;            /* ctx for SRP authentication */
 #  endif
 
 #  ifndef OPENSSL_NO_TLSEXT
 
 #   ifndef OPENSSL_NO_NEXTPROTONEG
     /* Next protocol negotiation information */
     /* (for experimental NPN extension). */
 
     /*
      * For a server, this contains a callback function by which the set of
      * advertised protocols can be provided.
      */
     int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf,
                                       unsigned int *len, void *arg);
     void *next_protos_advertised_cb_arg;
     /*
      * For a client, this contains a callback function that selects the next
      * protocol from the list provided by the server.
      */
     int (*next_proto_select_cb) (SSL *s, unsigned char **out,
                                  unsigned char *outlen,
                                  const unsigned char *in,
                                  unsigned int inlen, void *arg);
     void *next_proto_select_cb_arg;
 #   endif
     /* SRTP profiles we are willing to do from RFC 5764 */
     STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
 #  endif
 };
 
 # endif
 
 # define SSL_SESS_CACHE_OFF                      0x0000
 # define SSL_SESS_CACHE_CLIENT                   0x0001
 # define SSL_SESS_CACHE_SERVER                   0x0002
 # define SSL_SESS_CACHE_BOTH     (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER)
 # define SSL_SESS_CACHE_NO_AUTO_CLEAR            0x0080
 /* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */
 # define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP       0x0100
 # define SSL_SESS_CACHE_NO_INTERNAL_STORE        0x0200
 # define SSL_SESS_CACHE_NO_INTERNAL \
         (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE)
 
 LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
 # define SSL_CTX_sess_number(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL)
 # define SSL_CTX_sess_connect(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL)
 # define SSL_CTX_sess_connect_good(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL)
 # define SSL_CTX_sess_connect_renegotiate(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL)
 # define SSL_CTX_sess_accept(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL)
 # define SSL_CTX_sess_accept_renegotiate(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL)
 # define SSL_CTX_sess_accept_good(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL)
 # define SSL_CTX_sess_hits(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL)
 # define SSL_CTX_sess_cb_hits(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL)
 # define SSL_CTX_sess_misses(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL)
 # define SSL_CTX_sess_timeouts(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL)
 # define SSL_CTX_sess_cache_full(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL)
 
 void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
                              int (*new_session_cb) (struct ssl_st *ssl,
                                                     SSL_SESSION *sess));
 int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
                                               SSL_SESSION *sess);
 void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
                                 void (*remove_session_cb) (struct ssl_ctx_st
                                                            *ctx,
                                                            SSL_SESSION
                                                            *sess));
 void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx,
                                                   SSL_SESSION *sess);
 void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
                              SSL_SESSION *(*get_session_cb) (struct ssl_st
                                                              *ssl,
                                                              unsigned char
                                                              *data, int len,
                                                              int *copy));
 SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl,
                                                        unsigned char *Data,
                                                        int len, int *copy);
 void SSL_CTX_set_info_callback(SSL_CTX *ctx,
                                void (*cb) (const SSL *ssl, int type,
                                            int val));
 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
                                                  int val);
 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
                                 int (*client_cert_cb) (SSL *ssl, X509 **x509,
                                                        EVP_PKEY **pkey));
 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
                                                  EVP_PKEY **pkey);
 # ifndef OPENSSL_NO_ENGINE
 int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e);
 # endif
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
                                     int (*app_gen_cookie_cb) (SSL *ssl,
                                                               unsigned char
                                                               *cookie,
                                                               unsigned int
                                                               *cookie_len));
 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
                                   int (*app_verify_cookie_cb) (SSL *ssl,
                                                                unsigned char
                                                                *cookie,
                                                                unsigned int
                                                                cookie_len));
 # ifndef OPENSSL_NO_NEXTPROTONEG
 void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s,
                                            int (*cb) (SSL *ssl,
                                                       const unsigned char
                                                       **out,
                                                       unsigned int *outlen,
                                                       void *arg), void *arg);
 void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
                                       int (*cb) (SSL *ssl,
                                                  unsigned char **out,
                                                  unsigned char *outlen,
                                                  const unsigned char *in,
                                                  unsigned int inlen,
                                                  void *arg), void *arg);
 
 int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
                           const unsigned char *in, unsigned int inlen,
                           const unsigned char *client,
                           unsigned int client_len);
 void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
                                     unsigned *len);
 
 #  define OPENSSL_NPN_UNSUPPORTED 0
 #  define OPENSSL_NPN_NEGOTIATED  1
 #  define OPENSSL_NPN_NO_OVERLAP  2
 # endif
 
 # ifndef OPENSSL_NO_PSK
 /*
  * the maximum length of the buffer given to callbacks containing the
  * resulting identity/psk
  */
 #  define PSK_MAX_IDENTITY_LEN 128
 #  define PSK_MAX_PSK_LEN 256
 void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
                                      unsigned int (*psk_client_callback) (SSL
                                                                           *ssl,
                                                                           const
                                                                           char
                                                                           *hint,
                                                                           char
                                                                           *identity,
                                                                           unsigned
                                                                           int
                                                                           max_identity_len,
                                                                           unsigned
                                                                           char
                                                                           *psk,
                                                                           unsigned
                                                                           int
                                                                           max_psk_len));
 void SSL_set_psk_client_callback(SSL *ssl,
                                  unsigned int (*psk_client_callback) (SSL
                                                                       *ssl,
                                                                       const
                                                                       char
                                                                       *hint,
                                                                       char
                                                                       *identity,
                                                                       unsigned
                                                                       int
                                                                       max_identity_len,
                                                                       unsigned
                                                                       char
                                                                       *psk,
                                                                       unsigned
                                                                       int
                                                                       max_psk_len));
 void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
                                      unsigned int (*psk_server_callback) (SSL
                                                                           *ssl,
                                                                           const
                                                                           char
                                                                           *identity,
                                                                           unsigned
                                                                           char
                                                                           *psk,
                                                                           unsigned
                                                                           int
                                                                           max_psk_len));
 void SSL_set_psk_server_callback(SSL *ssl,
                                  unsigned int (*psk_server_callback) (SSL
                                                                       *ssl,
                                                                       const
                                                                       char
                                                                       *identity,
                                                                       unsigned
                                                                       char
                                                                       *psk,
                                                                       unsigned
                                                                       int
                                                                       max_psk_len));
 int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint);
 int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
 const char *SSL_get_psk_identity_hint(const SSL *s);
 const char *SSL_get_psk_identity(const SSL *s);
 # endif
 
 # define SSL_NOTHING     1
 # define SSL_WRITING     2
 # define SSL_READING     3
 # define SSL_X509_LOOKUP 4
 
 /* These will only be used when doing non-blocking IO */
 # define SSL_want_nothing(s)     (SSL_want(s) == SSL_NOTHING)
 # define SSL_want_read(s)        (SSL_want(s) == SSL_READING)
 # define SSL_want_write(s)       (SSL_want(s) == SSL_WRITING)
 # define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
 
 # define SSL_MAC_FLAG_READ_MAC_STREAM 1
 # define SSL_MAC_FLAG_WRITE_MAC_STREAM 2
 
 # ifndef OPENSSL_NO_SSL_INTERN
 
 struct ssl_st {
     /*
      * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION,
      * DTLS1_VERSION)
      */
     int version;
     /* SSL_ST_CONNECT or SSL_ST_ACCEPT */
     int type;
     /* SSLv3 */
     const SSL_METHOD *method;
     /*
      * There are 2 BIO's even though they are normally both the same.  This
      * is so data can be read and written to different handlers
      */
 #  ifndef OPENSSL_NO_BIO
     /* used by SSL_read */
     BIO *rbio;
     /* used by SSL_write */
     BIO *wbio;
     /* used during session-id reuse to concatenate messages */
     BIO *bbio;
 #  else
     /* used by SSL_read */
     char *rbio;
     /* used by SSL_write */
     char *wbio;
     char *bbio;
 #  endif
     /*
      * This holds a variable that indicates what we were doing when a 0 or -1
      * is returned.  This is needed for non-blocking IO so we know what
      * request needs re-doing when in SSL_accept or SSL_connect
      */
     int rwstate;
     /* true when we are actually in SSL_accept() or SSL_connect() */
     int in_handshake;
     int (*handshake_func) (SSL *);
     /*
      * Imagine that here's a boolean member "init" that is switched as soon
      * as SSL_set_{accept/connect}_state is called for the first time, so
      * that "state" and "handshake_func" are properly initialized.  But as
      * handshake_func is == 0 until then, we use this test instead of an
      * "init" member.
      */
     /* are we the server side? - mostly used by SSL_clear */
     int server;
     /*
      * Generate a new session or reuse an old one.
      * NB: For servers, the 'new' session may actually be a previously
      * cached session or even the previous session unless
      * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set
      */
     int new_session;
     /* don't send shutdown packets */
     int quiet_shutdown;
     /* we have shut things down, 0x01 sent, 0x02 for received */
     int shutdown;
     /* where we are */
     int state;
     /* where we are when reading */
     int rstate;
     BUF_MEM *init_buf;          /* buffer used during init */
     void *init_msg;             /* pointer to handshake message body, set by
                                  * ssl3_get_message() */
     int init_num;               /* amount read/written */
     int init_off;               /* amount read/written */
     /* used internally to point at a raw packet */
     unsigned char *packet;
     unsigned int packet_length;
     struct ssl2_state_st *s2;   /* SSLv2 variables */
     struct ssl3_state_st *s3;   /* SSLv3 variables */
     struct dtls1_state_st *d1;  /* DTLSv1 variables */
     int read_ahead;             /* Read as many input bytes as possible (for
                                  * non-blocking reads) */
     /* callback that allows applications to peek at protocol messages */
     void (*msg_callback) (int write_p, int version, int content_type,
                           const void *buf, size_t len, SSL *ssl, void *arg);
     void *msg_callback_arg;
     int hit;                    /* reusing a previous session */
     X509_VERIFY_PARAM *param;
 #  if 0
     int purpose;                /* Purpose setting */
     int trust;                  /* Trust setting */
 #  endif
     /* crypto */
     STACK_OF(SSL_CIPHER) *cipher_list;
     STACK_OF(SSL_CIPHER) *cipher_list_by_id;
     /*
      * These are the ones being used, the ones in SSL_SESSION are the ones to
      * be 'copied' into these ones
      */
     int mac_flags;
     EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */
     EVP_MD_CTX *read_hash;      /* used for mac generation */
 #  ifndef OPENSSL_NO_COMP
     COMP_CTX *expand;           /* uncompress */
 #  else
     char *expand;
 #  endif
     EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */
     EVP_MD_CTX *write_hash;     /* used for mac generation */
 #  ifndef OPENSSL_NO_COMP
     COMP_CTX *compress;         /* compression */
 #  else
     char *compress;
 #  endif
     /* session info */
     /* client cert? */
     /* This is used to hold the server certificate used */
     struct cert_st /* CERT */ *cert;
     /*
      * the session_id_context is used to ensure sessions are only reused in
      * the appropriate context
      */
     unsigned int sid_ctx_length;
     unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH];
     /* This can also be in the session once a session is established */
     SSL_SESSION *session;
     /* Default generate session ID callback. */
     GEN_SESSION_CB generate_session_id;
     /* Used in SSL2 and SSL3 */
     /*
      * 0 don't care about verify failure.
      * 1 fail if verify fails
      */
     int verify_mode;
     /* fail if callback returns 0 */
     int (*verify_callback) (int ok, X509_STORE_CTX *ctx);
     /* optional informational callback */
     void (*info_callback) (const SSL *ssl, int type, int val);
     /* error bytes to be written */
     int error;
     /* actual code */
     int error_code;
 #  ifndef OPENSSL_NO_KRB5
     /* Kerberos 5 context */
     KSSL_CTX *kssl_ctx;
 #  endif                        /* OPENSSL_NO_KRB5 */
 #  ifndef OPENSSL_NO_PSK
     unsigned int (*psk_client_callback) (SSL *ssl, const char *hint,
                                          char *identity,
                                          unsigned int max_identity_len,
                                          unsigned char *psk,
                                          unsigned int max_psk_len);
     unsigned int (*psk_server_callback) (SSL *ssl, const char *identity,
                                          unsigned char *psk,
                                          unsigned int max_psk_len);
 #  endif
     SSL_CTX *ctx;
     /*
      * set this flag to 1 and a sleep(1) is put into all SSL_read() and
      * SSL_write() calls, good for nbio debuging :-)
      */
     int debug;
     /* extra application data */
     long verify_result;
     CRYPTO_EX_DATA ex_data;
     /* for server side, keep the list of CA_dn we can use */
     STACK_OF(X509_NAME) *client_CA;
     int references;
     /* protocol behaviour */
     unsigned long options;
     /* API behaviour */
     unsigned long mode;
     long max_cert_list;
     int first_packet;
     /* what was passed, used for SSLv3/TLS rollback check */
     int client_version;
     unsigned int max_send_fragment;
 #  ifndef OPENSSL_NO_TLSEXT
     /* TLS extension debug callback */
     void (*tlsext_debug_cb) (SSL *s, int client_server, int type,
                              unsigned char *data, int len, void *arg);
     void *tlsext_debug_arg;
     char *tlsext_hostname;
     /*-
      * no further mod of servername
      * 0 : call the servername extension callback.
      * 1 : prepare 2, allow last ack just after in server callback.
      * 2 : don't call servername callback, no ack in server hello
      */
     int servername_done;
     /* certificate status request info */
     /* Status type or -1 if no status type */
     int tlsext_status_type;
     /* Expect OCSP CertificateStatus message */
     int tlsext_status_expected;
     /* OCSP status request only */
     STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids;
     X509_EXTENSIONS *tlsext_ocsp_exts;
     /* OCSP response received or to be sent */
     unsigned char *tlsext_ocsp_resp;
     int tlsext_ocsp_resplen;
     /* RFC4507 session ticket expected to be received or sent */
     int tlsext_ticket_expected;
 #   ifndef OPENSSL_NO_EC
     size_t tlsext_ecpointformatlist_length;
     /* our list */
     unsigned char *tlsext_ecpointformatlist;
     size_t tlsext_ellipticcurvelist_length;
     /* our list */
     unsigned char *tlsext_ellipticcurvelist;
 #   endif                       /* OPENSSL_NO_EC */
     /*
      * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for
      * handshakes
      */
     void *tlsext_opaque_prf_input;
     size_t tlsext_opaque_prf_input_len;
     /* TLS Session Ticket extension override */
     TLS_SESSION_TICKET_EXT *tlsext_session_ticket;
     /* TLS Session Ticket extension callback */
     tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb;
     void *tls_session_ticket_ext_cb_arg;
     /* TLS pre-shared secret session resumption */
     tls_session_secret_cb_fn tls_session_secret_cb;
     void *tls_session_secret_cb_arg;
     SSL_CTX *initial_ctx;       /* initial ctx, used to store sessions */
 #   ifndef OPENSSL_NO_NEXTPROTONEG
     /*
      * Next protocol negotiation. For the client, this is the protocol that
      * we sent in NextProtocol and is set when handling ServerHello
      * extensions. For a server, this is the client's selected_protocol from
      * NextProtocol and is set when handling the NextProtocol message, before
      * the Finished message.
      */
     unsigned char *next_proto_negotiated;
     unsigned char next_proto_negotiated_len;
 #   endif
 #   define session_ctx initial_ctx
     /* What we'll do */
     STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
     /* What's been chosen */
     SRTP_PROTECTION_PROFILE *srtp_profile;
         /*-
          * Is use of the Heartbeat extension negotiated?
          * 0: disabled
          * 1: enabled
          * 2: enabled, but not allowed to send Requests
          */
     unsigned int tlsext_heartbeat;
     /* Indicates if a HeartbeatRequest is in flight */
     unsigned int tlsext_hb_pending;
     /* HeartbeatRequest sequence number */
     unsigned int tlsext_hb_seq;
 #  else
 #   define session_ctx ctx
 #  endif                        /* OPENSSL_NO_TLSEXT */
     /*-
      * 1 if we are renegotiating.
      * 2 if we are a server and are inside a handshake
      * (i.e. not just sending a HelloRequest)
      */
     int renegotiate;
 #  ifndef OPENSSL_NO_SRP
     /* ctx for SRP authentication */
     SRP_CTX srp_ctx;
 #  endif
 };
 
 # endif
 
 #ifdef __cplusplus
 }
 #endif
 
 # include <openssl/ssl2.h>
 # include <openssl/ssl3.h>
 # include <openssl/tls1.h>      /* This is mostly sslv3 with a few tweaks */
 # include <openssl/dtls1.h>     /* Datagram TLS */
 # include <openssl/ssl23.h>
 # include <openssl/srtp.h>      /* Support for the use_srtp extension */
 
 #ifdef  __cplusplus
 extern "C" {
 #endif
 
 /* compatibility */
 # define SSL_set_app_data(s,arg)         (SSL_set_ex_data(s,0,(char *)arg))
 # define SSL_get_app_data(s)             (SSL_get_ex_data(s,0))
 # define SSL_SESSION_set_app_data(s,a)   (SSL_SESSION_set_ex_data(s,0,(char *)a))
 # define SSL_SESSION_get_app_data(s)     (SSL_SESSION_get_ex_data(s,0))
 # define SSL_CTX_get_app_data(ctx)       (SSL_CTX_get_ex_data(ctx,0))
 # define SSL_CTX_set_app_data(ctx,arg)   (SSL_CTX_set_ex_data(ctx,0,(char *)arg))
 
 /*
  * The following are the possible values for ssl->state are are used to
  * indicate where we are up to in the SSL connection establishment. The
  * macros that follow are about the only things you should need to use and
  * even then, only when using non-blocking IO. It can also be useful to work
  * out where you were when the connection failed
  */
 
 # define SSL_ST_CONNECT                  0x1000
 # define SSL_ST_ACCEPT                   0x2000
 # define SSL_ST_MASK                     0x0FFF
 # define SSL_ST_INIT                     (SSL_ST_CONNECT|SSL_ST_ACCEPT)
 # define SSL_ST_BEFORE                   0x4000
 # define SSL_ST_OK                       0x03
 # define SSL_ST_RENEGOTIATE              (0x04|SSL_ST_INIT)
 # define SSL_ST_ERR                      0x05
 
 # define SSL_CB_LOOP                     0x01
 # define SSL_CB_EXIT                     0x02
 # define SSL_CB_READ                     0x04
 # define SSL_CB_WRITE                    0x08
 # define SSL_CB_ALERT                    0x4000/* used in callback */
 # define SSL_CB_READ_ALERT               (SSL_CB_ALERT|SSL_CB_READ)
 # define SSL_CB_WRITE_ALERT              (SSL_CB_ALERT|SSL_CB_WRITE)
 # define SSL_CB_ACCEPT_LOOP              (SSL_ST_ACCEPT|SSL_CB_LOOP)
 # define SSL_CB_ACCEPT_EXIT              (SSL_ST_ACCEPT|SSL_CB_EXIT)
 # define SSL_CB_CONNECT_LOOP             (SSL_ST_CONNECT|SSL_CB_LOOP)
 # define SSL_CB_CONNECT_EXIT             (SSL_ST_CONNECT|SSL_CB_EXIT)
 # define SSL_CB_HANDSHAKE_START          0x10
 # define SSL_CB_HANDSHAKE_DONE           0x20
 
 /* Is the SSL_connection established? */
 # define SSL_get_state(a)                SSL_state(a)
 # define SSL_is_init_finished(a)         (SSL_state(a) == SSL_ST_OK)
 # define SSL_in_init(a)                  (SSL_state(a)&SSL_ST_INIT)
 # define SSL_in_before(a)                (SSL_state(a)&SSL_ST_BEFORE)
 # define SSL_in_connect_init(a)          (SSL_state(a)&SSL_ST_CONNECT)
 # define SSL_in_accept_init(a)           (SSL_state(a)&SSL_ST_ACCEPT)
 
 /*
  * The following 2 states are kept in ssl->rstate when reads fail, you should
  * not need these
  */
 # define SSL_ST_READ_HEADER                      0xF0
 # define SSL_ST_READ_BODY                        0xF1
 # define SSL_ST_READ_DONE                        0xF2
 
 /*-
  * Obtain latest Finished message
  *   -- that we sent (SSL_get_finished)
  *   -- that we expected from peer (SSL_get_peer_finished).
  * Returns length (0 == no Finished so far), copies up to 'count' bytes.
  */
 size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
 size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
 
 /*
  * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are
  * 'ored' with SSL_VERIFY_PEER if they are desired
  */
 # define SSL_VERIFY_NONE                 0x00
 # define SSL_VERIFY_PEER                 0x01
 # define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
 # define SSL_VERIFY_CLIENT_ONCE          0x04
 
 # define OpenSSL_add_ssl_algorithms()    SSL_library_init()
 # define SSLeay_add_ssl_algorithms()     SSL_library_init()
 
 /* this is for backward compatibility */
 # if 0                          /* NEW_SSLEAY */
 #  define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c)
 #  define SSL_set_pref_cipher(c,n)        SSL_set_cipher_list(c,n)
 #  define SSL_add_session(a,b)            SSL_CTX_add_session((a),(b))
 #  define SSL_remove_session(a,b)         SSL_CTX_remove_session((a),(b))
 #  define SSL_flush_sessions(a,b)         SSL_CTX_flush_sessions((a),(b))
 # endif
 /* More backward compatibility */
 # define SSL_get_cipher(s) \
                 SSL_CIPHER_get_name(SSL_get_current_cipher(s))
 # define SSL_get_cipher_bits(s,np) \
                 SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np)
 # define SSL_get_cipher_version(s) \
                 SSL_CIPHER_get_version(SSL_get_current_cipher(s))
 # define SSL_get_cipher_name(s) \
                 SSL_CIPHER_get_name(SSL_get_current_cipher(s))
 # define SSL_get_time(a)         SSL_SESSION_get_time(a)
 # define SSL_set_time(a,b)       SSL_SESSION_set_time((a),(b))
 # define SSL_get_timeout(a)      SSL_SESSION_get_timeout(a)
 # define SSL_set_timeout(a,b)    SSL_SESSION_set_timeout((a),(b))
 
 # define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id)
 # define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id)
 
 DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
 # define SSL_AD_REASON_OFFSET            1000/* offset to get SSL_R_... value
                                               * from SSL_AD_... */
 /* These alert types are for SSLv3 and TLSv1 */
 # define SSL_AD_CLOSE_NOTIFY             SSL3_AD_CLOSE_NOTIFY
 /* fatal */
 # define SSL_AD_UNEXPECTED_MESSAGE       SSL3_AD_UNEXPECTED_MESSAGE
 /* fatal */
 # define SSL_AD_BAD_RECORD_MAC           SSL3_AD_BAD_RECORD_MAC
 # define SSL_AD_DECRYPTION_FAILED        TLS1_AD_DECRYPTION_FAILED
 # define SSL_AD_RECORD_OVERFLOW          TLS1_AD_RECORD_OVERFLOW
 /* fatal */
 # define SSL_AD_DECOMPRESSION_FAILURE    SSL3_AD_DECOMPRESSION_FAILURE
 /* fatal */
 # define SSL_AD_HANDSHAKE_FAILURE        SSL3_AD_HANDSHAKE_FAILURE
 /* Not for TLS */
 # define SSL_AD_NO_CERTIFICATE           SSL3_AD_NO_CERTIFICATE
 # define SSL_AD_BAD_CERTIFICATE          SSL3_AD_BAD_CERTIFICATE
 # define SSL_AD_UNSUPPORTED_CERTIFICATE  SSL3_AD_UNSUPPORTED_CERTIFICATE
 # define SSL_AD_CERTIFICATE_REVOKED      SSL3_AD_CERTIFICATE_REVOKED
 # define SSL_AD_CERTIFICATE_EXPIRED      SSL3_AD_CERTIFICATE_EXPIRED
 # define SSL_AD_CERTIFICATE_UNKNOWN      SSL3_AD_CERTIFICATE_UNKNOWN
 /* fatal */
 # define SSL_AD_ILLEGAL_PARAMETER        SSL3_AD_ILLEGAL_PARAMETER
 /* fatal */
 # define SSL_AD_UNKNOWN_CA               TLS1_AD_UNKNOWN_CA
 /* fatal */
 # define SSL_AD_ACCESS_DENIED            TLS1_AD_ACCESS_DENIED
 /* fatal */
 # define SSL_AD_DECODE_ERROR             TLS1_AD_DECODE_ERROR
 # define SSL_AD_DECRYPT_ERROR            TLS1_AD_DECRYPT_ERROR
 /* fatal */
 # define SSL_AD_EXPORT_RESTRICTION       TLS1_AD_EXPORT_RESTRICTION
 /* fatal */
 # define SSL_AD_PROTOCOL_VERSION         TLS1_AD_PROTOCOL_VERSION
 /* fatal */
 # define SSL_AD_INSUFFICIENT_SECURITY    TLS1_AD_INSUFFICIENT_SECURITY
 /* fatal */
 # define SSL_AD_INTERNAL_ERROR           TLS1_AD_INTERNAL_ERROR
 # define SSL_AD_USER_CANCELLED           TLS1_AD_USER_CANCELLED
 # define SSL_AD_NO_RENEGOTIATION         TLS1_AD_NO_RENEGOTIATION
 # define SSL_AD_UNSUPPORTED_EXTENSION    TLS1_AD_UNSUPPORTED_EXTENSION
 # define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
 # define SSL_AD_UNRECOGNIZED_NAME        TLS1_AD_UNRECOGNIZED_NAME
 # define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
 # define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
 /* fatal */
 # define SSL_AD_UNKNOWN_PSK_IDENTITY     TLS1_AD_UNKNOWN_PSK_IDENTITY
 /* fatal */
 # define SSL_AD_INAPPROPRIATE_FALLBACK   TLS1_AD_INAPPROPRIATE_FALLBACK
 # define SSL_ERROR_NONE                  0
 # define SSL_ERROR_SSL                   1
 # define SSL_ERROR_WANT_READ             2
 # define SSL_ERROR_WANT_WRITE            3
 # define SSL_ERROR_WANT_X509_LOOKUP      4
 # define SSL_ERROR_SYSCALL               5/* look at error stack/return
                                            * value/errno */
 # define SSL_ERROR_ZERO_RETURN           6
 # define SSL_ERROR_WANT_CONNECT          7
 # define SSL_ERROR_WANT_ACCEPT           8
 # define SSL_CTRL_NEED_TMP_RSA                   1
 # define SSL_CTRL_SET_TMP_RSA                    2
 # define SSL_CTRL_SET_TMP_DH                     3
 # define SSL_CTRL_SET_TMP_ECDH                   4
 # define SSL_CTRL_SET_TMP_RSA_CB                 5
 # define SSL_CTRL_SET_TMP_DH_CB                  6
 # define SSL_CTRL_SET_TMP_ECDH_CB                7
 # define SSL_CTRL_GET_SESSION_REUSED             8
 # define SSL_CTRL_GET_CLIENT_CERT_REQUEST        9
 # define SSL_CTRL_GET_NUM_RENEGOTIATIONS         10
 # define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS       11
 # define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS       12
 # define SSL_CTRL_GET_FLAGS                      13
 # define SSL_CTRL_EXTRA_CHAIN_CERT               14
 # define SSL_CTRL_SET_MSG_CALLBACK               15
 # define SSL_CTRL_SET_MSG_CALLBACK_ARG           16
 /* only applies to datagram connections */
 # define SSL_CTRL_SET_MTU                17
 /* Stats */
 # define SSL_CTRL_SESS_NUMBER                    20
 # define SSL_CTRL_SESS_CONNECT                   21
 # define SSL_CTRL_SESS_CONNECT_GOOD              22
 # define SSL_CTRL_SESS_CONNECT_RENEGOTIATE       23
 # define SSL_CTRL_SESS_ACCEPT                    24
 # define SSL_CTRL_SESS_ACCEPT_GOOD               25
 # define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE        26
 # define SSL_CTRL_SESS_HIT                       27
 # define SSL_CTRL_SESS_CB_HIT                    28
 # define SSL_CTRL_SESS_MISSES                    29
 # define SSL_CTRL_SESS_TIMEOUTS                  30
 # define SSL_CTRL_SESS_CACHE_FULL                31
 # define SSL_CTRL_OPTIONS                        32
 # define SSL_CTRL_MODE                           33
 # define SSL_CTRL_GET_READ_AHEAD                 40
 # define SSL_CTRL_SET_READ_AHEAD                 41
 # define SSL_CTRL_SET_SESS_CACHE_SIZE            42
 # define SSL_CTRL_GET_SESS_CACHE_SIZE            43
 # define SSL_CTRL_SET_SESS_CACHE_MODE            44
 # define SSL_CTRL_GET_SESS_CACHE_MODE            45
 # define SSL_CTRL_GET_MAX_CERT_LIST              50
 # define SSL_CTRL_SET_MAX_CERT_LIST              51
 # define SSL_CTRL_SET_MAX_SEND_FRAGMENT          52
 /* see tls1.h for macros based on these */
 # ifndef OPENSSL_NO_TLSEXT
 #  define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB       53
 #  define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG      54
 #  define SSL_CTRL_SET_TLSEXT_HOSTNAME            55
 #  define SSL_CTRL_SET_TLSEXT_DEBUG_CB            56
 #  define SSL_CTRL_SET_TLSEXT_DEBUG_ARG           57
 #  define SSL_CTRL_GET_TLSEXT_TICKET_KEYS         58
 #  define SSL_CTRL_SET_TLSEXT_TICKET_KEYS         59
 #  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT    60
 #  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61
 #  define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB       63
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG   64
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE     65
 #  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS     66
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS     67
 #  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS      68
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS      69
 #  define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP        70
 #  define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP        71
 #  define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB       72
 #  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB    75
 #  define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB                76
 #  define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB             77
 #  define SSL_CTRL_SET_SRP_ARG            78
 #  define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME               79
 #  define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH               80
 #  define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD               81
 #  ifndef OPENSSL_NO_HEARTBEATS
 #   define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT                         85
 #   define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING          86
 #   define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS      87
 #  endif
 # endif
 # define DTLS_CTRL_GET_TIMEOUT           73
 # define DTLS_CTRL_HANDLE_TIMEOUT        74
 # define DTLS_CTRL_LISTEN                        75
 # define SSL_CTRL_GET_RI_SUPPORT                 76
 # define SSL_CTRL_CLEAR_OPTIONS                  77
 # define SSL_CTRL_CLEAR_MODE                     78
 # define SSL_CTRL_GET_EXTRA_CHAIN_CERTS          82
 # define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS        83
 # define SSL_CTRL_CHECK_PROTO_VERSION            119
 # define DTLS_CTRL_SET_LINK_MTU                  120
 # define DTLS_CTRL_GET_LINK_MIN_MTU              121
 # define DTLSv1_get_timeout(ssl, arg) \
         SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
 # define DTLSv1_handle_timeout(ssl) \
         SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL)
 # define DTLSv1_listen(ssl, peer) \
         SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer)
 # define SSL_session_reused(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
 # define SSL_num_renegotiations(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL)
 # define SSL_clear_num_renegotiations(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL)
 # define SSL_total_renegotiations(ssl) \
         SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL)
 # define SSL_CTX_need_tmp_RSA(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL)
 # define SSL_CTX_set_tmp_rsa(ctx,rsa) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
 # define SSL_CTX_set_tmp_dh(ctx,dh) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
 # define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
 # define SSL_need_tmp_RSA(ssl) \
         SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL)
 # define SSL_set_tmp_rsa(ssl,rsa) \
         SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa)
 # define SSL_set_tmp_dh(ssl,dh) \
         SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh)
 # define SSL_set_tmp_ecdh(ssl,ecdh) \
         SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh)
 # define SSL_CTX_add_extra_chain_cert(ctx,x509) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509)
 # define SSL_CTX_get_extra_chain_certs(ctx,px509) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509)
 # define SSL_CTX_clear_extra_chain_certs(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
 # ifndef OPENSSL_NO_BIO
 BIO_METHOD *BIO_f_ssl(void);
 BIO *BIO_new_ssl(SSL_CTX *ctx, int client);
 BIO *BIO_new_ssl_connect(SSL_CTX *ctx);
 BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx);
 int BIO_ssl_copy_session_id(BIO *to, BIO *from);
 void BIO_ssl_shutdown(BIO *ssl_bio);
 
 # endif
 
 int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
 SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth);
 void SSL_CTX_free(SSL_CTX *);
 long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
 long SSL_CTX_get_timeout(const SSL_CTX *ctx);
 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
 void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
 int SSL_want(const SSL *s);
 int SSL_clear(SSL *s);
 
 void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
 
 const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
 int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits);
 char *SSL_CIPHER_get_version(const SSL_CIPHER *c);
 const char *SSL_CIPHER_get_name(const SSL_CIPHER *c);
 unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c);
 
 int SSL_get_fd(const SSL *s);
 int SSL_get_rfd(const SSL *s);
 int SSL_get_wfd(const SSL *s);
 const char *SSL_get_cipher_list(const SSL *s, int n);
 char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len);
 int SSL_get_read_ahead(const SSL *s);
 int SSL_pending(const SSL *s);
 # ifndef OPENSSL_NO_SOCK
 int SSL_set_fd(SSL *s, int fd);
 int SSL_set_rfd(SSL *s, int fd);
 int SSL_set_wfd(SSL *s, int fd);
 # endif
 # ifndef OPENSSL_NO_BIO
 void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
 BIO *SSL_get_rbio(const SSL *s);
 BIO *SSL_get_wbio(const SSL *s);
 # endif
 int SSL_set_cipher_list(SSL *s, const char *str);
 void SSL_set_read_ahead(SSL *s, int yes);
 int SSL_get_verify_mode(const SSL *s);
 int SSL_get_verify_depth(const SSL *s);
 int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *);
 void SSL_set_verify(SSL *s, int mode,
                     int (*callback) (int ok, X509_STORE_CTX *ctx));
 void SSL_set_verify_depth(SSL *s, int depth);
 # ifndef OPENSSL_NO_RSA
 int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
 # endif
 int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len);
 int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
 int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d,
                             long len);
 int SSL_use_certificate(SSL *ssl, X509 *x);
 int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len);
 
 # ifndef OPENSSL_NO_STDIO
 int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type);
 int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type);
 int SSL_use_certificate_file(SSL *ssl, const char *file, int type);
 int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type);
 int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type);
 int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type);
 /* PEM type */
 int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file);
 STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
 int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
                                         const char *file);
 #  ifndef OPENSSL_SYS_VMS
 /* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */
 #   ifndef OPENSSL_SYS_MACINTOSH_CLASSIC
 int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs,
                                        const char *dir);
 #   endif
 #  endif
 
 # endif
 
 void SSL_load_error_strings(void);
 const char *SSL_state_string(const SSL *s);
 const char *SSL_rstate_string(const SSL *s);
 const char *SSL_state_string_long(const SSL *s);
 const char *SSL_rstate_string_long(const SSL *s);
 long SSL_SESSION_get_time(const SSL_SESSION *s);
 long SSL_SESSION_set_time(SSL_SESSION *s, long t);
 long SSL_SESSION_get_timeout(const SSL_SESSION *s);
 long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
 void SSL_copy_session_id(SSL *to, const SSL *from);
 X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
 int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
                                 unsigned int sid_ctx_len);
 
 SSL_SESSION *SSL_SESSION_new(void);
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                         unsigned int *len);
 unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s);
 # ifndef OPENSSL_NO_FP_API
 int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
 # endif
 # ifndef OPENSSL_NO_BIO
 int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
 # endif
 void SSL_SESSION_free(SSL_SESSION *ses);
 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
 int SSL_set_session(SSL *to, SSL_SESSION *session);
 int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
 int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
 int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
 int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
 int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
                                 unsigned int id_len);
 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
                              long length);
 
 # ifdef HEADER_X509_H
 X509 *SSL_get_peer_certificate(const SSL *s);
 # endif
 
 STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
 
 int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
 int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
 int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int,
                                                         X509_STORE_CTX *);
 void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
                         int (*callback) (int, X509_STORE_CTX *));
 void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
 void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
                                       int (*cb) (X509_STORE_CTX *, void *),
                                       void *arg);
 # ifndef OPENSSL_NO_RSA
 int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
 # endif
 int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d,
                                    long len);
 int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
 int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
                                 const unsigned char *d, long len);
 int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
 int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
                                  const unsigned char *d);
 
 void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb);
 void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u);
 
 int SSL_CTX_check_private_key(const SSL_CTX *ctx);
 int SSL_check_private_key(const SSL *ctx);
 
 int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
                                    unsigned int sid_ctx_len);
 
 SSL *SSL_new(SSL_CTX *ctx);
 int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
                                unsigned int sid_ctx_len);
 
 int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
 int SSL_set_purpose(SSL *s, int purpose);
 int SSL_CTX_set_trust(SSL_CTX *s, int trust);
 int SSL_set_trust(SSL *s, int trust);
 
 int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
 int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
 
 # ifndef OPENSSL_NO_SRP
 int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name);
 int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password);
 int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength);
 int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx,
                                         char *(*cb) (SSL *, void *));
 int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx,
                                           int (*cb) (SSL *, void *));
 int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx,
                                       int (*cb) (SSL *, int *, void *));
 int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg);
 
 int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g,
                              BIGNUM *sa, BIGNUM *v, char *info);
 int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass,
                                 const char *grp);
 
 BIGNUM *SSL_get_srp_g(SSL *s);
 BIGNUM *SSL_get_srp_N(SSL *s);
 
 char *SSL_get_srp_username(SSL *s);
 char *SSL_get_srp_userinfo(SSL *s);
 # endif
 
 void SSL_free(SSL *ssl);
 int SSL_accept(SSL *ssl);
 int SSL_connect(SSL *ssl);
 int SSL_read(SSL *ssl, void *buf, int num);
 int SSL_peek(SSL *ssl, void *buf, int num);
 int SSL_write(SSL *ssl, const void *buf, int num);
 long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
 long SSL_callback_ctrl(SSL *, int, void (*)(void));
 long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
 long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void));
 
 int SSL_get_error(const SSL *s, int ret_code);
 const char *SSL_get_version(const SSL *s);
 
 /* This sets the 'default' SSL version that SSL_new() will create */
 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
 
 # ifndef OPENSSL_NO_SSL2_METHOD
 const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
 const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
 const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
 # endif
 
 # ifndef OPENSSL_NO_SSL3_METHOD
 const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
 const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
 const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */
 # endif
 
 const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS
                                         * version */
 const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available
                                                * SSL/TLS version */
 const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available
                                                * SSL/TLS version */
 
 const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */
 const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */
 const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */
 
 const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */
 const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */
 const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */
 
 const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */
 const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */
 const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */
 
 const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */
 const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */
 const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */
 
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
 int SSL_do_handshake(SSL *s);
 int SSL_renegotiate(SSL *s);
 int SSL_renegotiate_abbreviated(SSL *s);
 int SSL_renegotiate_pending(SSL *s);
 int SSL_shutdown(SSL *s);
 
 const SSL_METHOD *SSL_get_ssl_method(SSL *s);
 int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method);
 const char *SSL_alert_type_string_long(int value);
 const char *SSL_alert_type_string(int value);
 const char *SSL_alert_desc_string_long(int value);
 const char *SSL_alert_desc_string(int value);
 
 void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list);
 void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list);
 STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
 STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s);
 int SSL_add_client_CA(SSL *ssl, X509 *x);
 int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
 
 void SSL_set_connect_state(SSL *s);
 void SSL_set_accept_state(SSL *s);
 
 long SSL_get_default_timeout(const SSL *s);
 
 int SSL_library_init(void);
 
 char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size);
 STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
 
 SSL *SSL_dup(SSL *ssl);
 
 X509 *SSL_get_certificate(const SSL *ssl);
 /*
  * EVP_PKEY
  */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl);
 
 void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
 int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
 void SSL_set_quiet_shutdown(SSL *ssl, int mode);
 int SSL_get_quiet_shutdown(const SSL *ssl);
 void SSL_set_shutdown(SSL *ssl, int mode);
 int SSL_get_shutdown(const SSL *ssl);
 int SSL_version(const SSL *ssl);
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
 int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
                                   const char *CApath);
 # define SSL_get0_session SSL_get_session/* just peek at pointer */
 SSL_SESSION *SSL_get_session(const SSL *ssl);
 SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */
 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
 SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
 void SSL_set_info_callback(SSL *ssl,
                            void (*cb) (const SSL *ssl, int type, int val));
 void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type,
                                                int val);
 int SSL_state(const SSL *ssl);
 void SSL_set_state(SSL *ssl, int state);
 
 void SSL_set_verify_result(SSL *ssl, long v);
 long SSL_get_verify_result(const SSL *ssl);
 
 int SSL_set_ex_data(SSL *ssl, int idx, void *data);
 void *SSL_get_ex_data(const SSL *ssl, int idx);
 int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
 
 int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data);
 void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
 int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                  CRYPTO_EX_new *new_func,
                                  CRYPTO_EX_dup *dup_func,
                                  CRYPTO_EX_free *free_func);
 
 int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
 void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
 int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                              CRYPTO_EX_dup *dup_func,
                              CRYPTO_EX_free *free_func);
 
 int SSL_get_ex_data_X509_STORE_CTX_idx(void);
 
 # define SSL_CTX_sess_set_cache_size(ctx,t) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL)
 # define SSL_CTX_sess_get_cache_size(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL)
 # define SSL_CTX_set_session_cache_mode(ctx,m) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL)
 # define SSL_CTX_get_session_cache_mode(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL)
 
 # define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx)
 # define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m)
 # define SSL_CTX_get_read_ahead(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL)
 # define SSL_CTX_set_read_ahead(ctx,m) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL)
 # define SSL_CTX_get_max_cert_list(ctx) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
 # define SSL_CTX_set_max_cert_list(ctx,m) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
 # define SSL_get_max_cert_list(ssl) \
         SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL)
 # define SSL_set_max_cert_list(ssl,m) \
         SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL)
 
 # define SSL_CTX_set_max_send_fragment(ctx,m) \
         SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
 # define SSL_set_max_send_fragment(ssl,m) \
         SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL)
 
      /* NB: the keylength is only applicable when is_export is true */
 # ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx,
                                   RSA *(*cb) (SSL *ssl, int is_export,
                                               int keylength));
 
 void SSL_set_tmp_rsa_callback(SSL *ssl,
                               RSA *(*cb) (SSL *ssl, int is_export,
                                           int keylength));
 # endif
 # ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                  DH *(*dh) (SSL *ssl, int is_export,
                                             int keylength));
 void SSL_set_tmp_dh_callback(SSL *ssl,
                              DH *(*dh) (SSL *ssl, int is_export,
                                         int keylength));
 # endif
 # ifndef OPENSSL_NO_ECDH
 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
                                    EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                     int keylength));
 void SSL_set_tmp_ecdh_callback(SSL *ssl,
                                EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                 int keylength));
 # endif
 
 # ifndef OPENSSL_NO_COMP
 const COMP_METHOD *SSL_get_current_compression(SSL *s);
 const COMP_METHOD *SSL_get_current_expansion(SSL *s);
 const char *SSL_COMP_get_name(const COMP_METHOD *comp);
 STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void);
 int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
 # else
 const void *SSL_get_current_compression(SSL *s);
 const void *SSL_get_current_expansion(SSL *s);
 const char *SSL_COMP_get_name(const void *comp);
 void *SSL_COMP_get_compression_methods(void);
 int SSL_COMP_add_compression_method(int id, void *cm);
 # endif
 
 /* TLS extensions functions */
 int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len);
 
 int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
                                   void *arg);
 
 /* Pre-shared secret session resumption functions */
 int SSL_set_session_secret_cb(SSL *s,
                               tls_session_secret_cb_fn tls_session_secret_cb,
                               void *arg);
 
 void SSL_set_debug(SSL *s, int debug);
 int SSL_cache_hit(SSL *s);
 
 # ifndef OPENSSL_NO_UNIT_TEST
 const struct openssl_ssl_test_functions *SSL_test_functions(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_SSL_strings(void);
 
 /* Error codes for the SSL functions. */
 
 /* Function codes. */
 # define SSL_F_CLIENT_CERTIFICATE                         100
 # define SSL_F_CLIENT_FINISHED                            167
 # define SSL_F_CLIENT_HELLO                               101
 # define SSL_F_CLIENT_MASTER_KEY                          102
 # define SSL_F_D2I_SSL_SESSION                            103
 # define SSL_F_DO_DTLS1_WRITE                             245
 # define SSL_F_DO_SSL3_WRITE                              104
 # define SSL_F_DTLS1_ACCEPT                               246
 # define SSL_F_DTLS1_ADD_CERT_TO_BUF                      295
 # define SSL_F_DTLS1_BUFFER_RECORD                        247
 # define SSL_F_DTLS1_CHECK_TIMEOUT_NUM                    316
 # define SSL_F_DTLS1_CLIENT_HELLO                         248
 # define SSL_F_DTLS1_CONNECT                              249
 # define SSL_F_DTLS1_ENC                                  250
 # define SSL_F_DTLS1_GET_HELLO_VERIFY                     251
 # define SSL_F_DTLS1_GET_MESSAGE                          252
 # define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT                 253
 # define SSL_F_DTLS1_GET_RECORD                           254
 # define SSL_F_DTLS1_HANDLE_TIMEOUT                       297
 # define SSL_F_DTLS1_HEARTBEAT                            305
 # define SSL_F_DTLS1_OUTPUT_CERT_CHAIN                    255
 # define SSL_F_DTLS1_PREPROCESS_FRAGMENT                  288
+# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS             424
 # define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE           256
 # define SSL_F_DTLS1_PROCESS_RECORD                       257
 # define SSL_F_DTLS1_READ_BYTES                           258
 # define SSL_F_DTLS1_READ_FAILED                          259
 # define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST             260
 # define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE              261
 # define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE             262
 # define SSL_F_DTLS1_SEND_CLIENT_VERIFY                   263
 # define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST            264
 # define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE              265
 # define SSL_F_DTLS1_SEND_SERVER_HELLO                    266
 # define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE             267
 # define SSL_F_DTLS1_WRITE_APP_DATA_BYTES                 268
 # define SSL_F_GET_CLIENT_FINISHED                        105
 # define SSL_F_GET_CLIENT_HELLO                           106
 # define SSL_F_GET_CLIENT_MASTER_KEY                      107
 # define SSL_F_GET_SERVER_FINISHED                        108
 # define SSL_F_GET_SERVER_HELLO                           109
 # define SSL_F_GET_SERVER_VERIFY                          110
 # define SSL_F_I2D_SSL_SESSION                            111
 # define SSL_F_READ_N                                     112
 # define SSL_F_REQUEST_CERTIFICATE                        113
 # define SSL_F_SERVER_FINISH                              239
 # define SSL_F_SERVER_HELLO                               114
 # define SSL_F_SERVER_VERIFY                              240
 # define SSL_F_SSL23_ACCEPT                               115
 # define SSL_F_SSL23_CLIENT_HELLO                         116
 # define SSL_F_SSL23_CONNECT                              117
 # define SSL_F_SSL23_GET_CLIENT_HELLO                     118
 # define SSL_F_SSL23_GET_SERVER_HELLO                     119
 # define SSL_F_SSL23_PEEK                                 237
 # define SSL_F_SSL23_READ                                 120
 # define SSL_F_SSL23_WRITE                                121
 # define SSL_F_SSL2_ACCEPT                                122
 # define SSL_F_SSL2_CONNECT                               123
 # define SSL_F_SSL2_ENC_INIT                              124
 # define SSL_F_SSL2_GENERATE_KEY_MATERIAL                 241
 # define SSL_F_SSL2_PEEK                                  234
 # define SSL_F_SSL2_READ                                  125
 # define SSL_F_SSL2_READ_INTERNAL                         236
 # define SSL_F_SSL2_SET_CERTIFICATE                       126
 # define SSL_F_SSL2_WRITE                                 127
 # define SSL_F_SSL3_ACCEPT                                128
 # define SSL_F_SSL3_ADD_CERT_TO_BUF                       296
 # define SSL_F_SSL3_CALLBACK_CTRL                         233
 # define SSL_F_SSL3_CHANGE_CIPHER_STATE                   129
 # define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM              130
 # define SSL_F_SSL3_CHECK_CLIENT_HELLO                    304
 # define SSL_F_SSL3_CHECK_FINISHED                        339
 # define SSL_F_SSL3_CLIENT_HELLO                          131
 # define SSL_F_SSL3_CONNECT                               132
 # define SSL_F_SSL3_CTRL                                  213
 # define SSL_F_SSL3_CTX_CTRL                              133
 # define SSL_F_SSL3_DIGEST_CACHED_RECORDS                 293
 # define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC                 292
 # define SSL_F_SSL3_ENC                                   134
 # define SSL_F_SSL3_GENERATE_KEY_BLOCK                    238
 # define SSL_F_SSL3_GENERATE_MASTER_SECRET                388
 # define SSL_F_SSL3_GET_CERTIFICATE_REQUEST               135
 # define SSL_F_SSL3_GET_CERT_STATUS                       289
 # define SSL_F_SSL3_GET_CERT_VERIFY                       136
 # define SSL_F_SSL3_GET_CLIENT_CERTIFICATE                137
 # define SSL_F_SSL3_GET_CLIENT_HELLO                      138
 # define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE               139
 # define SSL_F_SSL3_GET_FINISHED                          140
 # define SSL_F_SSL3_GET_KEY_EXCHANGE                      141
 # define SSL_F_SSL3_GET_MESSAGE                           142
 # define SSL_F_SSL3_GET_NEW_SESSION_TICKET                283
 # define SSL_F_SSL3_GET_NEXT_PROTO                        306
 # define SSL_F_SSL3_GET_RECORD                            143
 # define SSL_F_SSL3_GET_SERVER_CERTIFICATE                144
 # define SSL_F_SSL3_GET_SERVER_DONE                       145
 # define SSL_F_SSL3_GET_SERVER_HELLO                      146
 # define SSL_F_SSL3_HANDSHAKE_MAC                         285
 # define SSL_F_SSL3_NEW_SESSION_TICKET                    287
 # define SSL_F_SSL3_OUTPUT_CERT_CHAIN                     147
 # define SSL_F_SSL3_PEEK                                  235
 # define SSL_F_SSL3_READ_BYTES                            148
 # define SSL_F_SSL3_READ_N                                149
 # define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST              150
 # define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE               151
 # define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE              152
 # define SSL_F_SSL3_SEND_CLIENT_VERIFY                    153
 # define SSL_F_SSL3_SEND_SERVER_CERTIFICATE               154
 # define SSL_F_SSL3_SEND_SERVER_HELLO                     242
 # define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE              155
 # define SSL_F_SSL3_SETUP_KEY_BLOCK                       157
 # define SSL_F_SSL3_SETUP_READ_BUFFER                     156
 # define SSL_F_SSL3_SETUP_WRITE_BUFFER                    291
 # define SSL_F_SSL3_WRITE_BYTES                           158
 # define SSL_F_SSL3_WRITE_PENDING                         159
 # define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT        298
 # define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT                 277
 # define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT           307
 # define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK         215
 # define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK        216
 # define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT        299
 # define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT                 278
 # define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT           308
 # define SSL_F_SSL_BAD_METHOD                             160
 # define SSL_F_SSL_BYTES_TO_CIPHER_LIST                   161
 # define SSL_F_SSL_CERT_DUP                               221
 # define SSL_F_SSL_CERT_INST                              222
 # define SSL_F_SSL_CERT_INSTANTIATE                       214
 # define SSL_F_SSL_CERT_NEW                               162
 # define SSL_F_SSL_CHECK_PRIVATE_KEY                      163
 # define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT               280
 # define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG            279
 # define SSL_F_SSL_CIPHER_PROCESS_RULESTR                 230
 # define SSL_F_SSL_CIPHER_STRENGTH_SORT                   231
 # define SSL_F_SSL_CLEAR                                  164
 # define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD            165
 # define SSL_F_SSL_CREATE_CIPHER_LIST                     166
 # define SSL_F_SSL_CTRL                                   232
 # define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY                  168
 # define SSL_F_SSL_CTX_MAKE_PROFILES                      309
 # define SSL_F_SSL_CTX_NEW                                169
 # define SSL_F_SSL_CTX_SET_CIPHER_LIST                    269
 # define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE             290
 # define SSL_F_SSL_CTX_SET_PURPOSE                        226
 # define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT             219
 # define SSL_F_SSL_CTX_SET_SSL_VERSION                    170
 # define SSL_F_SSL_CTX_SET_TRUST                          229
 # define SSL_F_SSL_CTX_USE_CERTIFICATE                    171
 # define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1               172
 # define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE         220
 # define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE               173
 # define SSL_F_SSL_CTX_USE_PRIVATEKEY                     174
 # define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1                175
 # define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE                176
 # define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT              272
 # define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY                  177
 # define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1             178
 # define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE             179
 # define SSL_F_SSL_DO_HANDSHAKE                           180
 # define SSL_F_SSL_GET_NEW_SESSION                        181
 # define SSL_F_SSL_GET_PREV_SESSION                       217
 # define SSL_F_SSL_GET_SERVER_SEND_CERT                   182
 # define SSL_F_SSL_GET_SERVER_SEND_PKEY                   317
 # define SSL_F_SSL_GET_SIGN_PKEY                          183
 # define SSL_F_SSL_INIT_WBIO_BUFFER                       184
 # define SSL_F_SSL_LOAD_CLIENT_CA_FILE                    185
 # define SSL_F_SSL_NEW                                    186
 # define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT      300
 # define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT               302
 # define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT         310
 # define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT      301
 # define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT               303
 # define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT         311
 # define SSL_F_SSL_PEEK                                   270
 # define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT             281
 # define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT             282
 # define SSL_F_SSL_READ                                   223
 # define SSL_F_SSL_RSA_PRIVATE_DECRYPT                    187
 # define SSL_F_SSL_RSA_PUBLIC_ENCRYPT                     188
 # define SSL_F_SSL_SESSION_DUP                            348
 # define SSL_F_SSL_SESSION_NEW                            189
 # define SSL_F_SSL_SESSION_PRINT_FP                       190
 # define SSL_F_SSL_SESSION_SET1_ID_CONTEXT                312
 # define SSL_F_SSL_SESS_CERT_NEW                          225
 # define SSL_F_SSL_SET_CERT                               191
 # define SSL_F_SSL_SET_CIPHER_LIST                        271
 # define SSL_F_SSL_SET_FD                                 192
 # define SSL_F_SSL_SET_PKEY                               193
 # define SSL_F_SSL_SET_PURPOSE                            227
 # define SSL_F_SSL_SET_RFD                                194
 # define SSL_F_SSL_SET_SESSION                            195
 # define SSL_F_SSL_SET_SESSION_ID_CONTEXT                 218
 # define SSL_F_SSL_SET_SESSION_TICKET_EXT                 294
 # define SSL_F_SSL_SET_TRUST                              228
 # define SSL_F_SSL_SET_WFD                                196
 # define SSL_F_SSL_SHUTDOWN                               224
 # define SSL_F_SSL_SRP_CTX_INIT                           313
 # define SSL_F_SSL_UNDEFINED_CONST_FUNCTION               243
 # define SSL_F_SSL_UNDEFINED_FUNCTION                     197
 # define SSL_F_SSL_UNDEFINED_VOID_FUNCTION                244
 # define SSL_F_SSL_USE_CERTIFICATE                        198
 # define SSL_F_SSL_USE_CERTIFICATE_ASN1                   199
 # define SSL_F_SSL_USE_CERTIFICATE_FILE                   200
 # define SSL_F_SSL_USE_PRIVATEKEY                         201
 # define SSL_F_SSL_USE_PRIVATEKEY_ASN1                    202
 # define SSL_F_SSL_USE_PRIVATEKEY_FILE                    203
 # define SSL_F_SSL_USE_PSK_IDENTITY_HINT                  273
 # define SSL_F_SSL_USE_RSAPRIVATEKEY                      204
 # define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1                 205
 # define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE                 206
 # define SSL_F_SSL_VERIFY_CERT_CHAIN                      207
 # define SSL_F_SSL_WRITE                                  208
 # define SSL_F_TLS1_CERT_VERIFY_MAC                       286
 # define SSL_F_TLS1_CHANGE_CIPHER_STATE                   209
 # define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT              274
 # define SSL_F_TLS1_ENC                                   210
 # define SSL_F_TLS1_EXPORT_KEYING_MATERIAL                314
 # define SSL_F_TLS1_HEARTBEAT                             315
 # define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT            275
 # define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT            276
 # define SSL_F_TLS1_PRF                                   284
 # define SSL_F_TLS1_SETUP_KEY_BLOCK                       211
 # define SSL_F_WRITE_PENDING                              212
 
 /* Reason codes. */
 # define SSL_R_APP_DATA_IN_HANDSHAKE                      100
 # define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272
 # define SSL_R_BAD_ALERT_RECORD                           101
 # define SSL_R_BAD_AUTHENTICATION_TYPE                    102
 # define SSL_R_BAD_CHANGE_CIPHER_SPEC                     103
 # define SSL_R_BAD_CHECKSUM                               104
 # define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK              106
 # define SSL_R_BAD_DECOMPRESSION                          107
 # define SSL_R_BAD_DH_G_LENGTH                            108
 # define SSL_R_BAD_DH_G_VALUE                             375
 # define SSL_R_BAD_DH_PUB_KEY_LENGTH                      109
 # define SSL_R_BAD_DH_PUB_KEY_VALUE                       393
 # define SSL_R_BAD_DH_P_LENGTH                            110
 # define SSL_R_BAD_DH_P_VALUE                             395
 # define SSL_R_BAD_DIGEST_LENGTH                          111
 # define SSL_R_BAD_DSA_SIGNATURE                          112
 # define SSL_R_BAD_ECC_CERT                               304
 # define SSL_R_BAD_ECDSA_SIGNATURE                        305
 # define SSL_R_BAD_ECPOINT                                306
 # define SSL_R_BAD_HANDSHAKE_LENGTH                       332
 # define SSL_R_BAD_HELLO_REQUEST                          105
 # define SSL_R_BAD_LENGTH                                 271
 # define SSL_R_BAD_MAC_DECODE                             113
 # define SSL_R_BAD_MAC_LENGTH                             333
 # define SSL_R_BAD_MESSAGE_TYPE                           114
 # define SSL_R_BAD_PACKET_LENGTH                          115
 # define SSL_R_BAD_PROTOCOL_VERSION_NUMBER                116
 # define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH               316
 # define SSL_R_BAD_RESPONSE_ARGUMENT                      117
 # define SSL_R_BAD_RSA_DECRYPT                            118
 # define SSL_R_BAD_RSA_ENCRYPT                            119
 # define SSL_R_BAD_RSA_E_LENGTH                           120
 # define SSL_R_BAD_RSA_MODULUS_LENGTH                     121
 # define SSL_R_BAD_RSA_SIGNATURE                          122
 # define SSL_R_BAD_SIGNATURE                              123
 # define SSL_R_BAD_SRP_A_LENGTH                           347
 # define SSL_R_BAD_SRP_B_LENGTH                           348
 # define SSL_R_BAD_SRP_G_LENGTH                           349
 # define SSL_R_BAD_SRP_N_LENGTH                           350
 # define SSL_R_BAD_SRP_PARAMETERS                         371
 # define SSL_R_BAD_SRP_S_LENGTH                           351
 # define SSL_R_BAD_SRTP_MKI_VALUE                         352
 # define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST           353
 # define SSL_R_BAD_SSL_FILETYPE                           124
 # define SSL_R_BAD_SSL_SESSION_ID_LENGTH                  125
 # define SSL_R_BAD_STATE                                  126
 # define SSL_R_BAD_WRITE_RETRY                            127
 # define SSL_R_BIO_NOT_SET                                128
 # define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG                  129
 # define SSL_R_BN_LIB                                     130
 # define SSL_R_CA_DN_LENGTH_MISMATCH                      131
 # define SSL_R_CA_DN_TOO_LONG                             132
 # define SSL_R_CCS_RECEIVED_EARLY                         133
 # define SSL_R_CERTIFICATE_VERIFY_FAILED                  134
 # define SSL_R_CERT_LENGTH_MISMATCH                       135
 # define SSL_R_CHALLENGE_IS_DIFFERENT                     136
 # define SSL_R_CIPHER_CODE_WRONG_LENGTH                   137
 # define SSL_R_CIPHER_OR_HASH_UNAVAILABLE                 138
 # define SSL_R_CIPHER_TABLE_SRC_ERROR                     139
 # define SSL_R_CLIENTHELLO_TLSEXT                         226
 # define SSL_R_COMPRESSED_LENGTH_TOO_LONG                 140
 # define SSL_R_COMPRESSION_DISABLED                       343
 # define SSL_R_COMPRESSION_FAILURE                        141
 # define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE    307
 # define SSL_R_COMPRESSION_LIBRARY_ERROR                  142
 # define SSL_R_CONNECTION_ID_IS_DIFFERENT                 143
 # define SSL_R_CONNECTION_TYPE_NOT_SET                    144
 # define SSL_R_COOKIE_MISMATCH                            308
 # define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED              145
 # define SSL_R_DATA_LENGTH_TOO_LONG                       146
 # define SSL_R_DECRYPTION_FAILED                          147
 # define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC        281
 # define SSL_R_DH_KEY_TOO_SMALL                           372
 # define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG            148
 # define SSL_R_DIGEST_CHECK_FAILED                        149
 # define SSL_R_DTLS_MESSAGE_TOO_BIG                       334
 # define SSL_R_DUPLICATE_COMPRESSION_ID                   309
 # define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT             317
 # define SSL_R_ECC_CERT_NOT_FOR_SIGNING                   318
 # define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE         322
 # define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE        323
 # define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER               310
 # define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST         354
 # define SSL_R_ENCRYPTED_LENGTH_TOO_LONG                  150
 # define SSL_R_ERROR_GENERATING_TMP_RSA_KEY               282
 # define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST              151
 # define SSL_R_EXCESSIVE_MESSAGE_SIZE                     152
 # define SSL_R_EXTRA_DATA_IN_MESSAGE                      153
 # define SSL_R_GOT_A_FIN_BEFORE_A_CCS                     154
 # define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS                355
 # define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION           356
 # define SSL_R_HTTPS_PROXY_REQUEST                        155
 # define SSL_R_HTTP_REQUEST                               156
 # define SSL_R_ILLEGAL_PADDING                            283
 # define SSL_R_INAPPROPRIATE_FALLBACK                     373
 # define SSL_R_INCONSISTENT_COMPRESSION                   340
 # define SSL_R_INVALID_CHALLENGE_LENGTH                   158
 # define SSL_R_INVALID_COMMAND                            280
 # define SSL_R_INVALID_COMPRESSION_ALGORITHM              341
 # define SSL_R_INVALID_PURPOSE                            278
 # define SSL_R_INVALID_SRP_USERNAME                       357
 # define SSL_R_INVALID_STATUS_RESPONSE                    328
 # define SSL_R_INVALID_TICKET_KEYS_LENGTH                 325
 # define SSL_R_INVALID_TRUST                              279
 # define SSL_R_KEY_ARG_TOO_LONG                           284
 # define SSL_R_KRB5                                       285
 # define SSL_R_KRB5_C_CC_PRINC                            286
 # define SSL_R_KRB5_C_GET_CRED                            287
 # define SSL_R_KRB5_C_INIT                                288
 # define SSL_R_KRB5_C_MK_REQ                              289
 # define SSL_R_KRB5_S_BAD_TICKET                          290
 # define SSL_R_KRB5_S_INIT                                291
 # define SSL_R_KRB5_S_RD_REQ                              292
 # define SSL_R_KRB5_S_TKT_EXPIRED                         293
 # define SSL_R_KRB5_S_TKT_NYV                             294
 # define SSL_R_KRB5_S_TKT_SKEW                            295
 # define SSL_R_LENGTH_MISMATCH                            159
 # define SSL_R_LENGTH_TOO_SHORT                           160
 # define SSL_R_LIBRARY_BUG                                274
 # define SSL_R_LIBRARY_HAS_NO_CIPHERS                     161
 # define SSL_R_MESSAGE_TOO_LONG                           296
 # define SSL_R_MISSING_DH_DSA_CERT                        162
 # define SSL_R_MISSING_DH_KEY                             163
 # define SSL_R_MISSING_DH_RSA_CERT                        164
 # define SSL_R_MISSING_DSA_SIGNING_CERT                   165
 # define SSL_R_MISSING_EXPORT_TMP_DH_KEY                  166
 # define SSL_R_MISSING_EXPORT_TMP_RSA_KEY                 167
 # define SSL_R_MISSING_RSA_CERTIFICATE                    168
 # define SSL_R_MISSING_RSA_ENCRYPTING_CERT                169
 # define SSL_R_MISSING_RSA_SIGNING_CERT                   170
 # define SSL_R_MISSING_SRP_PARAM                          358
 # define SSL_R_MISSING_TMP_DH_KEY                         171
 # define SSL_R_MISSING_TMP_ECDH_KEY                       311
 # define SSL_R_MISSING_TMP_RSA_KEY                        172
 # define SSL_R_MISSING_TMP_RSA_PKEY                       173
 # define SSL_R_MISSING_VERIFY_MESSAGE                     174
 # define SSL_R_MULTIPLE_SGC_RESTARTS                      346
 # define SSL_R_NON_SSLV2_INITIAL_PACKET                   175
 # define SSL_R_NO_CERTIFICATES_RETURNED                   176
 # define SSL_R_NO_CERTIFICATE_ASSIGNED                    177
 # define SSL_R_NO_CERTIFICATE_RETURNED                    178
 # define SSL_R_NO_CERTIFICATE_SET                         179
 # define SSL_R_NO_CERTIFICATE_SPECIFIED                   180
 # define SSL_R_NO_CIPHERS_AVAILABLE                       181
 # define SSL_R_NO_CIPHERS_PASSED                          182
 # define SSL_R_NO_CIPHERS_SPECIFIED                       183
 # define SSL_R_NO_CIPHER_LIST                             184
 # define SSL_R_NO_CIPHER_MATCH                            185
 # define SSL_R_NO_CLIENT_CERT_METHOD                      331
 # define SSL_R_NO_CLIENT_CERT_RECEIVED                    186
 # define SSL_R_NO_COMPRESSION_SPECIFIED                   187
 # define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER           330
 # define SSL_R_NO_METHOD_SPECIFIED                        188
 # define SSL_R_NO_PRIVATEKEY                              189
 # define SSL_R_NO_PRIVATE_KEY_ASSIGNED                    190
 # define SSL_R_NO_PROTOCOLS_AVAILABLE                     191
 # define SSL_R_NO_PUBLICKEY                               192
 # define SSL_R_NO_RENEGOTIATION                           339
 # define SSL_R_NO_REQUIRED_DIGEST                         324
 # define SSL_R_NO_SHARED_CIPHER                           193
 # define SSL_R_NO_SRTP_PROFILES                           359
 # define SSL_R_NO_VERIFY_CALLBACK                         194
 # define SSL_R_NULL_SSL_CTX                               195
 # define SSL_R_NULL_SSL_METHOD_PASSED                     196
 # define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED            197
 # define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344
 # define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE              297
 # define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG                  327
 # define SSL_R_PACKET_LENGTH_TOO_LONG                     198
 # define SSL_R_PARSE_TLSEXT                               227
 # define SSL_R_PATH_TOO_LONG                              270
 # define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE          199
 # define SSL_R_PEER_ERROR                                 200
 # define SSL_R_PEER_ERROR_CERTIFICATE                     201
 # define SSL_R_PEER_ERROR_NO_CERTIFICATE                  202
 # define SSL_R_PEER_ERROR_NO_CIPHER                       203
 # define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE    204
 # define SSL_R_PRE_MAC_LENGTH_TOO_LONG                    205
 # define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS          206
 # define SSL_R_PROTOCOL_IS_SHUTDOWN                       207
 # define SSL_R_PSK_IDENTITY_NOT_FOUND                     223
 # define SSL_R_PSK_NO_CLIENT_CB                           224
 # define SSL_R_PSK_NO_SERVER_CB                           225
 # define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR                   208
 # define SSL_R_PUBLIC_KEY_IS_NOT_RSA                      209
 # define SSL_R_PUBLIC_KEY_NOT_RSA                         210
 # define SSL_R_READ_BIO_NOT_SET                           211
 # define SSL_R_READ_TIMEOUT_EXPIRED                       312
 # define SSL_R_READ_WRONG_PACKET_TYPE                     212
 # define SSL_R_RECORD_LENGTH_MISMATCH                     213
 # define SSL_R_RECORD_TOO_LARGE                           214
 # define SSL_R_RECORD_TOO_SMALL                           298
 # define SSL_R_RENEGOTIATE_EXT_TOO_LONG                   335
 # define SSL_R_RENEGOTIATION_ENCODING_ERR                 336
 # define SSL_R_RENEGOTIATION_MISMATCH                     337
 # define SSL_R_REQUIRED_CIPHER_MISSING                    215
 # define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING    342
 # define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO                 216
 # define SSL_R_REUSE_CERT_TYPE_NOT_ZERO                   217
 # define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO                 218
 # define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING           345
 # define SSL_R_SERVERHELLO_TLSEXT                         275
 # define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED           277
 # define SSL_R_SHORT_READ                                 219
 # define SSL_R_SIGNATURE_ALGORITHMS_ERROR                 360
 # define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE      220
 # define SSL_R_SRP_A_CALC                                 361
 # define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES           362
 # define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG      363
 # define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE            364
 # define SSL_R_SSL23_DOING_SESSION_ID_REUSE               221
 # define SSL_R_SSL2_CONNECTION_ID_TOO_LONG                299
 # define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT             321
 # define SSL_R_SSL3_EXT_INVALID_SERVERNAME                319
 # define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE           320
 # define SSL_R_SSL3_SESSION_ID_TOO_LONG                   300
 # define SSL_R_SSL3_SESSION_ID_TOO_SHORT                  222
 # define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE                1042
 # define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC                 1020
 # define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED            1045
 # define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED            1044
 # define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN            1046
 # define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE          1030
 # define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE              1040
 # define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER              1047
 # define SSL_R_SSLV3_ALERT_NO_CERTIFICATE                 1041
 # define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE             1010
 # define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE        1043
 # define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION         228
 # define SSL_R_SSL_HANDSHAKE_FAILURE                      229
 # define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS                 230
 # define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED             301
 # define SSL_R_SSL_SESSION_ID_CONFLICT                    302
 # define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG            273
 # define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH              303
 # define SSL_R_SSL_SESSION_ID_IS_DIFFERENT                231
 # define SSL_R_TLSV1_ALERT_ACCESS_DENIED                  1049
 # define SSL_R_TLSV1_ALERT_DECODE_ERROR                   1050
 # define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED              1021
 # define SSL_R_TLSV1_ALERT_DECRYPT_ERROR                  1051
 # define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION             1060
 # define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK         1086
 # define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY          1071
 # define SSL_R_TLSV1_ALERT_INTERNAL_ERROR                 1080
 # define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION               1100
 # define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION               1070
 # define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW                1022
 # define SSL_R_TLSV1_ALERT_UNKNOWN_CA                     1048
 # define SSL_R_TLSV1_ALERT_USER_CANCELLED                 1090
 # define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE           1114
 # define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE      1113
 # define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE             1111
 # define SSL_R_TLSV1_UNRECOGNIZED_NAME                    1112
 # define SSL_R_TLSV1_UNSUPPORTED_EXTENSION                1110
 # define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER       232
 # define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT           365
 # define SSL_R_TLS_HEARTBEAT_PENDING                      366
 # define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL                 367
 # define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST             157
 # define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
 # define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG    234
 # define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER            235
 # define SSL_R_UNABLE_TO_DECODE_DH_CERTS                  236
 # define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS                313
 # define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY               237
 # define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS               238
 # define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS             314
 # define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS       239
 # define SSL_R_UNABLE_TO_FIND_SSL_METHOD                  240
 # define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES           241
 # define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES           242
 # define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES          243
 # define SSL_R_UNEXPECTED_MESSAGE                         244
 # define SSL_R_UNEXPECTED_RECORD                          245
 # define SSL_R_UNINITIALIZED                              276
 # define SSL_R_UNKNOWN_ALERT_TYPE                         246
 # define SSL_R_UNKNOWN_CERTIFICATE_TYPE                   247
 # define SSL_R_UNKNOWN_CIPHER_RETURNED                    248
 # define SSL_R_UNKNOWN_CIPHER_TYPE                        249
 # define SSL_R_UNKNOWN_DIGEST                             368
 # define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE                  250
 # define SSL_R_UNKNOWN_PKEY_TYPE                          251
 # define SSL_R_UNKNOWN_PROTOCOL                           252
 # define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE                  253
 # define SSL_R_UNKNOWN_SSL_VERSION                        254
 # define SSL_R_UNKNOWN_STATE                              255
 # define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED       338
 # define SSL_R_UNSUPPORTED_CIPHER                         256
 # define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM          257
 # define SSL_R_UNSUPPORTED_DIGEST_TYPE                    326
 # define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE                 315
 # define SSL_R_UNSUPPORTED_PROTOCOL                       258
 # define SSL_R_UNSUPPORTED_SSL_VERSION                    259
 # define SSL_R_UNSUPPORTED_STATUS_TYPE                    329
 # define SSL_R_USE_SRTP_NOT_NEGOTIATED                    369
 # define SSL_R_WRITE_BIO_NOT_SET                          260
 # define SSL_R_WRONG_CIPHER_RETURNED                      261
 # define SSL_R_WRONG_MESSAGE_TYPE                         262
 # define SSL_R_WRONG_NUMBER_OF_KEY_BITS                   263
 # define SSL_R_WRONG_SIGNATURE_LENGTH                     264
 # define SSL_R_WRONG_SIGNATURE_SIZE                       265
 # define SSL_R_WRONG_SIGNATURE_TYPE                       370
 # define SSL_R_WRONG_SSL_VERSION                          266
 # define SSL_R_WRONG_VERSION_NUMBER                       267
 # define SSL_R_X509_LIB                                   268
 # define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS           269
 
 #ifdef  __cplusplus
 }
 #endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/ssl_err.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/ssl_err.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/ssl_err.c	(revision 306191)
@@ -1,797 +1,799 @@
 /* ssl/ssl_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2016 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 <openssl/ssl.h>
 
 /* BEGIN ERROR CODES */
 #ifndef OPENSSL_NO_ERR
 
 # define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0)
 # define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason)
 
 static ERR_STRING_DATA SSL_str_functs[] = {
     {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"},
     {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"},
     {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"},
     {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"},
     {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "DO_DTLS1_WRITE"},
     {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"},
     {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"},
     {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"},
     {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"},
     {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "DTLS1_CHECK_TIMEOUT_NUM"},
     {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"},
     {ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"},
     {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"},
     {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "DTLS1_GET_MESSAGE"},
     {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT),
      "DTLS1_GET_MESSAGE_FRAGMENT"},
     {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"},
     {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"},
     {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"},
     {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"},
     {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
+    {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),
+     "DTLS1_PROCESS_BUFFERED_RECORDS"},
     {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),
      "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
     {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"},
     {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"},
     {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "DTLS1_READ_FAILED"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST),
      "DTLS1_SEND_CERTIFICATE_REQUEST"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE),
      "DTLS1_SEND_CLIENT_CERTIFICATE"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE),
      "DTLS1_SEND_CLIENT_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "DTLS1_SEND_CLIENT_VERIFY"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST),
      "DTLS1_SEND_HELLO_VERIFY_REQUEST"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE),
      "DTLS1_SEND_SERVER_CERTIFICATE"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "DTLS1_SEND_SERVER_HELLO"},
     {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE),
      "DTLS1_SEND_SERVER_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES),
      "DTLS1_WRITE_APP_DATA_BYTES"},
     {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"},
     {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"},
     {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"},
     {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"},
     {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"},
     {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"},
     {ERR_FUNC(SSL_F_READ_N), "READ_N"},
     {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"},
     {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"},
     {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"},
     {ERR_FUNC(SSL_F_SSL23_ACCEPT), "SSL23_ACCEPT"},
     {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_SSL23_CONNECT), "SSL23_CONNECT"},
     {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"},
     {ERR_FUNC(SSL_F_SSL23_PEEK), "SSL23_PEEK"},
     {ERR_FUNC(SSL_F_SSL23_READ), "SSL23_READ"},
     {ERR_FUNC(SSL_F_SSL23_WRITE), "SSL23_WRITE"},
     {ERR_FUNC(SSL_F_SSL2_ACCEPT), "SSL2_ACCEPT"},
     {ERR_FUNC(SSL_F_SSL2_CONNECT), "SSL2_CONNECT"},
     {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "SSL2_ENC_INIT"},
     {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL),
      "SSL2_GENERATE_KEY_MATERIAL"},
     {ERR_FUNC(SSL_F_SSL2_PEEK), "SSL2_PEEK"},
     {ERR_FUNC(SSL_F_SSL2_READ), "SSL2_READ"},
     {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"},
     {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "SSL2_SET_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SSL2_WRITE), "SSL2_WRITE"},
     {ERR_FUNC(SSL_F_SSL3_ACCEPT), "SSL3_ACCEPT"},
     {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"},
     {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"},
     {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"},
     {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM),
      "SSL3_CHECK_CERT_AND_ALGORITHM"},
     {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"},
     {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"},
     {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"},
     {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS),
      "SSL3_DIGEST_CACHED_RECORDS"},
     {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC),
      "SSL3_DO_CHANGE_CIPHER_SPEC"},
     {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"},
     {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"},
     {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"},
     {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET),
      "ssl3_generate_master_secret"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST),
      "SSL3_GET_CERTIFICATE_REQUEST"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"},
     {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"},
     {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE),
      "SSL3_GET_CLIENT_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"},
     {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE),
      "SSL3_GET_CLIENT_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "SSL3_GET_FINISHED"},
     {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "SSL3_GET_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "SSL3_GET_MESSAGE"},
     {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET),
      "SSL3_GET_NEW_SESSION_TICKET"},
     {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "SSL3_GET_NEXT_PROTO"},
     {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"},
     {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE),
      "SSL3_GET_SERVER_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"},
     {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "SSL3_GET_SERVER_HELLO"},
     {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"},
     {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"},
     {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "SSL3_OUTPUT_CERT_CHAIN"},
     {ERR_FUNC(SSL_F_SSL3_PEEK), "SSL3_PEEK"},
     {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"},
     {ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"},
     {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST),
      "SSL3_SEND_CERTIFICATE_REQUEST"},
     {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE),
      "SSL3_SEND_CLIENT_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE),
      "SSL3_SEND_CLIENT_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"},
     {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE),
      "SSL3_SEND_SERVER_CERTIFICATE"},
     {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "SSL3_SEND_SERVER_HELLO"},
     {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE),
      "SSL3_SEND_SERVER_KEY_EXCHANGE"},
     {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"},
     {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "SSL3_SETUP_READ_BUFFER"},
     {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "SSL3_SETUP_WRITE_BUFFER"},
     {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"},
     {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"},
     {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT),
      "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
     {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT),
      "SSL_ADD_CLIENTHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT),
      "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"},
     {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK),
      "SSL_add_dir_cert_subjects_to_stack"},
     {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK),
      "SSL_add_file_cert_subjects_to_stack"},
     {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT),
      "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"},
     {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT),
      "SSL_ADD_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT),
      "SSL_ADD_SERVERHELLO_USE_SRTP_EXT"},
     {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"},
     {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"},
     {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"},
     {ERR_FUNC(SSL_F_SSL_CERT_INST), "SSL_CERT_INST"},
     {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"},
     {ERR_FUNC(SSL_F_SSL_CERT_NEW), "SSL_CERT_NEW"},
     {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"},
     {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT),
      "SSL_CHECK_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG),
      "SSL_CHECK_SRVR_ECC_CERT_AND_ALG"},
     {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR),
      "SSL_CIPHER_PROCESS_RULESTR"},
     {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"},
     {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"},
     {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD),
      "SSL_COMP_add_compression_method"},
     {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "SSL_CREATE_CIPHER_LIST"},
     {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"},
     {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"},
     {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"},
     {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE),
      "SSL_CTX_set_client_cert_engine"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT),
      "SSL_CTX_set_session_id_context"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"},
     {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1),
      "SSL_CTX_use_certificate_ASN1"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE),
      "SSL_CTX_use_certificate_chain_file"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE),
      "SSL_CTX_use_certificate_file"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1),
      "SSL_CTX_use_PrivateKey_ASN1"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE),
      "SSL_CTX_use_PrivateKey_file"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT),
      "SSL_CTX_use_psk_identity_hint"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1),
      "SSL_CTX_use_RSAPrivateKey_ASN1"},
     {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE),
      "SSL_CTX_use_RSAPrivateKey_file"},
     {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"},
     {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"},
     {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"},
     {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"},
     {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"},
     {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"},
     {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"},
     {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"},
     {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"},
     {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT),
      "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"},
     {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT),
      "SSL_PARSE_CLIENTHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT),
      "SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"},
     {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT),
      "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"},
     {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT),
      "SSL_PARSE_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT),
      "SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"},
     {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"},
     {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT),
      "SSL_PREPARE_CLIENTHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT),
      "SSL_PREPARE_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"},
     {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"},
     {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"},
     {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"},
     {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"},
     {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"},
     {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT),
      "SSL_SESSION_set1_id_context"},
     {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"},
     {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"},
     {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"},
     {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"},
     {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"},
     {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"},
     {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"},
     {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"},
     {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT),
      "SSL_set_session_id_context"},
     {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT),
      "SSL_set_session_ticket_ext"},
     {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"},
     {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"},
     {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"},
     {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"},
     {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION),
      "SSL_UNDEFINED_CONST_FUNCTION"},
     {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"},
     {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION),
      "SSL_UNDEFINED_VOID_FUNCTION"},
     {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"},
     {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"},
     {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"},
     {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"},
     {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"},
     {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"},
     {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"},
     {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"},
     {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1),
      "SSL_use_RSAPrivateKey_ASN1"},
     {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE),
      "SSL_use_RSAPrivateKey_file"},
     {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"},
     {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"},
     {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"},
     {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"},
     {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT),
      "TLS1_CHECK_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"},
     {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL),
      "TLS1_EXPORT_KEYING_MATERIAL"},
     {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"},
     {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT),
      "TLS1_PREPARE_CLIENTHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT),
      "TLS1_PREPARE_SERVERHELLO_TLSEXT"},
     {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"},
     {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"},
     {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"},
     {0, NULL}
 };
 
 static ERR_STRING_DATA SSL_str_reasons[] = {
     {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"},
     {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT),
      "attempt to reuse session in different context"},
     {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"},
     {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"},
     {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"},
     {ERR_REASON(SSL_R_BAD_CHECKSUM), "bad checksum"},
     {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK),
      "bad data returned by callback"},
     {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"},
     {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"},
     {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"},
     {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"},
     {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"},
     {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"},
     {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"},
     {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"},
     {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"},
     {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"},
     {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE), "bad ecdsa signature"},
     {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"},
     {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"},
     {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"},
     {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"},
     {ERR_REASON(SSL_R_BAD_MAC_DECODE), "bad mac decode"},
     {ERR_REASON(SSL_R_BAD_MAC_LENGTH), "bad mac length"},
     {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE), "bad message type"},
     {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"},
     {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER),
      "bad protocol version number"},
     {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH),
      "bad psk identity hint length"},
     {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT), "bad response argument"},
     {ERR_REASON(SSL_R_BAD_RSA_DECRYPT), "bad rsa decrypt"},
     {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"},
     {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH), "bad rsa e length"},
     {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"},
     {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE), "bad rsa signature"},
     {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"},
     {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"},
     {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH), "bad srp b length"},
     {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH), "bad srp g length"},
     {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH), "bad srp n length"},
     {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"},
     {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH), "bad srp s length"},
     {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"},
     {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST),
      "bad srtp protection profile list"},
     {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"},
     {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH),
      "bad ssl session id length"},
     {ERR_REASON(SSL_R_BAD_STATE), "bad state"},
     {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"},
     {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"},
     {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG),
      "block cipher pad is wrong"},
     {ERR_REASON(SSL_R_BN_LIB), "bn lib"},
     {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"},
     {ERR_REASON(SSL_R_CA_DN_TOO_LONG), "ca dn too long"},
     {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"},
     {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED),
      "certificate verify failed"},
     {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"},
     {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"},
     {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"},
     {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE),
      "cipher or hash unavailable"},
     {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"},
     {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"},
     {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG),
      "compressed length too long"},
     {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"},
     {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"},
     {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE),
      "compression id not within private range"},
     {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR),
      "compression library error"},
     {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT),
      "connection id is different"},
     {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"},
     {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"},
     {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED),
      "data between ccs and finished"},
     {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"},
     {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"},
     {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC),
      "decryption failed or bad record mac"},
     {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"},
     {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG),
      "dh public value length is wrong"},
     {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"},
     {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"},
     {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"},
     {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT),
      "ecc cert not for key agreement"},
     {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"},
     {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE),
      "ecc cert should have rsa signature"},
     {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE),
      "ecc cert should have sha1 signature"},
     {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER),
      "ecgroup too large for cipher"},
     {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST),
      "empty srtp protection profile list"},
     {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG),
      "encrypted length too long"},
     {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY),
      "error generating tmp rsa key"},
     {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST),
      "error in received cipher list"},
     {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"},
     {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"},
     {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"},
     {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS),
      "got next proto before a ccs"},
     {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION),
      "got next proto without seeing extension"},
     {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"},
     {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"},
     {ERR_REASON(SSL_R_ILLEGAL_PADDING), "illegal padding"},
     {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"},
     {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"},
     {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"},
     {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"},
     {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM),
      "invalid compression algorithm"},
     {ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"},
     {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"},
     {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"},
     {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH),
      "invalid ticket keys length"},
     {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"},
     {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG), "key arg too long"},
     {ERR_REASON(SSL_R_KRB5), "krb5"},
     {ERR_REASON(SSL_R_KRB5_C_CC_PRINC), "krb5 client cc principal (no tkt?)"},
     {ERR_REASON(SSL_R_KRB5_C_GET_CRED), "krb5 client get cred"},
     {ERR_REASON(SSL_R_KRB5_C_INIT), "krb5 client init"},
     {ERR_REASON(SSL_R_KRB5_C_MK_REQ), "krb5 client mk_req (expired tkt?)"},
     {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET), "krb5 server bad ticket"},
     {ERR_REASON(SSL_R_KRB5_S_INIT), "krb5 server init"},
     {ERR_REASON(SSL_R_KRB5_S_RD_REQ), "krb5 server rd_req (keytab perms?)"},
     {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED), "krb5 server tkt expired"},
     {ERR_REASON(SSL_R_KRB5_S_TKT_NYV), "krb5 server tkt not yet valid"},
     {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW), "krb5 server tkt skew"},
     {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"},
     {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"},
     {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"},
     {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"},
     {ERR_REASON(SSL_R_MESSAGE_TOO_LONG), "message too long"},
     {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT), "missing dh dsa cert"},
     {ERR_REASON(SSL_R_MISSING_DH_KEY), "missing dh key"},
     {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT), "missing dh rsa cert"},
     {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"},
     {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY),
      "missing export tmp dh key"},
     {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY),
      "missing export tmp rsa key"},
     {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"},
     {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT),
      "missing rsa encrypting cert"},
     {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"},
     {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"},
     {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"},
     {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"},
     {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY), "missing tmp rsa key"},
     {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY), "missing tmp rsa pkey"},
     {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"},
     {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS), "multiple sgc restarts"},
     {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"},
     {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"},
     {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"},
     {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"},
     {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"},
     {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"},
     {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"},
     {ERR_REASON(SSL_R_NO_CIPHERS_PASSED), "no ciphers passed"},
     {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"},
     {ERR_REASON(SSL_R_NO_CIPHER_LIST), "no cipher list"},
     {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"},
     {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"},
     {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"},
     {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"},
     {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER),
      "Peer haven't sent GOST certificate, required for selected ciphersuite"},
     {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"},
     {ERR_REASON(SSL_R_NO_PRIVATEKEY), "no privatekey"},
     {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"},
     {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"},
     {ERR_REASON(SSL_R_NO_PUBLICKEY), "no publickey"},
     {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"},
     {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST),
      "digest requred for handshake isn't computed"},
     {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"},
     {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"},
     {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK), "no verify callback"},
     {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"},
     {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"},
     {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED),
      "old session cipher not returned"},
     {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED),
      "old session compression algorithm not returned"},
     {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE),
      "only tls allowed in fips mode"},
     {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG),
      "opaque PRF input too long"},
     {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"},
     {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"},
     {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"},
     {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE),
      "peer did not return a certificate"},
     {ERR_REASON(SSL_R_PEER_ERROR), "peer error"},
     {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"},
     {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE),
      "peer error no certificate"},
     {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER), "peer error no cipher"},
     {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE),
      "peer error unsupported certificate type"},
     {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"},
     {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS),
      "problems mapping cipher functions"},
     {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"},
     {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"},
     {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"},
     {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"},
     {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"},
     {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA), "public key is not rsa"},
     {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"},
     {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"},
     {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"},
     {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"},
     {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"},
     {ERR_REASON(SSL_R_RECORD_TOO_LARGE), "record too large"},
     {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"},
     {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"},
     {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR),
      "renegotiation encoding err"},
     {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"},
     {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"},
     {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING),
      "required compresssion algorithm missing"},
     {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO),
      "reuse cert length not zero"},
     {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"},
     {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO),
      "reuse cipher list not zero"},
     {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),
      "scsv received when renegotiating"},
     {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"},
     {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),
      "session id context uninitialized"},
     {ERR_REASON(SSL_R_SHORT_READ), "short read"},
     {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR),
      "signature algorithms error"},
     {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),
      "signature for non signing certificate"},
     {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"},
     {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES),
      "srtp could not allocate profiles"},
     {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG),
      "srtp protection profile list too long"},
     {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE),
      "srtp unknown protection profile"},
     {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),
      "ssl23 doing session id reuse"},
     {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG),
      "ssl2 connection id too long"},
     {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT),
      "ssl3 ext invalid ecpointformat"},
     {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME),
      "ssl3 ext invalid servername"},
     {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE),
      "ssl3 ext invalid servername type"},
     {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"},
     {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT),
      "ssl3 session id too short"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE),
      "sslv3 alert bad certificate"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC),
      "sslv3 alert bad record mac"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED),
      "sslv3 alert certificate expired"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED),
      "sslv3 alert certificate revoked"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN),
      "sslv3 alert certificate unknown"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE),
      "sslv3 alert decompression failure"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE),
      "sslv3 alert handshake failure"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER),
      "sslv3 alert illegal parameter"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE),
      "sslv3 alert no certificate"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE),
      "sslv3 alert unexpected message"},
     {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE),
      "sslv3 alert unsupported certificate"},
     {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION),
      "ssl ctx has no default ssl version"},
     {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"},
     {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS),
      "ssl library has no ciphers"},
     {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED),
      "ssl session id callback failed"},
     {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"},
     {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG),
      "ssl session id context too long"},
     {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH),
      "ssl session id has bad length"},
     {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT),
      "ssl session id is different"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED),
      "tlsv1 alert access denied"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED),
      "tlsv1 alert decryption failed"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR),
      "tlsv1 alert decrypt error"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION),
      "tlsv1 alert export restriction"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK),
      "tlsv1 alert inappropriate fallback"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY),
      "tlsv1 alert insufficient security"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR),
      "tlsv1 alert internal error"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION),
      "tlsv1 alert no renegotiation"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION),
      "tlsv1 alert protocol version"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW),
      "tlsv1 alert record overflow"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"},
     {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED),
      "tlsv1 alert user cancelled"},
     {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE),
      "tlsv1 bad certificate hash value"},
     {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE),
      "tlsv1 bad certificate status response"},
     {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE),
      "tlsv1 certificate unobtainable"},
     {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"},
     {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION),
      "tlsv1 unsupported extension"},
     {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER),
      "tls client cert req with anon cipher"},
     {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT),
      "peer does not accept heartbeats"},
     {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING),
      "heartbeat request already pending"},
     {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL),
      "tls illegal exporter label"},
     {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
      "tls invalid ecpointformat list"},
     {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),
      "tls peer did not respond with certificate list"},
     {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),
      "tls rsa encrypted value length is wrong"},
     {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER),
      "tried to use unsupported cipher"},
     {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS),
      "unable to decode dh certs"},
     {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS),
      "unable to decode ecdh certs"},
     {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY),
      "unable to extract public key"},
     {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS),
      "unable to find dh parameters"},
     {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS),
      "unable to find ecdh parameters"},
     {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS),
      "unable to find public key parameters"},
     {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD),
      "unable to find ssl method"},
     {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES),
      "unable to load ssl2 md5 routines"},
     {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES),
      "unable to load ssl3 md5 routines"},
     {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES),
      "unable to load ssl3 sha1 routines"},
     {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"},
     {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"},
     {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"},
     {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"},
     {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"},
     {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"},
     {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"},
     {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"},
     {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE),
      "unknown key exchange type"},
     {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"},
     {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"},
     {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE),
      "unknown remote error type"},
     {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"},
     {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"},
     {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED),
      "unsafe legacy renegotiation disabled"},
     {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
     {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
      "unsupported compression algorithm"},
     {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"},
     {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE),
      "unsupported elliptic curve"},
     {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"},
     {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"},
     {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"},
     {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"},
     {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET), "write bio not set"},
     {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"},
     {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE), "wrong message type"},
     {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"},
     {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"},
     {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"},
     {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"},
     {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"},
     {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"},
     {ERR_REASON(SSL_R_X509_LIB), "x509 lib"},
     {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS),
      "x509 verification setup problems"},
     {0, NULL}
 };
 
 #endif
 
 void ERR_load_SSL_strings(void)
 {
 #ifndef OPENSSL_NO_ERR
 
     if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) {
         ERR_load_strings(0, SSL_str_functs);
         ERR_load_strings(0, SSL_str_reasons);
     }
 #endif
 }
Index: vendor-crypto/openssl/dist-1.0.1/ssl/ssl_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/ssl_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/ssl_lib.c	(revision 306191)
@@ -1,3325 +1,3325 @@
 /*
  * ! \file ssl/ssl_lib.c \brief Version independent SSL functions.
  */
 /* 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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  * ECC cipher suite support in OpenSSL originally developed by
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #ifdef REF_CHECK
 # include <assert.h>
 #endif
 #include <stdio.h>
 #include "ssl_locl.h"
 #include "kssl_lcl.h"
 #include <openssl/objects.h>
 #include <openssl/lhash.h>
 #include <openssl/x509v3.h>
 #include <openssl/rand.h>
 #include <openssl/ocsp.h>
 #ifndef OPENSSL_NO_DH
 # include <openssl/dh.h>
 #endif
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 
 const char *SSL_version_str = OPENSSL_VERSION_TEXT;
 
 SSL3_ENC_METHOD ssl3_undef_enc_method = {
     /*
      * evil casts, but these functions are only called if there's a library
      * bug
      */
     (int (*)(SSL *, int))ssl_undefined_function,
     (int (*)(SSL *, unsigned char *, int))ssl_undefined_function,
     ssl_undefined_function,
     (int (*)(SSL *, unsigned char *, unsigned char *, int))
         ssl_undefined_function,
     (int (*)(SSL *, int))ssl_undefined_function,
     (int (*)(SSL *, const char *, int, unsigned char *))
         ssl_undefined_function,
     0,                          /* finish_mac_length */
     (int (*)(SSL *, int, unsigned char *))ssl_undefined_function,
     NULL,                       /* client_finished_label */
     0,                          /* client_finished_label_len */
     NULL,                       /* server_finished_label */
     0,                          /* server_finished_label_len */
     (int (*)(int))ssl_undefined_function,
     (int (*)(SSL *, unsigned char *, size_t, const char *,
              size_t, const unsigned char *, size_t,
              int use_context))ssl_undefined_function,
 };
 
 int SSL_clear(SSL *s)
 {
 
     if (s->method == NULL) {
         SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED);
         return (0);
     }
 
     if (ssl_clear_bad_session(s)) {
         SSL_SESSION_free(s->session);
         s->session = NULL;
     }
 
     s->error = 0;
     s->hit = 0;
     s->shutdown = 0;
 
 #if 0
     /*
      * Disabled since version 1.10 of this file (early return not
      * needed because SSL_clear is not called when doing renegotiation)
      */
     /*
      * This is set if we are doing dynamic renegotiation so keep
      * the old cipher.  It is sort of a SSL_clear_lite :-)
      */
     if (s->renegotiate)
         return (1);
 #else
     if (s->renegotiate) {
         SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR);
         return 0;
     }
 #endif
 
     s->type = 0;
 
     s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT);
 
     s->version = s->method->version;
     s->client_version = s->version;
     s->rwstate = SSL_NOTHING;
     s->rstate = SSL_ST_READ_HEADER;
 #if 0
     s->read_ahead = s->ctx->read_ahead;
 #endif
 
     if (s->init_buf != NULL) {
         BUF_MEM_free(s->init_buf);
         s->init_buf = NULL;
     }
 
     ssl_clear_cipher_ctx(s);
     ssl_clear_hash_ctx(&s->read_hash);
     ssl_clear_hash_ctx(&s->write_hash);
 
     s->first_packet = 0;
 
 #if 1
     /*
      * Check to see if we were changed into a different method, if so, revert
      * back if we are not doing session-id reuse.
      */
     if (!s->in_handshake && (s->session == NULL)
         && (s->method != s->ctx->method)) {
         s->method->ssl_free(s);
         s->method = s->ctx->method;
         if (!s->method->ssl_new(s))
             return (0);
     } else
 #endif
         s->method->ssl_clear(s);
     return (1);
 }
 
 /** Used to change an SSL_CTXs default SSL method type */
 int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth)
 {
     STACK_OF(SSL_CIPHER) *sk;
 
     ctx->method = meth;
 
     sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list),
                                 &(ctx->cipher_list_by_id),
                                 meth->version ==
                                 SSL2_VERSION ? "SSLv2" :
                                 SSL_DEFAULT_CIPHER_LIST);
     if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
         SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION,
                SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
         return (0);
     }
     return (1);
 }
 
 SSL *SSL_new(SSL_CTX *ctx)
 {
     SSL *s;
 
     if (ctx == NULL) {
         SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX);
         return (NULL);
     }
     if (ctx->method == NULL) {
         SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
         return (NULL);
     }
 
     s = (SSL *)OPENSSL_malloc(sizeof(SSL));
     if (s == NULL)
         goto err;
     memset(s, 0, sizeof(SSL));
 
 #ifndef OPENSSL_NO_KRB5
     s->kssl_ctx = kssl_ctx_new();
 #endif                          /* OPENSSL_NO_KRB5 */
 
     s->options = ctx->options;
     s->mode = ctx->mode;
     s->max_cert_list = ctx->max_cert_list;
     s->references = 1;
 
     if (ctx->cert != NULL) {
         /*
          * Earlier library versions used to copy the pointer to the CERT, not
          * its contents; only when setting new parameters for the per-SSL
          * copy, ssl_cert_new would be called (and the direct reference to
          * the per-SSL_CTX settings would be lost, but those still were
          * indirectly accessed for various purposes, and for that reason they
          * used to be known as s->ctx->default_cert). Now we don't look at the
          * SSL_CTX's CERT after having duplicated it once.
          */
 
         s->cert = ssl_cert_dup(ctx->cert);
         if (s->cert == NULL)
             goto err;
     } else
         s->cert = NULL;         /* Cannot really happen (see SSL_CTX_new) */
 
     s->read_ahead = ctx->read_ahead;
     s->msg_callback = ctx->msg_callback;
     s->msg_callback_arg = ctx->msg_callback_arg;
     s->verify_mode = ctx->verify_mode;
 #if 0
     s->verify_depth = ctx->verify_depth;
 #endif
     s->sid_ctx_length = ctx->sid_ctx_length;
     OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx);
     memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx));
     s->verify_callback = ctx->default_verify_callback;
     s->generate_session_id = ctx->generate_session_id;
 
     s->param = X509_VERIFY_PARAM_new();
     if (!s->param)
         goto err;
     X509_VERIFY_PARAM_inherit(s->param, ctx->param);
 #if 0
     s->purpose = ctx->purpose;
     s->trust = ctx->trust;
 #endif
     s->quiet_shutdown = ctx->quiet_shutdown;
     s->max_send_fragment = ctx->max_send_fragment;
 
     CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
     s->ctx = ctx;
 #ifndef OPENSSL_NO_TLSEXT
     s->tlsext_debug_cb = 0;
     s->tlsext_debug_arg = NULL;
     s->tlsext_ticket_expected = 0;
     s->tlsext_status_type = -1;
     s->tlsext_status_expected = 0;
     s->tlsext_ocsp_ids = NULL;
     s->tlsext_ocsp_exts = NULL;
     s->tlsext_ocsp_resp = NULL;
     s->tlsext_ocsp_resplen = -1;
     CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
     s->initial_ctx = ctx;
 # ifndef OPENSSL_NO_NEXTPROTONEG
     s->next_proto_negotiated = NULL;
 # endif
 #endif
 
     s->verify_result = X509_V_OK;
 
     s->method = ctx->method;
 
     if (!s->method->ssl_new(s))
         goto err;
 
     s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1;
 
     SSL_clear(s);
 
     CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
 
 #ifndef OPENSSL_NO_PSK
     s->psk_client_callback = ctx->psk_client_callback;
     s->psk_server_callback = ctx->psk_server_callback;
 #endif
 
     return (s);
  err:
     if (s != NULL)
         SSL_free(s);
     SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE);
     return (NULL);
 }
 
 int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx,
                                    unsigned int sid_ctx_len)
 {
     if (sid_ctx_len > sizeof ctx->sid_ctx) {
         SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT,
                SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
         return 0;
     }
     ctx->sid_ctx_length = sid_ctx_len;
     memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len);
 
     return 1;
 }
 
 int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx,
                                unsigned int sid_ctx_len)
 {
     if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
         SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT,
                SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
         return 0;
     }
     ssl->sid_ctx_length = sid_ctx_len;
     memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len);
 
     return 1;
 }
 
 int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb)
 {
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
     ctx->generate_session_id = cb;
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
     return 1;
 }
 
 int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb)
 {
     CRYPTO_w_lock(CRYPTO_LOCK_SSL);
     ssl->generate_session_id = cb;
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
     return 1;
 }
 
 int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id,
                                 unsigned int id_len)
 {
     /*
      * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how
      * we can "construct" a session to give us the desired check - ie. to
      * find if there's a session in the hash table that would conflict with
      * any new session built out of this id/id_len and the ssl_version in use
      * by this SSL.
      */
     SSL_SESSION r, *p;
 
     if (id_len > sizeof r.session_id)
         return 0;
 
     r.ssl_version = ssl->version;
     r.session_id_length = id_len;
     memcpy(r.session_id, id, id_len);
     /*
      * NB: SSLv2 always uses a fixed 16-byte session ID, so even if a
      * callback is calling us to check the uniqueness of a shorter ID, it
      * must be compared as a padded-out ID because that is what it will be
      * converted to when the callback has finished choosing it.
      */
     if ((r.ssl_version == SSL2_VERSION) &&
         (id_len < SSL2_SSL_SESSION_ID_LENGTH)) {
         memset(r.session_id + id_len, 0, SSL2_SSL_SESSION_ID_LENGTH - id_len);
         r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
     }
 
     CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
     p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r);
     CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
     return (p != NULL);
 }
 
 int SSL_CTX_set_purpose(SSL_CTX *s, int purpose)
 {
     return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
 }
 
 int SSL_set_purpose(SSL *s, int purpose)
 {
     return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
 }
 
 int SSL_CTX_set_trust(SSL_CTX *s, int trust)
 {
     return X509_VERIFY_PARAM_set_trust(s->param, trust);
 }
 
 int SSL_set_trust(SSL *s, int trust)
 {
     return X509_VERIFY_PARAM_set_trust(s->param, trust);
 }
 
 int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm)
 {
     return X509_VERIFY_PARAM_set1(ctx->param, vpm);
 }
 
 int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm)
 {
     return X509_VERIFY_PARAM_set1(ssl->param, vpm);
 }
 
 void SSL_free(SSL *s)
 {
     int i;
 
     if (s == NULL)
         return;
 
     i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL);
 #ifdef REF_PRINT
     REF_PRINT("SSL", s);
 #endif
     if (i > 0)
         return;
 #ifdef REF_CHECK
     if (i < 0) {
         fprintf(stderr, "SSL_free, bad reference count\n");
         abort();                /* ok */
     }
 #endif
 
     if (s->param)
         X509_VERIFY_PARAM_free(s->param);
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data);
 
     if (s->bbio != NULL) {
         /* If the buffering BIO is in place, pop it off */
         if (s->bbio == s->wbio) {
             s->wbio = BIO_pop(s->wbio);
         }
         BIO_free(s->bbio);
         s->bbio = NULL;
     }
     if (s->rbio != NULL)
         BIO_free_all(s->rbio);
     if ((s->wbio != NULL) && (s->wbio != s->rbio))
         BIO_free_all(s->wbio);
 
     if (s->init_buf != NULL)
         BUF_MEM_free(s->init_buf);
 
     /* add extra stuff */
     if (s->cipher_list != NULL)
         sk_SSL_CIPHER_free(s->cipher_list);
     if (s->cipher_list_by_id != NULL)
         sk_SSL_CIPHER_free(s->cipher_list_by_id);
 
     /* Make the next call work :-) */
     if (s->session != NULL) {
         ssl_clear_bad_session(s);
         SSL_SESSION_free(s->session);
     }
 
     ssl_clear_cipher_ctx(s);
     ssl_clear_hash_ctx(&s->read_hash);
     ssl_clear_hash_ctx(&s->write_hash);
 
     if (s->cert != NULL)
         ssl_cert_free(s->cert);
     /* Free up if allocated */
 
 #ifndef OPENSSL_NO_TLSEXT
     if (s->tlsext_hostname)
         OPENSSL_free(s->tlsext_hostname);
     if (s->initial_ctx)
         SSL_CTX_free(s->initial_ctx);
 # ifndef OPENSSL_NO_EC
     if (s->tlsext_ecpointformatlist)
         OPENSSL_free(s->tlsext_ecpointformatlist);
     if (s->tlsext_ellipticcurvelist)
         OPENSSL_free(s->tlsext_ellipticcurvelist);
 # endif                         /* OPENSSL_NO_EC */
     if (s->tlsext_opaque_prf_input)
         OPENSSL_free(s->tlsext_opaque_prf_input);
     if (s->tlsext_ocsp_exts)
         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free);
     if (s->tlsext_ocsp_ids)
         sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free);
     if (s->tlsext_ocsp_resp)
         OPENSSL_free(s->tlsext_ocsp_resp);
 #endif
 
     if (s->client_CA != NULL)
         sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free);
 
     if (s->method != NULL)
         s->method->ssl_free(s);
 
     if (s->ctx)
         SSL_CTX_free(s->ctx);
 
 #ifndef OPENSSL_NO_KRB5
     if (s->kssl_ctx != NULL)
         kssl_ctx_free(s->kssl_ctx);
 #endif                          /* OPENSSL_NO_KRB5 */
 
 #if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
     if (s->next_proto_negotiated)
         OPENSSL_free(s->next_proto_negotiated);
 #endif
 
 #ifndef OPENSSL_NO_SRTP
     if (s->srtp_profiles)
         sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles);
 #endif
 
     OPENSSL_free(s);
 }
 
 void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio)
 {
     /*
      * If the output buffering BIO is still in place, remove it
      */
     if (s->bbio != NULL) {
         if (s->wbio == s->bbio) {
             s->wbio = s->wbio->next_bio;
             s->bbio->next_bio = NULL;
         }
     }
     if ((s->rbio != NULL) && (s->rbio != rbio))
         BIO_free_all(s->rbio);
     if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio))
         BIO_free_all(s->wbio);
     s->rbio = rbio;
     s->wbio = wbio;
 }
 
 BIO *SSL_get_rbio(const SSL *s)
 {
     return (s->rbio);
 }
 
 BIO *SSL_get_wbio(const SSL *s)
 {
     return (s->wbio);
 }
 
 int SSL_get_fd(const SSL *s)
 {
     return (SSL_get_rfd(s));
 }
 
 int SSL_get_rfd(const SSL *s)
 {
     int ret = -1;
     BIO *b, *r;
 
     b = SSL_get_rbio(s);
     r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
     if (r != NULL)
         BIO_get_fd(r, &ret);
     return (ret);
 }
 
 int SSL_get_wfd(const SSL *s)
 {
     int ret = -1;
     BIO *b, *r;
 
     b = SSL_get_wbio(s);
     r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR);
     if (r != NULL)
         BIO_get_fd(r, &ret);
     return (ret);
 }
 
 #ifndef OPENSSL_NO_SOCK
 int SSL_set_fd(SSL *s, int fd)
 {
     int ret = 0;
     BIO *bio = NULL;
 
     bio = BIO_new(BIO_s_socket());
 
     if (bio == NULL) {
         SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB);
         goto err;
     }
     BIO_set_fd(bio, fd, BIO_NOCLOSE);
     SSL_set_bio(s, bio, bio);
     ret = 1;
  err:
     return (ret);
 }
 
 int SSL_set_wfd(SSL *s, int fd)
 {
     int ret = 0;
     BIO *bio = NULL;
 
     if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET)
         || ((int)BIO_get_fd(s->rbio, NULL) != fd)) {
         bio = BIO_new(BIO_s_socket());
 
         if (bio == NULL) {
             SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB);
             goto err;
         }
         BIO_set_fd(bio, fd, BIO_NOCLOSE);
         SSL_set_bio(s, SSL_get_rbio(s), bio);
     } else
         SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s));
     ret = 1;
  err:
     return (ret);
 }
 
 int SSL_set_rfd(SSL *s, int fd)
 {
     int ret = 0;
     BIO *bio = NULL;
 
     if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET)
         || ((int)BIO_get_fd(s->wbio, NULL) != fd)) {
         bio = BIO_new(BIO_s_socket());
 
         if (bio == NULL) {
             SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB);
             goto err;
         }
         BIO_set_fd(bio, fd, BIO_NOCLOSE);
         SSL_set_bio(s, bio, SSL_get_wbio(s));
     } else
         SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s));
     ret = 1;
  err:
     return (ret);
 }
 #endif
 
 /* return length of latest Finished message we sent, copy to 'buf' */
 size_t SSL_get_finished(const SSL *s, void *buf, size_t count)
 {
     size_t ret = 0;
 
     if (s->s3 != NULL) {
         ret = s->s3->tmp.finish_md_len;
         if (count > ret)
             count = ret;
         memcpy(buf, s->s3->tmp.finish_md, count);
     }
     return ret;
 }
 
 /* return length of latest Finished message we expected, copy to 'buf' */
 size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count)
 {
     size_t ret = 0;
 
     if (s->s3 != NULL) {
         ret = s->s3->tmp.peer_finish_md_len;
         if (count > ret)
             count = ret;
         memcpy(buf, s->s3->tmp.peer_finish_md, count);
     }
     return ret;
 }
 
 int SSL_get_verify_mode(const SSL *s)
 {
     return (s->verify_mode);
 }
 
 int SSL_get_verify_depth(const SSL *s)
 {
     return X509_VERIFY_PARAM_get_depth(s->param);
 }
 
 int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) {
     return (s->verify_callback);
 }
 
 int SSL_CTX_get_verify_mode(const SSL_CTX *ctx)
 {
     return (ctx->verify_mode);
 }
 
 int SSL_CTX_get_verify_depth(const SSL_CTX *ctx)
 {
     return X509_VERIFY_PARAM_get_depth(ctx->param);
 }
 
 int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) {
     return (ctx->default_verify_callback);
 }
 
 void SSL_set_verify(SSL *s, int mode,
                     int (*callback) (int ok, X509_STORE_CTX *ctx))
 {
     s->verify_mode = mode;
     if (callback != NULL)
         s->verify_callback = callback;
 }
 
 void SSL_set_verify_depth(SSL *s, int depth)
 {
     X509_VERIFY_PARAM_set_depth(s->param, depth);
 }
 
 void SSL_set_read_ahead(SSL *s, int yes)
 {
     s->read_ahead = yes;
 }
 
 int SSL_get_read_ahead(const SSL *s)
 {
     return (s->read_ahead);
 }
 
 int SSL_pending(const SSL *s)
 {
     /*
      * SSL_pending cannot work properly if read-ahead is enabled
      * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is
      * impossible to fix since SSL_pending cannot report errors that may be
      * observed while scanning the new data. (Note that SSL_pending() is
      * often used as a boolean value, so we'd better not return -1.)
      */
     return (s->method->ssl_pending(s));
 }
 
 X509 *SSL_get_peer_certificate(const SSL *s)
 {
     X509 *r;
 
     if ((s == NULL) || (s->session == NULL))
         r = NULL;
     else
         r = s->session->peer;
 
     if (r == NULL)
         return (r);
 
     CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509);
 
     return (r);
 }
 
 STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
 {
     STACK_OF(X509) *r;
 
     if ((s == NULL) || (s->session == NULL)
         || (s->session->sess_cert == NULL))
         r = NULL;
     else
         r = s->session->sess_cert->cert_chain;
 
     /*
      * If we are a client, cert_chain includes the peer's own certificate; if
      * we are a server, it does not.
      */
 
     return (r);
 }
 
 /*
  * Now in theory, since the calling process own 't' it should be safe to
  * modify.  We need to be able to read f without being hassled
  */
 void SSL_copy_session_id(SSL *t, const SSL *f)
 {
     CERT *tmp;
 
     /* Do we need to to SSL locking? */
     SSL_set_session(t, SSL_get_session(f));
 
     /*
      * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa
      */
     if (t->method != f->method) {
         t->method->ssl_free(t); /* cleanup current */
         t->method = f->method;  /* change method */
         t->method->ssl_new(t);  /* setup new */
     }
 
     tmp = t->cert;
     if (f->cert != NULL) {
         CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT);
         t->cert = f->cert;
     } else
         t->cert = NULL;
     if (tmp != NULL)
         ssl_cert_free(tmp);
     SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length);
 }
 
 /* Fix this so it checks all the valid key/cert options */
 int SSL_CTX_check_private_key(const SSL_CTX *ctx)
 {
     if ((ctx == NULL) ||
         (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) {
         SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,
                SSL_R_NO_CERTIFICATE_ASSIGNED);
         return (0);
     }
     if (ctx->cert->key->privatekey == NULL) {
         SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY,
                SSL_R_NO_PRIVATE_KEY_ASSIGNED);
         return (0);
     }
     return (X509_check_private_key
             (ctx->cert->key->x509, ctx->cert->key->privatekey));
 }
 
 /* Fix this function so that it takes an optional type parameter */
 int SSL_check_private_key(const SSL *ssl)
 {
     if (ssl == NULL) {
         SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER);
         return (0);
     }
     if (ssl->cert == NULL) {
         SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
         return 0;
     }
     if (ssl->cert->key->x509 == NULL) {
         SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED);
         return (0);
     }
     if (ssl->cert->key->privatekey == NULL) {
         SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
         return (0);
     }
     return (X509_check_private_key(ssl->cert->key->x509,
                                    ssl->cert->key->privatekey));
 }
 
 int SSL_accept(SSL *s)
 {
     if (s->handshake_func == 0)
         /* Not properly initialized yet */
         SSL_set_accept_state(s);
 
     return (s->method->ssl_accept(s));
 }
 
 int SSL_connect(SSL *s)
 {
     if (s->handshake_func == 0)
         /* Not properly initialized yet */
         SSL_set_connect_state(s);
 
     return (s->method->ssl_connect(s));
 }
 
 long SSL_get_default_timeout(const SSL *s)
 {
     return (s->method->get_timeout());
 }
 
 int SSL_read(SSL *s, void *buf, int num)
 {
     if (s->handshake_func == 0) {
         SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED);
         return -1;
     }
 
     if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
         s->rwstate = SSL_NOTHING;
         return (0);
     }
     return (s->method->ssl_read(s, buf, num));
 }
 
 int SSL_peek(SSL *s, void *buf, int num)
 {
     if (s->handshake_func == 0) {
         SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED);
         return -1;
     }
 
     if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
         return (0);
     }
     return (s->method->ssl_peek(s, buf, num));
 }
 
 int SSL_write(SSL *s, const void *buf, int num)
 {
     if (s->handshake_func == 0) {
         SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED);
         return -1;
     }
 
     if (s->shutdown & SSL_SENT_SHUTDOWN) {
         s->rwstate = SSL_NOTHING;
         SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN);
         return (-1);
     }
     return (s->method->ssl_write(s, buf, num));
 }
 
 int SSL_shutdown(SSL *s)
 {
     /*
      * Note that this function behaves differently from what one might
      * expect.  Return values are 0 for no success (yet), 1 for success; but
      * calling it once is usually not enough, even if blocking I/O is used
      * (see ssl3_shutdown).
      */
 
     if (s->handshake_func == 0) {
         SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED);
         return -1;
     }
 
     if ((s != NULL) && !SSL_in_init(s))
         return (s->method->ssl_shutdown(s));
     else
         return (1);
 }
 
 int SSL_renegotiate(SSL *s)
 {
     if (s->renegotiate == 0)
         s->renegotiate = 1;
 
     s->new_session = 1;
 
     return (s->method->ssl_renegotiate(s));
 }
 
 int SSL_renegotiate_abbreviated(SSL *s)
 {
     if (s->renegotiate == 0)
         s->renegotiate = 1;
 
     s->new_session = 0;
 
     return (s->method->ssl_renegotiate(s));
 }
 
 int SSL_renegotiate_pending(SSL *s)
 {
     /*
      * becomes true when negotiation is requested; false again once a
      * handshake has finished
      */
     return (s->renegotiate != 0);
 }
 
 long SSL_ctrl(SSL *s, int cmd, long larg, void *parg)
 {
     long l;
 
     switch (cmd) {
     case SSL_CTRL_GET_READ_AHEAD:
         return (s->read_ahead);
     case SSL_CTRL_SET_READ_AHEAD:
         l = s->read_ahead;
         s->read_ahead = larg;
         return (l);
 
     case SSL_CTRL_SET_MSG_CALLBACK_ARG:
         s->msg_callback_arg = parg;
         return 1;
 
     case SSL_CTRL_OPTIONS:
         return (s->options |= larg);
     case SSL_CTRL_CLEAR_OPTIONS:
         return (s->options &= ~larg);
     case SSL_CTRL_MODE:
         return (s->mode |= larg);
     case SSL_CTRL_CLEAR_MODE:
         return (s->mode &= ~larg);
     case SSL_CTRL_GET_MAX_CERT_LIST:
         return (s->max_cert_list);
     case SSL_CTRL_SET_MAX_CERT_LIST:
         l = s->max_cert_list;
         s->max_cert_list = larg;
         return (l);
     case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
         if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
             return 0;
         s->max_send_fragment = larg;
         return 1;
     case SSL_CTRL_GET_RI_SUPPORT:
         if (s->s3)
             return s->s3->send_connection_binding;
         else
             return 0;
     default:
         return (s->method->ssl_ctrl(s, cmd, larg, parg));
     }
 }
 
 long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void))
 {
     switch (cmd) {
     case SSL_CTRL_SET_MSG_CALLBACK:
         s->msg_callback = (void (*)
                            (int write_p, int version, int content_type,
                             const void *buf, size_t len, SSL *ssl,
                             void *arg))(fp);
         return 1;
 
     default:
         return (s->method->ssl_callback_ctrl(s, cmd, fp));
     }
 }
 
 LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx)
 {
     return ctx->sessions;
 }
 
 long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
 {
     long l;
 
     switch (cmd) {
     case SSL_CTRL_GET_READ_AHEAD:
         return (ctx->read_ahead);
     case SSL_CTRL_SET_READ_AHEAD:
         l = ctx->read_ahead;
         ctx->read_ahead = larg;
         return (l);
 
     case SSL_CTRL_SET_MSG_CALLBACK_ARG:
         ctx->msg_callback_arg = parg;
         return 1;
 
     case SSL_CTRL_GET_MAX_CERT_LIST:
         return (ctx->max_cert_list);
     case SSL_CTRL_SET_MAX_CERT_LIST:
         l = ctx->max_cert_list;
         ctx->max_cert_list = larg;
         return (l);
 
     case SSL_CTRL_SET_SESS_CACHE_SIZE:
         l = ctx->session_cache_size;
         ctx->session_cache_size = larg;
         return (l);
     case SSL_CTRL_GET_SESS_CACHE_SIZE:
         return (ctx->session_cache_size);
     case SSL_CTRL_SET_SESS_CACHE_MODE:
         l = ctx->session_cache_mode;
         ctx->session_cache_mode = larg;
         return (l);
     case SSL_CTRL_GET_SESS_CACHE_MODE:
         return (ctx->session_cache_mode);
 
     case SSL_CTRL_SESS_NUMBER:
         return (lh_SSL_SESSION_num_items(ctx->sessions));
     case SSL_CTRL_SESS_CONNECT:
         return (ctx->stats.sess_connect);
     case SSL_CTRL_SESS_CONNECT_GOOD:
         return (ctx->stats.sess_connect_good);
     case SSL_CTRL_SESS_CONNECT_RENEGOTIATE:
         return (ctx->stats.sess_connect_renegotiate);
     case SSL_CTRL_SESS_ACCEPT:
         return (ctx->stats.sess_accept);
     case SSL_CTRL_SESS_ACCEPT_GOOD:
         return (ctx->stats.sess_accept_good);
     case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE:
         return (ctx->stats.sess_accept_renegotiate);
     case SSL_CTRL_SESS_HIT:
         return (ctx->stats.sess_hit);
     case SSL_CTRL_SESS_CB_HIT:
         return (ctx->stats.sess_cb_hit);
     case SSL_CTRL_SESS_MISSES:
         return (ctx->stats.sess_miss);
     case SSL_CTRL_SESS_TIMEOUTS:
         return (ctx->stats.sess_timeout);
     case SSL_CTRL_SESS_CACHE_FULL:
         return (ctx->stats.sess_cache_full);
     case SSL_CTRL_OPTIONS:
         return (ctx->options |= larg);
     case SSL_CTRL_CLEAR_OPTIONS:
         return (ctx->options &= ~larg);
     case SSL_CTRL_MODE:
         return (ctx->mode |= larg);
     case SSL_CTRL_CLEAR_MODE:
         return (ctx->mode &= ~larg);
     case SSL_CTRL_SET_MAX_SEND_FRAGMENT:
         if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH)
             return 0;
         ctx->max_send_fragment = larg;
         return 1;
     default:
         return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg));
     }
 }
 
 long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void))
 {
     switch (cmd) {
     case SSL_CTRL_SET_MSG_CALLBACK:
         ctx->msg_callback = (void (*)
                              (int write_p, int version, int content_type,
                               const void *buf, size_t len, SSL *ssl,
                               void *arg))(fp);
         return 1;
 
     default:
         return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp));
     }
 }
 
 int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b)
 {
     long l;
 
     l = a->id - b->id;
     if (l == 0L)
         return (0);
     else
         return ((l > 0) ? 1 : -1);
 }
 
 int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
                           const SSL_CIPHER *const *bp)
 {
     long l;
 
     l = (*ap)->id - (*bp)->id;
     if (l == 0L)
         return (0);
     else
         return ((l > 0) ? 1 : -1);
 }
 
 /** return a STACK of the ciphers available for the SSL and in order of
  * preference */
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s)
 {
     if (s != NULL) {
         if (s->cipher_list != NULL) {
             return (s->cipher_list);
         } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) {
             return (s->ctx->cipher_list);
         }
     }
     return (NULL);
 }
 
 /** return a STACK of the ciphers available for the SSL and in order of
  * algorithm id */
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s)
 {
     if (s != NULL) {
         if (s->cipher_list_by_id != NULL) {
             return (s->cipher_list_by_id);
         } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) {
             return (s->ctx->cipher_list_by_id);
         }
     }
     return (NULL);
 }
 
 /** The old interface to get the same thing as SSL_get_ciphers() */
 const char *SSL_get_cipher_list(const SSL *s, int n)
 {
     SSL_CIPHER *c;
     STACK_OF(SSL_CIPHER) *sk;
 
     if (s == NULL)
         return (NULL);
     sk = SSL_get_ciphers(s);
     if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n))
         return (NULL);
     c = sk_SSL_CIPHER_value(sk, n);
     if (c == NULL)
         return (NULL);
     return (c->name);
 }
 
 /** specify the ciphers to be used by default by the SSL_CTX */
 int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str)
 {
     STACK_OF(SSL_CIPHER) *sk;
 
     sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list,
                                 &ctx->cipher_list_by_id, str);
     /*
      * ssl_create_cipher_list may return an empty stack if it was unable to
      * find a cipher matching the given rule string (for example if the rule
      * string specifies a cipher which has been disabled). This is not an
      * error as far as ssl_create_cipher_list is concerned, and hence
      * ctx->cipher_list and ctx->cipher_list_by_id has been updated.
      */
     if (sk == NULL)
         return 0;
     else if (sk_SSL_CIPHER_num(sk) == 0) {
         SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
         return 0;
     }
     return 1;
 }
 
 /** specify the ciphers to be used by the SSL */
 int SSL_set_cipher_list(SSL *s, const char *str)
 {
     STACK_OF(SSL_CIPHER) *sk;
 
     sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list,
                                 &s->cipher_list_by_id, str);
     /* see comment in SSL_CTX_set_cipher_list */
     if (sk == NULL)
         return 0;
     else if (sk_SSL_CIPHER_num(sk) == 0) {
         SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH);
         return 0;
     }
     return 1;
 }
 
 /* works well for SSLv2, not so good for SSLv3 */
 char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len)
 {
     char *p;
     STACK_OF(SSL_CIPHER) *sk;
     SSL_CIPHER *c;
     int i;
 
     if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2))
         return (NULL);
 
     p = buf;
     sk = s->session->ciphers;
 
     if (sk_SSL_CIPHER_num(sk) == 0)
         return NULL;
 
     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
         int n;
 
         c = sk_SSL_CIPHER_value(sk, i);
         n = strlen(c->name);
         if (n + 1 > len) {
             if (p != buf)
                 --p;
             *p = '\0';
             return buf;
         }
         strcpy(p, c->name);
         p += n;
         *(p++) = ':';
         len -= n + 1;
     }
     p[-1] = '\0';
     return (buf);
 }
 
 int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
                              unsigned char *p,
                              int (*put_cb) (const SSL_CIPHER *,
                                             unsigned char *))
 {
     int i, j = 0;
     SSL_CIPHER *c;
     unsigned char *q;
 #ifndef OPENSSL_NO_KRB5
     int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx);
 #endif                          /* OPENSSL_NO_KRB5 */
 
     if (sk == NULL)
         return (0);
     q = p;
     if (put_cb == NULL)
         put_cb = s->method->put_cipher_by_char;
 
     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
         c = sk_SSL_CIPHER_value(sk, i);
         /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */
         if ((c->algorithm_ssl & SSL_TLSV1_2) &&
             (TLS1_get_client_version(s) < TLS1_2_VERSION))
             continue;
 #ifndef OPENSSL_NO_KRB5
         if (((c->algorithm_mkey & SSL_kKRB5)
              || (c->algorithm_auth & SSL_aKRB5)) && nokrb5)
             continue;
 #endif                          /* OPENSSL_NO_KRB5 */
 #ifndef OPENSSL_NO_PSK
         /* with PSK there must be client callback set */
         if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK))
             && s->psk_client_callback == NULL)
             continue;
 #endif                          /* OPENSSL_NO_PSK */
 #ifndef OPENSSL_NO_SRP
         if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP))
             && !(s->srp_ctx.srp_Mask & SSL_kSRP))
             continue;
 #endif                          /* OPENSSL_NO_SRP */
         j = put_cb(c, p);
         p += j;
     }
     /*
      * If p == q, no ciphers; caller indicates an error. Otherwise, add
      * applicable SCSVs.
      */
     if (p != q) {
         if (!s->renegotiate) {
             static SSL_CIPHER scsv = {
                 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
             };
             j = put_cb(&scsv, p);
             p += j;
 #ifdef OPENSSL_RI_DEBUG
             fprintf(stderr,
                     "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n");
 #endif
         }
 
         if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
             static SSL_CIPHER scsv = {
                 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0
             };
             j = put_cb(&scsv, p);
             p += j;
         }
     }
 
     return (p - q);
 }
 
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
                                                STACK_OF(SSL_CIPHER) **skp)
 {
     const SSL_CIPHER *c;
     STACK_OF(SSL_CIPHER) *sk;
     int i, n;
 
     if (s->s3)
         s->s3->send_connection_binding = 0;
 
     n = ssl_put_cipher_by_char(s, NULL, NULL);
     if (n == 0 || (num % n) != 0) {
         SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
                SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
         return (NULL);
     }
     if ((skp == NULL) || (*skp == NULL)) {
         sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
         if(sk == NULL) {
             SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
             return NULL;
         }
     } else {
         sk = *skp;
         sk_SSL_CIPHER_zero(sk);
     }
 
     for (i = 0; i < num; i += n) {
         /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
         if (s->s3 && (n != 3 || !p[0]) &&
             (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) &&
             (p[n - 1] == (SSL3_CK_SCSV & 0xff))) {
             /* SCSV fatal if renegotiating */
             if (s->renegotiate) {
                 SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
                        SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
                 ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
                 goto err;
             }
             s->s3->send_connection_binding = 1;
             p += n;
 #ifdef OPENSSL_RI_DEBUG
             fprintf(stderr, "SCSV received by server\n");
 #endif
             continue;
         }
 
         /* Check for TLS_FALLBACK_SCSV */
         if ((n != 3 || !p[0]) &&
             (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) &&
             (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) {
             /*
              * The SCSV indicates that the client previously tried a higher
              * version. Fail if the current version is an unexpected
              * downgrade.
              */
             if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) {
                 SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST,
                        SSL_R_INAPPROPRIATE_FALLBACK);
                 if (s->s3)
                     ssl3_send_alert(s, SSL3_AL_FATAL,
                                     SSL_AD_INAPPROPRIATE_FALLBACK);
                 goto err;
             }
             p += n;
             continue;
         }
 
         c = ssl_get_cipher_by_char(s, p);
         p += n;
         if (c != NULL) {
             if (!sk_SSL_CIPHER_push(sk, c)) {
                 SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
                 goto err;
             }
         }
     }
 
     if (skp != NULL)
         *skp = sk;
     return (sk);
  err:
     if ((skp == NULL) || (*skp == NULL))
         sk_SSL_CIPHER_free(sk);
     return (NULL);
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 /** return a servername extension value if provided in Client Hello, or NULL.
  * So far, only host_name types are defined (RFC 3546).
  */
 
 const char *SSL_get_servername(const SSL *s, const int type)
 {
     if (type != TLSEXT_NAMETYPE_host_name)
         return NULL;
 
     return s->session && !s->tlsext_hostname ?
         s->session->tlsext_hostname : s->tlsext_hostname;
 }
 
 int SSL_get_servername_type(const SSL *s)
 {
     if (s->session
         && (!s->tlsext_hostname ? s->session->
             tlsext_hostname : s->tlsext_hostname))
         return TLSEXT_NAMETYPE_host_name;
     return -1;
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * SSL_select_next_proto implements the standard protocol selection. It is
  * expected that this function is called from the callback set by
  * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a
  * vector of 8-bit, length prefixed byte strings. The length byte itself is
  * not included in the length. A byte string of length 0 is invalid. No byte
  * string may be truncated. The current, but experimental algorithm for
  * selecting the protocol is: 1) If the server doesn't support NPN then this
  * is indicated to the callback. In this case, the client application has to
  * abort the connection or have a default application level protocol. 2) If
  * the server supports NPN, but advertises an empty list then the client
  * selects the first protcol in its list, but indicates via the API that this
  * fallback case was enacted. 3) Otherwise, the client finds the first
  * protocol in the server's list that it supports and selects this protocol.
  * This is because it's assumed that the server has better information about
  * which protocol a client should use. 4) If the client doesn't support any
  * of the server's advertised protocols, then this is treated the same as
  * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was
  * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
  */
 int SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
                           const unsigned char *server,
                           unsigned int server_len,
                           const unsigned char *client,
                           unsigned int client_len)
 {
     unsigned int i, j;
     const unsigned char *result;
     int status = OPENSSL_NPN_UNSUPPORTED;
 
     /*
      * For each protocol in server preference order, see if we support it.
      */
     for (i = 0; i < server_len;) {
         for (j = 0; j < client_len;) {
             if (server[i] == client[j] &&
                 memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) {
                 /* We found a match */
                 result = &server[i];
                 status = OPENSSL_NPN_NEGOTIATED;
                 goto found;
             }
             j += client[j];
             j++;
         }
         i += server[i];
         i++;
     }
 
     /* There's no overlap between our protocols and the server's list. */
     result = client;
     status = OPENSSL_NPN_NO_OVERLAP;
 
  found:
     *out = (unsigned char *)result + 1;
     *outlen = result[0];
     return status;
 }
 
 /*
  * SSL_get0_next_proto_negotiated sets *data and *len to point to the
  * client's requested protocol for this connection and returns 0. If the
  * client didn't request any protocol, then *data is set to NULL. Note that
  * the client can request any protocol it chooses. The value returned from
  * this function need not be a member of the list of supported protocols
  * provided by the callback.
  */
 void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
                                     unsigned *len)
 {
     *data = s->next_proto_negotiated;
     if (!*data) {
         *len = 0;
     } else {
         *len = s->next_proto_negotiated_len;
     }
 }
 
 /*
  * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when
  * a TLS server needs a list of supported protocols for Next Protocol
  * Negotiation. The returned list must be in wire format.  The list is
  * returned by setting |out| to point to it and |outlen| to its length. This
  * memory will not be modified, but one should assume that the SSL* keeps a
  * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it
  * wishes to advertise. Otherwise, no such extension will be included in the
  * ServerHello.
  */
 void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx,
                                            int (*cb) (SSL *ssl,
                                                       const unsigned char
                                                       **out,
                                                       unsigned int *outlen,
                                                       void *arg), void *arg)
 {
     ctx->next_protos_advertised_cb = cb;
     ctx->next_protos_advertised_cb_arg = arg;
 }
 
 /*
  * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
  * client needs to select a protocol from the server's provided list. |out|
  * must be set to point to the selected protocol (which may be within |in|).
  * The length of the protocol name must be written into |outlen|. The
  * server's advertised protocols are provided in |in| and |inlen|. The
  * callback can assume that |in| is syntactically valid. The client must
  * select a protocol. It is fatal to the connection if this callback returns
  * a value other than SSL_TLSEXT_ERR_OK.
  */
 void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx,
                                       int (*cb) (SSL *s, unsigned char **out,
                                                  unsigned char *outlen,
                                                  const unsigned char *in,
                                                  unsigned int inlen,
                                                  void *arg), void *arg)
 {
     ctx->next_proto_select_cb = cb;
     ctx->next_proto_select_cb_arg = arg;
 }
 # endif
 #endif
 
 int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                const char *label, size_t llen,
                                const unsigned char *p, size_t plen,
                                int use_context)
 {
-    if (s->version < TLS1_VERSION)
+    if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)
         return -1;
 
     return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
                                                        llen, p, plen,
                                                        use_context);
 }
 
 static unsigned long ssl_session_hash(const SSL_SESSION *a)
 {
     unsigned long l;
 
     l = (unsigned long)
         ((unsigned int)a->session_id[0]) |
         ((unsigned int)a->session_id[1] << 8L) |
         ((unsigned long)a->session_id[2] << 16L) |
         ((unsigned long)a->session_id[3] << 24L);
     return (l);
 }
 
 /*
  * NB: If this function (or indeed the hash function which uses a sort of
  * coarser function than this one) is changed, ensure
  * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on
  * being able to construct an SSL_SESSION that will collide with any existing
  * session with a matching session ID.
  */
 static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b)
 {
     if (a->ssl_version != b->ssl_version)
         return (1);
     if (a->session_id_length != b->session_id_length)
         return (1);
     return (memcmp(a->session_id, b->session_id, a->session_id_length));
 }
 
 /*
  * These wrapper functions should remain rather than redeclaring
  * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each
  * variable. The reason is that the functions aren't static, they're exposed
  * via ssl.h.
  */
 static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION)
 static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION)
 
 SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
 {
     SSL_CTX *ret = NULL;
 
     if (meth == NULL) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED);
         return (NULL);
     }
 #ifdef OPENSSL_FIPS
     if (FIPS_mode() && (meth->version < TLS1_VERSION)) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE);
         return NULL;
     }
 #endif
 
     if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
         goto err;
     }
     ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
     if (ret == NULL)
         goto err;
 
     memset(ret, 0, sizeof(SSL_CTX));
 
     ret->method = meth;
 
     ret->cert_store = NULL;
     ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
     ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
     ret->session_cache_head = NULL;
     ret->session_cache_tail = NULL;
 
     /* We take the system default */
     ret->session_timeout = meth->get_timeout();
 
     ret->new_session_cb = 0;
     ret->remove_session_cb = 0;
     ret->get_session_cb = 0;
     ret->generate_session_id = 0;
 
     memset((char *)&ret->stats, 0, sizeof(ret->stats));
 
     ret->references = 1;
     ret->quiet_shutdown = 0;
 
 /*  ret->cipher=NULL;*/
 /*-
     ret->s2->challenge=NULL;
     ret->master_key=NULL;
     ret->key_arg=NULL;
     ret->s2->conn_id=NULL; */
 
     ret->info_callback = NULL;
 
     ret->app_verify_callback = 0;
     ret->app_verify_arg = NULL;
 
     ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
     ret->read_ahead = 0;
     ret->msg_callback = 0;
     ret->msg_callback_arg = NULL;
     ret->verify_mode = SSL_VERIFY_NONE;
 #if 0
     ret->verify_depth = -1;     /* Don't impose a limit (but x509_lu.c does) */
 #endif
     ret->sid_ctx_length = 0;
     ret->default_verify_callback = NULL;
     if ((ret->cert = ssl_cert_new()) == NULL)
         goto err;
 
     ret->default_passwd_callback = 0;
     ret->default_passwd_callback_userdata = NULL;
     ret->client_cert_cb = 0;
     ret->app_gen_cookie_cb = 0;
     ret->app_verify_cookie_cb = 0;
 
     ret->sessions = lh_SSL_SESSION_new();
     if (ret->sessions == NULL)
         goto err;
     ret->cert_store = X509_STORE_new();
     if (ret->cert_store == NULL)
         goto err;
 
     ssl_create_cipher_list(ret->method,
                            &ret->cipher_list, &ret->cipher_list_by_id,
                            meth->version ==
                            SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST);
     if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS);
         goto err2;
     }
 
     ret->param = X509_VERIFY_PARAM_new();
     if (!ret->param)
         goto err;
 
     if ((ret->rsa_md5 = EVP_get_digestbyname("ssl2-md5")) == NULL) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES);
         goto err2;
     }
     if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES);
         goto err2;
     }
     if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) {
         SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES);
         goto err2;
     }
 
     if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL)
         goto err;
 
     CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data);
 
     ret->extra_certs = NULL;
     /* No compression for DTLS */
     if (meth->version != DTLS1_VERSION)
         ret->comp_methods = SSL_COMP_get_compression_methods();
 
     ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
 
 #ifndef OPENSSL_NO_TLSEXT
     ret->tlsext_servername_callback = 0;
     ret->tlsext_servername_arg = NULL;
     /* Setup RFC4507 ticket keys */
-    if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0)
+    if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0)
         || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0)
         || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
         ret->options |= SSL_OP_NO_TICKET;
 
     ret->tlsext_status_cb = 0;
     ret->tlsext_status_arg = NULL;
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
     ret->next_protos_advertised_cb = 0;
     ret->next_proto_select_cb = 0;
 # endif
 #endif
 #ifndef OPENSSL_NO_PSK
     ret->psk_identity_hint = NULL;
     ret->psk_client_callback = NULL;
     ret->psk_server_callback = NULL;
 #endif
 #ifndef OPENSSL_NO_SRP
     SSL_CTX_SRP_CTX_init(ret);
 #endif
 #ifndef OPENSSL_NO_BUF_FREELISTS
     ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT;
     ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
     if (!ret->rbuf_freelist)
         goto err;
     ret->rbuf_freelist->chunklen = 0;
     ret->rbuf_freelist->len = 0;
     ret->rbuf_freelist->head = NULL;
     ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
     if (!ret->wbuf_freelist) {
         OPENSSL_free(ret->rbuf_freelist);
         goto err;
     }
     ret->wbuf_freelist->chunklen = 0;
     ret->wbuf_freelist->len = 0;
     ret->wbuf_freelist->head = NULL;
 #endif
 #ifndef OPENSSL_NO_ENGINE
     ret->client_cert_engine = NULL;
 # ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO
 #  define eng_strx(x)     #x
 #  define eng_str(x)      eng_strx(x)
     /* Use specific client engine automatically... ignore errors */
     {
         ENGINE *eng;
         eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
         if (!eng) {
             ERR_clear_error();
             ENGINE_load_builtin_engines();
             eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO));
         }
         if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng))
             ERR_clear_error();
     }
 # endif
 #endif
     /*
      * Default is to connect to non-RI servers. When RI is more widely
      * deployed might change this.
      */
     ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
 
     /*
      * Disable SSLv2 by default, callers that want to enable SSLv2 will have to
      * explicitly clear this option via either of SSL_CTX_clear_options() or
      * SSL_clear_options().
      */
     ret->options |= SSL_OP_NO_SSLv2;
 
     return (ret);
  err:
     SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE);
  err2:
     if (ret != NULL)
         SSL_CTX_free(ret);
     return (NULL);
 }
 
 #if 0
 static void SSL_COMP_free(SSL_COMP *comp)
 {
     OPENSSL_free(comp);
 }
 #endif
 
 #ifndef OPENSSL_NO_BUF_FREELISTS
 static void ssl_buf_freelist_free(SSL3_BUF_FREELIST *list)
 {
     SSL3_BUF_FREELIST_ENTRY *ent, *next;
     for (ent = list->head; ent; ent = next) {
         next = ent->next;
         OPENSSL_free(ent);
     }
     OPENSSL_free(list);
 }
 #endif
 
 void SSL_CTX_free(SSL_CTX *a)
 {
     int i;
 
     if (a == NULL)
         return;
 
     i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX);
 #ifdef REF_PRINT
     REF_PRINT("SSL_CTX", a);
 #endif
     if (i > 0)
         return;
 #ifdef REF_CHECK
     if (i < 0) {
         fprintf(stderr, "SSL_CTX_free, bad reference count\n");
         abort();                /* ok */
     }
 #endif
 
     if (a->param)
         X509_VERIFY_PARAM_free(a->param);
 
     /*
      * Free internal session cache. However: the remove_cb() may reference
      * the ex_data of SSL_CTX, thus the ex_data store can only be removed
      * after the sessions were flushed.
      * As the ex_data handling routines might also touch the session cache,
      * the most secure solution seems to be: empty (flush) the cache, then
      * free ex_data, then finally free the cache.
      * (See ticket [openssl.org #212].)
      */
     if (a->sessions != NULL)
         SSL_CTX_flush_sessions(a, 0);
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data);
 
     if (a->sessions != NULL)
         lh_SSL_SESSION_free(a->sessions);
 
     if (a->cert_store != NULL)
         X509_STORE_free(a->cert_store);
     if (a->cipher_list != NULL)
         sk_SSL_CIPHER_free(a->cipher_list);
     if (a->cipher_list_by_id != NULL)
         sk_SSL_CIPHER_free(a->cipher_list_by_id);
     if (a->cert != NULL)
         ssl_cert_free(a->cert);
     if (a->client_CA != NULL)
         sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free);
     if (a->extra_certs != NULL)
         sk_X509_pop_free(a->extra_certs, X509_free);
 #if 0                           /* This should never be done, since it
                                  * removes a global database */
     if (a->comp_methods != NULL)
         sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free);
 #else
     a->comp_methods = NULL;
 #endif
 
 #ifndef OPENSSL_NO_SRTP
     if (a->srtp_profiles)
         sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles);
 #endif
 
 #ifndef OPENSSL_NO_PSK
     if (a->psk_identity_hint)
         OPENSSL_free(a->psk_identity_hint);
 #endif
 #ifndef OPENSSL_NO_SRP
     SSL_CTX_SRP_CTX_free(a);
 #endif
 #ifndef OPENSSL_NO_ENGINE
     if (a->client_cert_engine)
         ENGINE_finish(a->client_cert_engine);
 #endif
 
 #ifndef OPENSSL_NO_BUF_FREELISTS
     if (a->wbuf_freelist)
         ssl_buf_freelist_free(a->wbuf_freelist);
     if (a->rbuf_freelist)
         ssl_buf_freelist_free(a->rbuf_freelist);
 #endif
 
     OPENSSL_free(a);
 }
 
 void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb)
 {
     ctx->default_passwd_callback = cb;
 }
 
 void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u)
 {
     ctx->default_passwd_callback_userdata = u;
 }
 
 void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
                                       int (*cb) (X509_STORE_CTX *, void *),
                                       void *arg)
 {
     ctx->app_verify_callback = cb;
     ctx->app_verify_arg = arg;
 }
 
 void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
                         int (*cb) (int, X509_STORE_CTX *))
 {
     ctx->verify_mode = mode;
     ctx->default_verify_callback = cb;
 }
 
 void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth)
 {
     X509_VERIFY_PARAM_set_depth(ctx->param, depth);
 }
 
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher)
 {
     CERT_PKEY *cpk;
     int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign;
     int rsa_enc_export, dh_rsa_export, dh_dsa_export;
     int rsa_tmp_export, dh_tmp_export, kl;
     unsigned long mask_k, mask_a, emask_k, emask_a;
 #ifndef OPENSSL_NO_ECDSA
     int have_ecc_cert, ecdsa_ok, ecc_pkey_size;
 #endif
 #ifndef OPENSSL_NO_ECDH
     int have_ecdh_tmp, ecdh_ok;
 #endif
 #ifndef OPENSSL_NO_EC
     X509 *x = NULL;
     EVP_PKEY *ecc_pkey = NULL;
     int signature_nid = 0, pk_nid = 0, md_nid = 0;
 #endif
     if (c == NULL)
         return;
 
     kl = SSL_C_EXPORT_PKEYLENGTH(cipher);
 
 #ifndef OPENSSL_NO_RSA
     rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL);
     rsa_tmp_export = (c->rsa_tmp_cb != NULL ||
                       (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl));
 #else
     rsa_tmp = rsa_tmp_export = 0;
 #endif
 #ifndef OPENSSL_NO_DH
     dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
     dh_tmp_export = (c->dh_tmp_cb != NULL ||
                      (dh_tmp && DH_size(c->dh_tmp) * 8 <= kl));
 #else
     dh_tmp = dh_tmp_export = 0;
 #endif
 
 #ifndef OPENSSL_NO_ECDH
     have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL);
 #endif
     cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]);
     rsa_enc = (cpk->x509 != NULL && cpk->privatekey != NULL);
     rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]);
     rsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL);
     cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]);
     dsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL);
     cpk = &(c->pkeys[SSL_PKEY_DH_RSA]);
     dh_rsa = (cpk->x509 != NULL && cpk->privatekey != NULL);
     dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_DH_DSA]);
 /* FIX THIS EAY EAY EAY */
     dh_dsa = (cpk->x509 != NULL && cpk->privatekey != NULL);
     dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl);
     cpk = &(c->pkeys[SSL_PKEY_ECC]);
 #ifndef OPENSSL_NO_EC
     have_ecc_cert = (cpk->x509 != NULL && cpk->privatekey != NULL);
 #endif
     mask_k = 0;
     mask_a = 0;
     emask_k = 0;
     emask_a = 0;
 
 #ifdef CIPHER_DEBUG
     fprintf(stderr,
             "rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n",
             rsa_tmp, rsa_tmp_export, dh_tmp, have_ecdh_tmp, rsa_enc,
             rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa);
 #endif
 
     cpk = &(c->pkeys[SSL_PKEY_GOST01]);
     if (cpk->x509 != NULL && cpk->privatekey != NULL) {
         mask_k |= SSL_kGOST;
         mask_a |= SSL_aGOST01;
     }
     cpk = &(c->pkeys[SSL_PKEY_GOST94]);
     if (cpk->x509 != NULL && cpk->privatekey != NULL) {
         mask_k |= SSL_kGOST;
         mask_a |= SSL_aGOST94;
     }
 
     if (rsa_enc || (rsa_tmp && rsa_sign))
         mask_k |= SSL_kRSA;
     if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc)))
         emask_k |= SSL_kRSA;
 
 #if 0
     /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */
     if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign))
         mask_k |= SSL_kEDH;
     if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) &&
         (rsa_enc || rsa_sign || dsa_sign))
         emask_k |= SSL_kEDH;
 #endif
 
     if (dh_tmp_export)
         emask_k |= SSL_kEDH;
 
     if (dh_tmp)
         mask_k |= SSL_kEDH;
 
     if (dh_rsa)
         mask_k |= SSL_kDHr;
     if (dh_rsa_export)
         emask_k |= SSL_kDHr;
 
     if (dh_dsa)
         mask_k |= SSL_kDHd;
     if (dh_dsa_export)
         emask_k |= SSL_kDHd;
 
     if (rsa_enc || rsa_sign) {
         mask_a |= SSL_aRSA;
         emask_a |= SSL_aRSA;
     }
 
     if (dsa_sign) {
         mask_a |= SSL_aDSS;
         emask_a |= SSL_aDSS;
     }
 
     mask_a |= SSL_aNULL;
     emask_a |= SSL_aNULL;
 
 #ifndef OPENSSL_NO_KRB5
     mask_k |= SSL_kKRB5;
     mask_a |= SSL_aKRB5;
     emask_k |= SSL_kKRB5;
     emask_a |= SSL_aKRB5;
 #endif
 
     /*
      * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites
      * depending on the key usage extension.
      */
 #ifndef OPENSSL_NO_EC
     if (have_ecc_cert) {
         /* This call populates extension flags (ex_flags) */
         x = (c->pkeys[SSL_PKEY_ECC]).x509;
         X509_check_purpose(x, -1, 0);
         ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
             (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1;
         ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ?
             (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1;
         ecc_pkey = X509_get_pubkey(x);
         ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0;
         EVP_PKEY_free(ecc_pkey);
         if ((x->sig_alg) && (x->sig_alg->algorithm)) {
             signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
             OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
         }
 #ifndef OPENSSL_NO_ECDH
         if (ecdh_ok) {
 
             if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) {
                 mask_k |= SSL_kECDHr;
                 mask_a |= SSL_aECDH;
                 if (ecc_pkey_size <= 163) {
                     emask_k |= SSL_kECDHr;
                     emask_a |= SSL_aECDH;
                 }
             }
 
             if (pk_nid == NID_X9_62_id_ecPublicKey) {
                 mask_k |= SSL_kECDHe;
                 mask_a |= SSL_aECDH;
                 if (ecc_pkey_size <= 163) {
                     emask_k |= SSL_kECDHe;
                     emask_a |= SSL_aECDH;
                 }
             }
         }
 #endif
 #ifndef OPENSSL_NO_ECDSA
         if (ecdsa_ok) {
             mask_a |= SSL_aECDSA;
             emask_a |= SSL_aECDSA;
         }
 #endif
     }
 #endif
 #ifndef OPENSSL_NO_ECDH
     if (have_ecdh_tmp) {
         mask_k |= SSL_kEECDH;
         emask_k |= SSL_kEECDH;
     }
 #endif
 
 #ifndef OPENSSL_NO_PSK
     mask_k |= SSL_kPSK;
     mask_a |= SSL_aPSK;
     emask_k |= SSL_kPSK;
     emask_a |= SSL_aPSK;
 #endif
 
     c->mask_k = mask_k;
     c->mask_a = mask_a;
     c->export_mask_k = emask_k;
     c->export_mask_a = emask_a;
     c->valid = 1;
 }
 
 /* This handy macro borrowed from crypto/x509v3/v3_purp.c */
 #define ku_reject(x, usage) \
         (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
 
 #ifndef OPENSSL_NO_EC
 
 int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s)
 {
     unsigned long alg_k, alg_a;
     EVP_PKEY *pkey = NULL;
     int keysize = 0;
     int signature_nid = 0, md_nid = 0, pk_nid = 0;
     const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
 
     alg_k = cs->algorithm_mkey;
     alg_a = cs->algorithm_auth;
 
     if (SSL_C_IS_EXPORT(cs)) {
         /* ECDH key length in export ciphers must be <= 163 bits */
         pkey = X509_get_pubkey(x);
         if (pkey == NULL)
             return 0;
         keysize = EVP_PKEY_bits(pkey);
         EVP_PKEY_free(pkey);
         if (keysize > 163)
             return 0;
     }
 
     /* This call populates the ex_flags field correctly */
     X509_check_purpose(x, -1, 0);
     if ((x->sig_alg) && (x->sig_alg->algorithm)) {
         signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
         OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
     }
     if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) {
         /* key usage, if present, must allow key agreement */
         if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) {
             SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG,
                    SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT);
             return 0;
         }
         if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) {
             /* signature alg must be ECDSA */
             if (pk_nid != NID_X9_62_id_ecPublicKey) {
                 SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG,
                        SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE);
                 return 0;
             }
         }
         if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) {
             /* signature alg must be RSA */
 
             if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) {
                 SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG,
                        SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE);
                 return 0;
             }
         }
     }
     if (alg_a & SSL_aECDSA) {
         /* key usage, if present, must allow signing */
         if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
             SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG,
                    SSL_R_ECC_CERT_NOT_FOR_SIGNING);
             return 0;
         }
     }
 
     return 1;                   /* all checks are ok */
 }
 
 #endif
 
 /* THIS NEEDS CLEANING UP */
 CERT_PKEY *ssl_get_server_send_pkey(const SSL *s)
 {
     unsigned long alg_k, alg_a;
     CERT *c;
     int i;
 
     c = s->cert;
     ssl_set_cert_masks(c, s->s3->tmp.new_cipher);
 
     alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
     alg_a = s->s3->tmp.new_cipher->algorithm_auth;
 
     if (alg_k & (SSL_kECDHr | SSL_kECDHe)) {
         /*
          * we don't need to look at SSL_kEECDH since no certificate is needed
          * for anon ECDH and for authenticated EECDH, the check for the auth
          * algorithm will set i correctly NOTE: For ECDH-RSA, we need an ECC
          * not an RSA cert but for EECDH-RSA we need an RSA cert. Placing the
          * checks for SSL_kECDH before RSA checks ensures the correct cert is
          * chosen.
          */
         i = SSL_PKEY_ECC;
     } else if (alg_a & SSL_aECDSA) {
         i = SSL_PKEY_ECC;
     } else if (alg_k & SSL_kDHr)
         i = SSL_PKEY_DH_RSA;
     else if (alg_k & SSL_kDHd)
         i = SSL_PKEY_DH_DSA;
     else if (alg_a & SSL_aDSS)
         i = SSL_PKEY_DSA_SIGN;
     else if (alg_a & SSL_aRSA) {
         if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL)
             i = SSL_PKEY_RSA_SIGN;
         else
             i = SSL_PKEY_RSA_ENC;
     } else if (alg_a & SSL_aKRB5) {
         /* VRS something else here? */
         return (NULL);
     } else if (alg_a & SSL_aGOST94)
         i = SSL_PKEY_GOST94;
     else if (alg_a & SSL_aGOST01)
         i = SSL_PKEY_GOST01;
     else {                      /* if (alg_a & SSL_aNULL) */
 
         SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY, ERR_R_INTERNAL_ERROR);
         return (NULL);
     }
 
     return c->pkeys + i;
 }
 
 X509 *ssl_get_server_send_cert(const SSL *s)
 {
     CERT_PKEY *cpk;
     cpk = ssl_get_server_send_pkey(s);
     if (!cpk)
         return NULL;
     return cpk->x509;
 }
 
 EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher,
                             const EVP_MD **pmd)
 {
     unsigned long alg_a;
     CERT *c;
     int idx = -1;
 
     alg_a = cipher->algorithm_auth;
     c = s->cert;
 
     if ((alg_a & SSL_aDSS) &&
         (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL))
         idx = SSL_PKEY_DSA_SIGN;
     else if (alg_a & SSL_aRSA) {
         if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL)
             idx = SSL_PKEY_RSA_SIGN;
         else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL)
             idx = SSL_PKEY_RSA_ENC;
     } else if ((alg_a & SSL_aECDSA) &&
                (c->pkeys[SSL_PKEY_ECC].privatekey != NULL))
         idx = SSL_PKEY_ECC;
     if (idx == -1) {
         SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR);
         return (NULL);
     }
     if (pmd)
         *pmd = c->pkeys[idx].digest;
     return c->pkeys[idx].privatekey;
 }
 
 void ssl_update_cache(SSL *s, int mode)
 {
     int i;
 
     /*
      * If the session_id_length is 0, we are not supposed to cache it, and it
      * would be rather hard to do anyway :-)
      */
     if (s->session->session_id_length == 0)
         return;
 
     i = s->session_ctx->session_cache_mode;
     if ((i & mode) && (!s->hit)
         && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE)
             || SSL_CTX_add_session(s->session_ctx, s->session))
         && (s->session_ctx->new_session_cb != NULL)) {
         CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION);
         if (!s->session_ctx->new_session_cb(s, s->session))
             SSL_SESSION_free(s->session);
     }
 
     /* auto flush every 255 connections */
     if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) {
         if ((((mode & SSL_SESS_CACHE_CLIENT)
               ? s->session_ctx->stats.sess_connect_good
               : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) {
             SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL));
         }
     }
 }
 
 const SSL_METHOD *SSL_get_ssl_method(SSL *s)
 {
     return (s->method);
 }
 
 int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth)
 {
     int conn = -1;
     int ret = 1;
 
     if (s->method != meth) {
         if (s->handshake_func != NULL)
             conn = (s->handshake_func == s->method->ssl_connect);
 
         if (s->method->version == meth->version)
             s->method = meth;
         else {
             s->method->ssl_free(s);
             s->method = meth;
             ret = s->method->ssl_new(s);
         }
 
         if (conn == 1)
             s->handshake_func = meth->ssl_connect;
         else if (conn == 0)
             s->handshake_func = meth->ssl_accept;
     }
     return (ret);
 }
 
 int SSL_get_error(const SSL *s, int i)
 {
     int reason;
     unsigned long l;
     BIO *bio;
 
     if (i > 0)
         return (SSL_ERROR_NONE);
 
     /*
      * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
      * where we do encode the error
      */
     if ((l = ERR_peek_error()) != 0) {
         if (ERR_GET_LIB(l) == ERR_LIB_SYS)
             return (SSL_ERROR_SYSCALL);
         else
             return (SSL_ERROR_SSL);
     }
 
     if ((i < 0) && SSL_want_read(s)) {
         bio = SSL_get_rbio(s);
         if (BIO_should_read(bio))
             return (SSL_ERROR_WANT_READ);
         else if (BIO_should_write(bio))
             /*
              * This one doesn't make too much sense ... We never try to write
              * to the rbio, and an application program where rbio and wbio
              * are separate couldn't even know what it should wait for.
              * However if we ever set s->rwstate incorrectly (so that we have
              * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and
              * wbio *are* the same, this test works around that bug; so it
              * might be safer to keep it.
              */
             return (SSL_ERROR_WANT_WRITE);
         else if (BIO_should_io_special(bio)) {
             reason = BIO_get_retry_reason(bio);
             if (reason == BIO_RR_CONNECT)
                 return (SSL_ERROR_WANT_CONNECT);
             else if (reason == BIO_RR_ACCEPT)
                 return (SSL_ERROR_WANT_ACCEPT);
             else
                 return (SSL_ERROR_SYSCALL); /* unknown */
         }
     }
 
     if ((i < 0) && SSL_want_write(s)) {
         bio = SSL_get_wbio(s);
         if (BIO_should_write(bio))
             return (SSL_ERROR_WANT_WRITE);
         else if (BIO_should_read(bio))
             /*
              * See above (SSL_want_read(s) with BIO_should_write(bio))
              */
             return (SSL_ERROR_WANT_READ);
         else if (BIO_should_io_special(bio)) {
             reason = BIO_get_retry_reason(bio);
             if (reason == BIO_RR_CONNECT)
                 return (SSL_ERROR_WANT_CONNECT);
             else if (reason == BIO_RR_ACCEPT)
                 return (SSL_ERROR_WANT_ACCEPT);
             else
                 return (SSL_ERROR_SYSCALL);
         }
     }
     if ((i < 0) && SSL_want_x509_lookup(s)) {
         return (SSL_ERROR_WANT_X509_LOOKUP);
     }
 
     if (i == 0) {
         if (s->version == SSL2_VERSION) {
             /* assume it is the socket being closed */
             return (SSL_ERROR_ZERO_RETURN);
         } else {
             if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
                 (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY))
                 return (SSL_ERROR_ZERO_RETURN);
         }
     }
     return (SSL_ERROR_SYSCALL);
 }
 
 int SSL_do_handshake(SSL *s)
 {
     int ret = 1;
 
     if (s->handshake_func == NULL) {
         SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET);
         return (-1);
     }
 
     s->method->ssl_renegotiate_check(s);
 
     if (SSL_in_init(s) || SSL_in_before(s)) {
         ret = s->handshake_func(s);
     }
     return (ret);
 }
 
 /*
  * For the next 2 functions, SSL_clear() sets shutdown and so one of these
  * calls will reset it
  */
 void SSL_set_accept_state(SSL *s)
 {
     s->server = 1;
     s->shutdown = 0;
     s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE;
     s->handshake_func = s->method->ssl_accept;
     /* clear the current cipher */
     ssl_clear_cipher_ctx(s);
     ssl_clear_hash_ctx(&s->read_hash);
     ssl_clear_hash_ctx(&s->write_hash);
 }
 
 void SSL_set_connect_state(SSL *s)
 {
     s->server = 0;
     s->shutdown = 0;
     s->state = SSL_ST_CONNECT | SSL_ST_BEFORE;
     s->handshake_func = s->method->ssl_connect;
     /* clear the current cipher */
     ssl_clear_cipher_ctx(s);
     ssl_clear_hash_ctx(&s->read_hash);
     ssl_clear_hash_ctx(&s->write_hash);
 }
 
 int ssl_undefined_function(SSL *s)
 {
     SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return (0);
 }
 
 int ssl_undefined_void_function(void)
 {
     SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION,
            ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return (0);
 }
 
 int ssl_undefined_const_function(const SSL *s)
 {
     SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION,
            ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return (0);
 }
 
 SSL_METHOD *ssl_bad_method(int ver)
 {
     SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
     return (NULL);
 }
 
 const char *SSL_get_version(const SSL *s)
 {
     if (s->version == TLS1_2_VERSION)
         return ("TLSv1.2");
     else if (s->version == TLS1_1_VERSION)
         return ("TLSv1.1");
     else if (s->version == TLS1_VERSION)
         return ("TLSv1");
     else if (s->version == SSL3_VERSION)
         return ("SSLv3");
     else if (s->version == SSL2_VERSION)
         return ("SSLv2");
     else
         return ("unknown");
 }
 
 SSL *SSL_dup(SSL *s)
 {
     STACK_OF(X509_NAME) *sk;
     X509_NAME *xn;
     SSL *ret;
     int i;
 
     if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL)
         return (NULL);
 
     ret->version = s->version;
     ret->type = s->type;
     ret->method = s->method;
 
     if (s->session != NULL) {
         /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */
         SSL_copy_session_id(ret, s);
     } else {
         /*
          * No session has been established yet, so we have to expect that
          * s->cert or ret->cert will be changed later -- they should not both
          * point to the same object, and thus we can't use
          * SSL_copy_session_id.
          */
 
         ret->method->ssl_free(ret);
         ret->method = s->method;
         ret->method->ssl_new(ret);
 
         if (s->cert != NULL) {
             if (ret->cert != NULL) {
                 ssl_cert_free(ret->cert);
             }
             ret->cert = ssl_cert_dup(s->cert);
             if (ret->cert == NULL)
                 goto err;
         }
 
         SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length);
     }
 
     ret->options = s->options;
     ret->mode = s->mode;
     SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s));
     SSL_set_read_ahead(ret, SSL_get_read_ahead(s));
     ret->msg_callback = s->msg_callback;
     ret->msg_callback_arg = s->msg_callback_arg;
     SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s));
     SSL_set_verify_depth(ret, SSL_get_verify_depth(s));
     ret->generate_session_id = s->generate_session_id;
 
     SSL_set_info_callback(ret, SSL_get_info_callback(s));
 
     ret->debug = s->debug;
 
     /* copy app data, a little dangerous perhaps */
     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data))
         goto err;
 
     /* setup rbio, and wbio */
     if (s->rbio != NULL) {
         if (!BIO_dup_state(s->rbio, (char *)&ret->rbio))
             goto err;
     }
     if (s->wbio != NULL) {
         if (s->wbio != s->rbio) {
             if (!BIO_dup_state(s->wbio, (char *)&ret->wbio))
                 goto err;
         } else
             ret->wbio = ret->rbio;
     }
     ret->rwstate = s->rwstate;
     ret->in_handshake = s->in_handshake;
     ret->handshake_func = s->handshake_func;
     ret->server = s->server;
     ret->renegotiate = s->renegotiate;
     ret->new_session = s->new_session;
     ret->quiet_shutdown = s->quiet_shutdown;
     ret->shutdown = s->shutdown;
     ret->state = s->state;      /* SSL_dup does not really work at any state,
                                  * though */
     ret->rstate = s->rstate;
     ret->init_num = 0;          /* would have to copy ret->init_buf,
                                  * ret->init_msg, ret->init_num,
                                  * ret->init_off */
     ret->hit = s->hit;
 
     X509_VERIFY_PARAM_inherit(ret->param, s->param);
 
     /* dup the cipher_list and cipher_list_by_id stacks */
     if (s->cipher_list != NULL) {
         if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL)
             goto err;
     }
     if (s->cipher_list_by_id != NULL)
         if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id))
             == NULL)
             goto err;
 
     /* Dup the client_CA list */
     if (s->client_CA != NULL) {
         if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL)
             goto err;
         ret->client_CA = sk;
         for (i = 0; i < sk_X509_NAME_num(sk); i++) {
             xn = sk_X509_NAME_value(sk, i);
             if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) {
                 X509_NAME_free(xn);
                 goto err;
             }
         }
     }
 
     if (0) {
  err:
         if (ret != NULL)
             SSL_free(ret);
         ret = NULL;
     }
     return (ret);
 }
 
 void ssl_clear_cipher_ctx(SSL *s)
 {
     if (s->enc_read_ctx != NULL) {
         EVP_CIPHER_CTX_cleanup(s->enc_read_ctx);
         OPENSSL_free(s->enc_read_ctx);
         s->enc_read_ctx = NULL;
     }
     if (s->enc_write_ctx != NULL) {
         EVP_CIPHER_CTX_cleanup(s->enc_write_ctx);
         OPENSSL_free(s->enc_write_ctx);
         s->enc_write_ctx = NULL;
     }
 #ifndef OPENSSL_NO_COMP
     if (s->expand != NULL) {
         COMP_CTX_free(s->expand);
         s->expand = NULL;
     }
     if (s->compress != NULL) {
         COMP_CTX_free(s->compress);
         s->compress = NULL;
     }
 #endif
 }
 
 /* Fix this function so that it takes an optional type parameter */
 X509 *SSL_get_certificate(const SSL *s)
 {
     if (s->cert != NULL)
         return (s->cert->key->x509);
     else
         return (NULL);
 }
 
 /* Fix this function so that it takes an optional type parameter */
 EVP_PKEY *SSL_get_privatekey(SSL *s)
 {
     if (s->cert != NULL)
         return (s->cert->key->privatekey);
     else
         return (NULL);
 }
 
 const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
 {
     if ((s->session != NULL) && (s->session->cipher != NULL))
         return (s->session->cipher);
     return (NULL);
 }
 
 #ifdef OPENSSL_NO_COMP
 const void *SSL_get_current_compression(SSL *s)
 {
     return NULL;
 }
 
 const void *SSL_get_current_expansion(SSL *s)
 {
     return NULL;
 }
 #else
 
 const COMP_METHOD *SSL_get_current_compression(SSL *s)
 {
     if (s->compress != NULL)
         return (s->compress->meth);
     return (NULL);
 }
 
 const COMP_METHOD *SSL_get_current_expansion(SSL *s)
 {
     if (s->expand != NULL)
         return (s->expand->meth);
     return (NULL);
 }
 #endif
 
 int ssl_init_wbio_buffer(SSL *s, int push)
 {
     BIO *bbio;
 
     if (s->bbio == NULL) {
         bbio = BIO_new(BIO_f_buffer());
         if (bbio == NULL)
             return (0);
         s->bbio = bbio;
     } else {
         bbio = s->bbio;
         if (s->bbio == s->wbio)
             s->wbio = BIO_pop(s->wbio);
     }
     (void)BIO_reset(bbio);
 /*      if (!BIO_set_write_buffer_size(bbio,16*1024)) */
     if (!BIO_set_read_buffer_size(bbio, 1)) {
         SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB);
         return (0);
     }
     if (push) {
         if (s->wbio != bbio)
             s->wbio = BIO_push(bbio, s->wbio);
     } else {
         if (s->wbio == bbio)
             s->wbio = BIO_pop(bbio);
     }
     return (1);
 }
 
 void ssl_free_wbio_buffer(SSL *s)
 {
     if (s->bbio == NULL)
         return;
 
     if (s->bbio == s->wbio) {
         /* remove buffering */
         s->wbio = BIO_pop(s->wbio);
 #ifdef REF_CHECK                /* not the usual REF_CHECK, but this avoids
                                  * adding one more preprocessor symbol */
         assert(s->wbio != NULL);
 #endif
     }
     BIO_free(s->bbio);
     s->bbio = NULL;
 }
 
 void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode)
 {
     ctx->quiet_shutdown = mode;
 }
 
 int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx)
 {
     return (ctx->quiet_shutdown);
 }
 
 void SSL_set_quiet_shutdown(SSL *s, int mode)
 {
     s->quiet_shutdown = mode;
 }
 
 int SSL_get_quiet_shutdown(const SSL *s)
 {
     return (s->quiet_shutdown);
 }
 
 void SSL_set_shutdown(SSL *s, int mode)
 {
     s->shutdown = mode;
 }
 
 int SSL_get_shutdown(const SSL *s)
 {
     return (s->shutdown);
 }
 
 int SSL_version(const SSL *s)
 {
     return (s->version);
 }
 
 SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl)
 {
     return (ssl->ctx);
 }
 
 SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
 {
     CERT *ocert = ssl->cert;
     if (ssl->ctx == ctx)
         return ssl->ctx;
 #ifndef OPENSSL_NO_TLSEXT
     if (ctx == NULL)
         ctx = ssl->initial_ctx;
 #endif
     ssl->cert = ssl_cert_dup(ctx->cert);
     if (ocert != NULL) {
         int i;
         /* Copy negotiated digests from original */
         for (i = 0; i < SSL_PKEY_NUM; i++) {
             CERT_PKEY *cpk = ocert->pkeys + i;
             CERT_PKEY *rpk = ssl->cert->pkeys + i;
             rpk->digest = cpk->digest;
         }
         ssl_cert_free(ocert);
     }
 
     /*
      * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
      * so setter APIs must prevent invalid lengths from entering the system.
      */
     OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx));
 
     /*
      * If the session ID context matches that of the parent SSL_CTX,
      * inherit it from the new SSL_CTX as well. If however the context does
      * not match (i.e., it was set per-ssl with SSL_set_session_id_context),
      * leave it unchanged.
      */
     if ((ssl->ctx != NULL) &&
         (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) &&
         (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) {
         ssl->sid_ctx_length = ctx->sid_ctx_length;
         memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx));
     }
 
     CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX);
     if (ssl->ctx != NULL)
         SSL_CTX_free(ssl->ctx); /* decrement reference count */
     ssl->ctx = ctx;
 
     return (ssl->ctx);
 }
 
 #ifndef OPENSSL_NO_STDIO
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
 {
     return (X509_STORE_set_default_paths(ctx->cert_store));
 }
 
 int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
                                   const char *CApath)
 {
     return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath));
 }
 #endif
 
 void SSL_set_info_callback(SSL *ssl,
                            void (*cb) (const SSL *ssl, int type, int val))
 {
     ssl->info_callback = cb;
 }
 
 /*
  * One compiler (Diab DCC) doesn't like argument names in returned function
  * pointer.
  */
 void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ ,
                                                int /* type */ ,
                                                int /* val */ ) {
     return ssl->info_callback;
 }
 
 int SSL_state(const SSL *ssl)
 {
     return (ssl->state);
 }
 
 void SSL_set_state(SSL *ssl, int state)
 {
     ssl->state = state;
 }
 
 void SSL_set_verify_result(SSL *ssl, long arg)
 {
     ssl->verify_result = arg;
 }
 
 long SSL_get_verify_result(const SSL *ssl)
 {
     return (ssl->verify_result);
 }
 
 int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                          CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
 {
     return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp,
                                    new_func, dup_func, free_func);
 }
 
 int SSL_set_ex_data(SSL *s, int idx, void *arg)
 {
     return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
 }
 
 void *SSL_get_ex_data(const SSL *s, int idx)
 {
     return (CRYPTO_get_ex_data(&s->ex_data, idx));
 }
 
 int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
                              CRYPTO_EX_dup *dup_func,
                              CRYPTO_EX_free *free_func)
 {
     return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp,
                                    new_func, dup_func, free_func);
 }
 
 int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg)
 {
     return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
 }
 
 void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx)
 {
     return (CRYPTO_get_ex_data(&s->ex_data, idx));
 }
 
 int ssl_ok(SSL *s)
 {
     return (1);
 }
 
 X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx)
 {
     return (ctx->cert_store);
 }
 
 void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
 {
     if (ctx->cert_store != NULL)
         X509_STORE_free(ctx->cert_store);
     ctx->cert_store = store;
 }
 
 int SSL_want(const SSL *s)
 {
     return (s->rwstate);
 }
 
 /**
  * \brief Set the callback for generating temporary RSA keys.
  * \param ctx the SSL context.
  * \param cb the callback
  */
 
 #ifndef OPENSSL_NO_RSA
 void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl,
                                                             int is_export,
                                                             int keylength))
 {
     SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
 }
 
 void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl,
                                                     int is_export,
                                                     int keylength))
 {
     SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb);
 }
 #endif
 
 #ifdef DOXYGEN
 /**
  * \brief The RSA temporary key callback function.
  * \param ssl the SSL session.
  * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite.
  * \param keylength if \c is_export is \c TRUE, then \c keylength is the size
  * of the required key in bits.
  * \return the temporary RSA key.
  * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback
  */
 
 RSA *cb(SSL *ssl, int is_export, int keylength)
 {
 }
 #endif
 
 /**
  * \brief Set the callback for generating temporary DH keys.
  * \param ctx the SSL context.
  * \param dh the callback
  */
 
 #ifndef OPENSSL_NO_DH
 void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx,
                                  DH *(*dh) (SSL *ssl, int is_export,
                                             int keylength))
 {
     SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
 }
 
 void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export,
                                                   int keylength))
 {
     SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh);
 }
 #endif
 
 #ifndef OPENSSL_NO_ECDH
 void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx,
                                    EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                     int keylength))
 {
     SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB,
                           (void (*)(void))ecdh);
 }
 
 void SSL_set_tmp_ecdh_callback(SSL *ssl,
                                EC_KEY *(*ecdh) (SSL *ssl, int is_export,
                                                 int keylength))
 {
     SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh);
 }
 #endif
 
 #ifndef OPENSSL_NO_PSK
 int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint)
 {
     if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
         SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT,
                SSL_R_DATA_LENGTH_TOO_LONG);
         return 0;
     }
     if (ctx->psk_identity_hint != NULL)
         OPENSSL_free(ctx->psk_identity_hint);
     if (identity_hint != NULL) {
         ctx->psk_identity_hint = BUF_strdup(identity_hint);
         if (ctx->psk_identity_hint == NULL)
             return 0;
     } else
         ctx->psk_identity_hint = NULL;
     return 1;
 }
 
 int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint)
 {
     if (s == NULL)
         return 0;
 
     if (s->session == NULL)
         return 1;               /* session not created yet, ignored */
 
     if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
         SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG);
         return 0;
     }
     if (s->session->psk_identity_hint != NULL)
         OPENSSL_free(s->session->psk_identity_hint);
     if (identity_hint != NULL) {
         s->session->psk_identity_hint = BUF_strdup(identity_hint);
         if (s->session->psk_identity_hint == NULL)
             return 0;
     } else
         s->session->psk_identity_hint = NULL;
     return 1;
 }
 
 const char *SSL_get_psk_identity_hint(const SSL *s)
 {
     if (s == NULL || s->session == NULL)
         return NULL;
     return (s->session->psk_identity_hint);
 }
 
 const char *SSL_get_psk_identity(const SSL *s)
 {
     if (s == NULL || s->session == NULL)
         return NULL;
     return (s->session->psk_identity);
 }
 
 void SSL_set_psk_client_callback(SSL *s,
                                  unsigned int (*cb) (SSL *ssl,
                                                      const char *hint,
                                                      char *identity,
                                                      unsigned int
                                                      max_identity_len,
                                                      unsigned char *psk,
                                                      unsigned int
                                                      max_psk_len))
 {
     s->psk_client_callback = cb;
 }
 
 void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx,
                                      unsigned int (*cb) (SSL *ssl,
                                                          const char *hint,
                                                          char *identity,
                                                          unsigned int
                                                          max_identity_len,
                                                          unsigned char *psk,
                                                          unsigned int
                                                          max_psk_len))
 {
     ctx->psk_client_callback = cb;
 }
 
 void SSL_set_psk_server_callback(SSL *s,
                                  unsigned int (*cb) (SSL *ssl,
                                                      const char *identity,
                                                      unsigned char *psk,
                                                      unsigned int
                                                      max_psk_len))
 {
     s->psk_server_callback = cb;
 }
 
 void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx,
                                      unsigned int (*cb) (SSL *ssl,
                                                          const char *identity,
                                                          unsigned char *psk,
                                                          unsigned int
                                                          max_psk_len))
 {
     ctx->psk_server_callback = cb;
 }
 #endif
 
 void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
                               void (*cb) (int write_p, int version,
                                           int content_type, const void *buf,
                                           size_t len, SSL *ssl, void *arg))
 {
     SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
 }
 
 void SSL_set_msg_callback(SSL *ssl,
                           void (*cb) (int write_p, int version,
                                       int content_type, const void *buf,
                                       size_t len, SSL *ssl, void *arg))
 {
     SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb);
 }
 
 /*
  * Allocates new EVP_MD_CTX and sets pointer to it into given pointer
  * vairable, freeing EVP_MD_CTX previously stored in that variable, if any.
  * If EVP_MD pointer is passed, initializes ctx with this md Returns newly
  * allocated ctx;
  */
 
 EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md)
 {
     ssl_clear_hash_ctx(hash);
     *hash = EVP_MD_CTX_create();
     if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) {
         EVP_MD_CTX_destroy(*hash);
         *hash = NULL;
         return NULL;
     }
     return *hash;
 }
 
 void ssl_clear_hash_ctx(EVP_MD_CTX **hash)
 {
 
     if (*hash)
         EVP_MD_CTX_destroy(*hash);
     *hash = NULL;
 }
 
 void SSL_set_debug(SSL *s, int debug)
 {
     s->debug = debug;
 }
 
 int SSL_cache_hit(SSL *s)
 {
     return s->hit;
 }
 
 #if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16)
 # include "../crypto/bio/bss_file.c"
 #endif
 
 IMPLEMENT_STACK_OF(SSL_CIPHER)
 IMPLEMENT_STACK_OF(SSL_COMP)
 IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
Index: vendor-crypto/openssl/dist-1.0.1/ssl/ssl_locl.h
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/ssl_locl.h	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/ssl_locl.h	(revision 306191)
@@ -1,1246 +1,1247 @@
 /* ssl/ssl_locl.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.]
  */
 /* ====================================================================
  * 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).
  *
  */
 /* ====================================================================
  * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
  * ECC cipher suite support in OpenSSL originally developed by
  * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project.
  */
 /* ====================================================================
  * Copyright 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #ifndef HEADER_SSL_LOCL_H
 # define HEADER_SSL_LOCL_H
 # include <stdlib.h>
 # include <time.h>
 # include <string.h>
 # include <errno.h>
 
 # include "e_os.h"
 
 # include <openssl/buffer.h>
 # ifndef OPENSSL_NO_COMP
 #  include <openssl/comp.h>
 # endif
 # include <openssl/bio.h>
 # include <openssl/stack.h>
 # ifndef OPENSSL_NO_RSA
 #  include <openssl/rsa.h>
 # endif
 # ifndef OPENSSL_NO_DSA
 #  include <openssl/dsa.h>
 # endif
 # include <openssl/err.h>
 # include <openssl/ssl.h>
 # include <openssl/symhacks.h>
 
 # ifdef OPENSSL_BUILD_SHLIBSSL
 #  undef OPENSSL_EXTERN
 #  define OPENSSL_EXTERN OPENSSL_EXPORT
 # endif
 
 # undef PKCS1_CHECK
 
 # define c2l(c,l)        (l = ((unsigned long)(*((c)++)))     , \
                          l|=(((unsigned long)(*((c)++)))<< 8), \
                          l|=(((unsigned long)(*((c)++)))<<16), \
                          l|=(((unsigned long)(*((c)++)))<<24))
 
 /* NOTE - c is not incremented as per c2l */
 # define c2ln(c,l1,l2,n) { \
                         c+=n; \
                         l1=l2=0; \
                         switch (n) { \
                         case 8: l2 =((unsigned long)(*(--(c))))<<24; \
                         case 7: l2|=((unsigned long)(*(--(c))))<<16; \
                         case 6: l2|=((unsigned long)(*(--(c))))<< 8; \
                         case 5: l2|=((unsigned long)(*(--(c))));     \
                         case 4: l1 =((unsigned long)(*(--(c))))<<24; \
                         case 3: l1|=((unsigned long)(*(--(c))))<<16; \
                         case 2: l1|=((unsigned long)(*(--(c))))<< 8; \
                         case 1: l1|=((unsigned long)(*(--(c))));     \
                                 } \
                         }
 
 # define l2c(l,c)        (*((c)++)=(unsigned char)(((l)    )&0xff), \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>24)&0xff))
 
 # define n2l(c,l)        (l =((unsigned long)(*((c)++)))<<24, \
                          l|=((unsigned long)(*((c)++)))<<16, \
                          l|=((unsigned long)(*((c)++)))<< 8, \
                          l|=((unsigned long)(*((c)++))))
 
 # define l2n(l,c)        (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                          *((c)++)=(unsigned char)(((l)    )&0xff))
 
 # define l2n6(l,c)       (*((c)++)=(unsigned char)(((l)>>40)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>32)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>24)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                          *((c)++)=(unsigned char)(((l)    )&0xff))
 
 # define l2n8(l,c)       (*((c)++)=(unsigned char)(((l)>>56)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>48)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>40)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>32)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>24)&0xff), \
                          *((c)++)=(unsigned char)(((l)>>16)&0xff), \
                          *((c)++)=(unsigned char)(((l)>> 8)&0xff), \
                          *((c)++)=(unsigned char)(((l)    )&0xff))
 
 # define n2l6(c,l)       (l =((BN_ULLONG)(*((c)++)))<<40, \
                          l|=((BN_ULLONG)(*((c)++)))<<32, \
                          l|=((BN_ULLONG)(*((c)++)))<<24, \
                          l|=((BN_ULLONG)(*((c)++)))<<16, \
                          l|=((BN_ULLONG)(*((c)++)))<< 8, \
                          l|=((BN_ULLONG)(*((c)++))))
 
 /* NOTE - c is not incremented as per l2c */
 # define l2cn(l1,l2,c,n) { \
                         c+=n; \
                         switch (n) { \
                         case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \
                         case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \
                         case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \
                         case 5: *(--(c))=(unsigned char)(((l2)    )&0xff); \
                         case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \
                         case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \
                         case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \
                         case 1: *(--(c))=(unsigned char)(((l1)    )&0xff); \
                                 } \
                         }
 
 # define n2s(c,s)        ((s=(((unsigned int)(c[0]))<< 8)| \
                             (((unsigned int)(c[1]))    )),c+=2)
 # define s2n(s,c)        ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
                           c[1]=(unsigned char)(((s)    )&0xff)),c+=2)
 
 # define n2l3(c,l)       ((l =(((unsigned long)(c[0]))<<16)| \
                              (((unsigned long)(c[1]))<< 8)| \
                              (((unsigned long)(c[2]))    )),c+=3)
 
 # define l2n3(l,c)       ((c[0]=(unsigned char)(((l)>>16)&0xff), \
                           c[1]=(unsigned char)(((l)>> 8)&0xff), \
                           c[2]=(unsigned char)(((l)    )&0xff)),c+=3)
 
 /* LOCAL STUFF */
 
 # define SSL_DECRYPT     0
 # define SSL_ENCRYPT     1
 
 # define TWO_BYTE_BIT    0x80
 # define SEC_ESC_BIT     0x40
 # define TWO_BYTE_MASK   0x7fff
 # define THREE_BYTE_MASK 0x3fff
 
 # define INC32(a)        ((a)=((a)+1)&0xffffffffL)
 # define DEC32(a)        ((a)=((a)-1)&0xffffffffL)
 # define MAX_MAC_SIZE    20     /* up from 16 for SSLv3 */
 
 /*
  * Define the Bitmasks for SSL_CIPHER.algorithms.
  * This bits are used packed as dense as possible. If new methods/ciphers
  * etc will be added, the bits a likely to change, so this information
  * is for internal library use only, even though SSL_CIPHER.algorithms
  * can be publicly accessed.
  * Use the according functions for cipher management instead.
  *
  * The bit mask handling in the selection and sorting scheme in
  * ssl_create_cipher_list() has only limited capabilities, reflecting
  * that the different entities within are mutually exclusive:
  * ONLY ONE BIT PER MASK CAN BE SET AT A TIME.
  */
 
 /* Bits for algorithm_mkey (key exchange algorithm) */
 /* RSA key exchange */
 # define SSL_kRSA                0x00000001L
 /* DH cert, RSA CA cert */
 /* no such ciphersuites supported! */
 # define SSL_kDHr                0x00000002L
 /* DH cert, DSA CA cert */
 /* no such ciphersuite supported! */
 # define SSL_kDHd                0x00000004L
 /* tmp DH key no DH cert */
 # define SSL_kEDH                0x00000008L
 /* Kerberos5 key exchange */
 # define SSL_kKRB5               0x00000010L
 /* ECDH cert, RSA CA cert */
 # define SSL_kECDHr              0x00000020L
 /* ECDH cert, ECDSA CA cert */
 # define SSL_kECDHe              0x00000040L
 /* ephemeral ECDH */
 # define SSL_kEECDH              0x00000080L
 /* PSK */
 # define SSL_kPSK                0x00000100L
 /* GOST key exchange */
 # define SSL_kGOST       0x00000200L
 /* SRP */
 # define SSL_kSRP        0x00000400L
 
 /* Bits for algorithm_auth (server authentication) */
 /* RSA auth */
 # define SSL_aRSA                0x00000001L
 /* DSS auth */
 # define SSL_aDSS                0x00000002L
 /* no auth (i.e. use ADH or AECDH) */
 # define SSL_aNULL               0x00000004L
 /* Fixed DH auth (kDHd or kDHr) */
 /* no such ciphersuites supported! */
 # define SSL_aDH                 0x00000008L
 /* Fixed ECDH auth (kECDHe or kECDHr) */
 # define SSL_aECDH               0x00000010L
 /* KRB5 auth */
 # define SSL_aKRB5               0x00000020L
 /* ECDSA auth*/
 # define SSL_aECDSA              0x00000040L
 /* PSK auth */
 # define SSL_aPSK                0x00000080L
 /* GOST R 34.10-94 signature auth */
 # define SSL_aGOST94                             0x00000100L
 /* GOST R 34.10-2001 signature auth */
 # define SSL_aGOST01                     0x00000200L
 /* SRP auth */
 # define SSL_aSRP                0x00000400L
 
 /* Bits for algorithm_enc (symmetric encryption) */
 # define SSL_DES                 0x00000001L
 # define SSL_3DES                0x00000002L
 # define SSL_RC4                 0x00000004L
 # define SSL_RC2                 0x00000008L
 # define SSL_IDEA                0x00000010L
 # define SSL_eNULL               0x00000020L
 # define SSL_AES128              0x00000040L
 # define SSL_AES256              0x00000080L
 # define SSL_CAMELLIA128         0x00000100L
 # define SSL_CAMELLIA256         0x00000200L
 # define SSL_eGOST2814789CNT     0x00000400L
 # define SSL_SEED                0x00000800L
 # define SSL_AES128GCM           0x00001000L
 # define SSL_AES256GCM           0x00002000L
 
 # define SSL_AES                 (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM)
 # define SSL_CAMELLIA            (SSL_CAMELLIA128|SSL_CAMELLIA256)
 
 /* Bits for algorithm_mac (symmetric authentication) */
 
 # define SSL_MD5                 0x00000001L
 # define SSL_SHA1                0x00000002L
 # define SSL_GOST94      0x00000004L
 # define SSL_GOST89MAC   0x00000008L
 # define SSL_SHA256              0x00000010L
 # define SSL_SHA384              0x00000020L
 /* Not a real MAC, just an indication it is part of cipher */
 # define SSL_AEAD                0x00000040L
 
 /* Bits for algorithm_ssl (protocol version) */
 # define SSL_SSLV2               0x00000001UL
 # define SSL_SSLV3               0x00000002UL
 # define SSL_TLSV1               SSL_SSLV3/* for now */
 # define SSL_TLSV1_2             0x00000004UL
 
 /* Bits for algorithm2 (handshake digests and other extra flags) */
 
 # define SSL_HANDSHAKE_MAC_MD5 0x10
 # define SSL_HANDSHAKE_MAC_SHA 0x20
 # define SSL_HANDSHAKE_MAC_GOST94 0x40
 # define SSL_HANDSHAKE_MAC_SHA256 0x80
 # define SSL_HANDSHAKE_MAC_SHA384 0x100
 # define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
 
 /*
  * When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX make
  * sure to update this constant too
  */
 # define SSL_MAX_DIGEST 6
 
 # define TLS1_PRF_DGST_MASK      (0xff << TLS1_PRF_DGST_SHIFT)
 
 # define TLS1_PRF_DGST_SHIFT 10
 # define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT)
 # define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT)
 # define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT)
 # define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT)
 # define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT)
 # define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1)
 
 /*
  * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also
  * goes into algorithm2)
  */
 # define TLS1_STREAM_MAC 0x04
 
 /*
  * Export and cipher strength information. For each cipher we have to decide
  * whether it is exportable or not. This information is likely to change
  * over time, since the export control rules are no static technical issue.
  *
  * Independent of the export flag the cipher strength is sorted into classes.
  * SSL_EXP40 was denoting the 40bit US export limit of past times, which now
  * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change
  * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more,
  * since SSL_EXP64 could be similar to SSL_LOW.
  * For this reason SSL_MICRO and SSL_MINI macros are included to widen the
  * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed
  * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would
  * be possible.
  */
 # define SSL_EXP_MASK            0x00000003L
 # define SSL_STRONG_MASK         0x000001fcL
 
 # define SSL_NOT_EXP             0x00000001L
 # define SSL_EXPORT              0x00000002L
 
 # define SSL_STRONG_NONE         0x00000004L
 # define SSL_EXP40               0x00000008L
 # define SSL_MICRO               (SSL_EXP40)
 # define SSL_EXP56               0x00000010L
 # define SSL_MINI                (SSL_EXP56)
 # define SSL_LOW                 0x00000020L
 # define SSL_MEDIUM              0x00000040L
 # define SSL_HIGH                0x00000080L
 # define SSL_FIPS                0x00000100L
 # define SSL_NOT_DEFAULT         0x00000200L
 
 /* we have used 000003ff - 22 bits left to go */
 
 /*-
  * Macros to check the export status and cipher strength for export ciphers.
  * Even though the macros for EXPORT and EXPORT40/56 have similar names,
  * their meaning is different:
  * *_EXPORT macros check the 'exportable' status.
  * *_EXPORT40/56 macros are used to check whether a certain cipher strength
  *          is given.
  * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct
  * algorithm structure element to be passed (algorithms, algo_strength) and no
  * typechecking can be done as they are all of type unsigned long, their
  * direct usage is discouraged.
  * Use the SSL_C_* macros instead.
  */
 # define SSL_IS_EXPORT(a)        ((a)&SSL_EXPORT)
 # define SSL_IS_EXPORT56(a)      ((a)&SSL_EXP56)
 # define SSL_IS_EXPORT40(a)      ((a)&SSL_EXP40)
 # define SSL_C_IS_EXPORT(c)      SSL_IS_EXPORT((c)->algo_strength)
 # define SSL_C_IS_EXPORT56(c)    SSL_IS_EXPORT56((c)->algo_strength)
 # define SSL_C_IS_EXPORT40(c)    SSL_IS_EXPORT40((c)->algo_strength)
 
 # define SSL_EXPORT_KEYLENGTH(a,s)       (SSL_IS_EXPORT40(s) ? 5 : \
                                  (a) == SSL_DES ? 8 : 7)
 # define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024)
 # define SSL_C_EXPORT_KEYLENGTH(c)       SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \
                                 (c)->algo_strength)
 # define SSL_C_EXPORT_PKEYLENGTH(c)      SSL_EXPORT_PKEYLENGTH((c)->algo_strength)
 
 /* Mostly for SSLv3 */
 # define SSL_PKEY_RSA_ENC        0
 # define SSL_PKEY_RSA_SIGN       1
 # define SSL_PKEY_DSA_SIGN       2
 # define SSL_PKEY_DH_RSA         3
 # define SSL_PKEY_DH_DSA         4
 # define SSL_PKEY_ECC            5
 # define SSL_PKEY_GOST94         6
 # define SSL_PKEY_GOST01         7
 # define SSL_PKEY_NUM            8
 
 /*-
  * SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) |
  *          <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN)
  * SSL_kDH  <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN)
  * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN
  * SSL_aRSA <- RSA_ENC | RSA_SIGN
  * SSL_aDSS <- DSA_SIGN
  */
 
 /*-
 #define CERT_INVALID            0
 #define CERT_PUBLIC_KEY         1
 #define CERT_PRIVATE_KEY        2
 */
 
 # ifndef OPENSSL_NO_EC
 /*
  * From ECC-TLS draft, used in encoding the curve type in ECParameters
  */
 #  define EXPLICIT_PRIME_CURVE_TYPE  1
 #  define EXPLICIT_CHAR2_CURVE_TYPE  2
 #  define NAMED_CURVE_TYPE           3
 # endif                         /* OPENSSL_NO_EC */
 
 typedef struct cert_pkey_st {
     X509 *x509;
     EVP_PKEY *privatekey;
     /* Digest to use when signing */
     const EVP_MD *digest;
 } CERT_PKEY;
 
 typedef struct cert_st {
     /* Current active set */
     /*
      * ALWAYS points to an element of the pkeys array
      * Probably it would make more sense to store
      * an index, not a pointer.
      */
     CERT_PKEY *key;
     /*
      * The following masks are for the key and auth algorithms that are
      * supported by the certs below
      */
     int valid;
     unsigned long mask_k;
     unsigned long mask_a;
     unsigned long export_mask_k;
     unsigned long export_mask_a;
 # ifndef OPENSSL_NO_RSA
     RSA *rsa_tmp;
     RSA *(*rsa_tmp_cb) (SSL *ssl, int is_export, int keysize);
 # endif
 # ifndef OPENSSL_NO_DH
     DH *dh_tmp;
     DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize);
 # endif
 # ifndef OPENSSL_NO_ECDH
     EC_KEY *ecdh_tmp;
     /* Callback for generating ephemeral ECDH keys */
     EC_KEY *(*ecdh_tmp_cb) (SSL *ssl, int is_export, int keysize);
 # endif
     CERT_PKEY pkeys[SSL_PKEY_NUM];
     int references;             /* >1 only if SSL_copy_session_id is used */
 } CERT;
 
 typedef struct sess_cert_st {
     STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */
     /* The 'peer_...' members are used only by clients. */
     int peer_cert_type;
     CERT_PKEY *peer_key;        /* points to an element of peer_pkeys (never
                                  * NULL!) */
     CERT_PKEY peer_pkeys[SSL_PKEY_NUM];
     /*
      * Obviously we don't have the private keys of these, so maybe we
      * shouldn't even use the CERT_PKEY type here.
      */
 # ifndef OPENSSL_NO_RSA
     RSA *peer_rsa_tmp;          /* not used for SSL 2 */
 # endif
 # ifndef OPENSSL_NO_DH
     DH *peer_dh_tmp;            /* not used for SSL 2 */
 # endif
 # ifndef OPENSSL_NO_ECDH
     EC_KEY *peer_ecdh_tmp;
 # endif
     int references;             /* actually always 1 at the moment */
 } SESS_CERT;
 
 /*
  * #define MAC_DEBUG
  */
 
 /*
  * #define ERR_DEBUG
  */
 /*
  * #define ABORT_DEBUG
  */
 /*
  * #define PKT_DEBUG 1
  */
 /*
  * #define DES_DEBUG
  */
 /*
  * #define DES_OFB_DEBUG
  */
 /*
  * #define SSL_DEBUG
  */
 /*
  * #define RSA_DEBUG
  */
 /*
  * #define IDEA_DEBUG
  */
 
 # define FP_ICC  (int (*)(const void *,const void *))
 # define ssl_put_cipher_by_char(ssl,ciph,ptr) \
                 ((ssl)->method->put_cipher_by_char((ciph),(ptr)))
 # define ssl_get_cipher_by_char(ssl,ptr) \
                 ((ssl)->method->get_cipher_by_char(ptr))
 
 /*
  * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit
  * of a mess of functions, but hell, think of it as an opaque structure :-)
  */
 typedef struct ssl3_enc_method {
     int (*enc) (SSL *, int);
     int (*mac) (SSL *, unsigned char *, int);
     int (*setup_key_block) (SSL *);
     int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *,
                                    int);
     int (*change_cipher_state) (SSL *, int);
     int (*final_finish_mac) (SSL *, const char *, int, unsigned char *);
     int finish_mac_length;
     int (*cert_verify_mac) (SSL *, int, unsigned char *);
     const char *client_finished_label;
     int client_finished_label_len;
     const char *server_finished_label;
     int server_finished_label_len;
     int (*alert_value) (int);
     int (*export_keying_material) (SSL *, unsigned char *, size_t,
                                    const char *, size_t,
                                    const unsigned char *, size_t,
                                    int use_context);
 } SSL3_ENC_METHOD;
 
 # ifndef OPENSSL_NO_COMP
 /* Used for holding the relevant compression methods loaded into SSL_CTX */
 typedef struct ssl3_comp_st {
     int comp_id;                /* The identifier byte for this compression
                                  * type */
     char *name;                 /* Text name used for the compression type */
     COMP_METHOD *method;        /* The method :-) */
 } SSL3_COMP;
 # endif
 
 # ifndef OPENSSL_NO_BUF_FREELISTS
 typedef struct ssl3_buf_freelist_st {
     size_t chunklen;
     unsigned int len;
     struct ssl3_buf_freelist_entry_st *head;
 } SSL3_BUF_FREELIST;
 
 typedef struct ssl3_buf_freelist_entry_st {
     struct ssl3_buf_freelist_entry_st *next;
 } SSL3_BUF_FREELIST_ENTRY;
 # endif
 
 extern SSL3_ENC_METHOD ssl3_undef_enc_method;
 OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[];
 OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[];
 
 SSL_METHOD *ssl_bad_method(int ver);
 
 extern SSL3_ENC_METHOD TLSv1_enc_data;
 extern SSL3_ENC_METHOD SSLv3_enc_data;
 extern SSL3_ENC_METHOD DTLSv1_enc_data;
 
 # define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION)
 
 # define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \
                                 s_get_meth) \
 const SSL_METHOD *func_name(void)  \
         { \
         static const SSL_METHOD func_name##_data= { \
                 version, \
                 tls1_new, \
                 tls1_clear, \
                 tls1_free, \
                 s_accept, \
                 s_connect, \
                 ssl3_read, \
                 ssl3_peek, \
                 ssl3_write, \
                 ssl3_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
                 ssl3_get_message, \
                 ssl3_read_bytes, \
                 ssl3_write_bytes, \
                 ssl3_dispatch_alert, \
                 ssl3_ctrl, \
                 ssl3_ctx_ctrl, \
                 ssl3_get_cipher_by_char, \
                 ssl3_put_cipher_by_char, \
                 ssl3_pending, \
                 ssl3_num_ciphers, \
                 ssl3_get_cipher, \
                 s_get_meth, \
                 tls1_default_timeout, \
                 &TLSv1_enc_data, \
                 ssl_undefined_void_function, \
                 ssl3_callback_ctrl, \
                 ssl3_ctx_callback_ctrl, \
         }; \
         return &func_name##_data; \
         }
 
 # define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \
 const SSL_METHOD *func_name(void)  \
         { \
         static const SSL_METHOD func_name##_data= { \
                 SSL3_VERSION, \
                 ssl3_new, \
                 ssl3_clear, \
                 ssl3_free, \
                 s_accept, \
                 s_connect, \
                 ssl3_read, \
                 ssl3_peek, \
                 ssl3_write, \
                 ssl3_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
                 ssl3_get_message, \
                 ssl3_read_bytes, \
                 ssl3_write_bytes, \
                 ssl3_dispatch_alert, \
                 ssl3_ctrl, \
                 ssl3_ctx_ctrl, \
                 ssl3_get_cipher_by_char, \
                 ssl3_put_cipher_by_char, \
                 ssl3_pending, \
                 ssl3_num_ciphers, \
                 ssl3_get_cipher, \
                 s_get_meth, \
                 ssl3_default_timeout, \
                 &SSLv3_enc_data, \
                 ssl_undefined_void_function, \
                 ssl3_callback_ctrl, \
                 ssl3_ctx_callback_ctrl, \
         }; \
         return &func_name##_data; \
         }
 
 # define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \
 const SSL_METHOD *func_name(void)  \
         { \
         static const SSL_METHOD func_name##_data= { \
         TLS1_2_VERSION, \
         tls1_new, \
         tls1_clear, \
         tls1_free, \
         s_accept, \
         s_connect, \
         ssl23_read, \
         ssl23_peek, \
         ssl23_write, \
         ssl_undefined_function, \
         ssl_undefined_function, \
         ssl_ok, \
         ssl3_get_message, \
         ssl3_read_bytes, \
         ssl3_write_bytes, \
         ssl3_dispatch_alert, \
         ssl3_ctrl, \
         ssl3_ctx_ctrl, \
         ssl23_get_cipher_by_char, \
         ssl23_put_cipher_by_char, \
         ssl_undefined_const_function, \
         ssl23_num_ciphers, \
         ssl23_get_cipher, \
         s_get_meth, \
         ssl23_default_timeout, \
         &ssl3_undef_enc_method, \
         ssl_undefined_void_function, \
         ssl3_callback_ctrl, \
         ssl3_ctx_callback_ctrl, \
         }; \
         return &func_name##_data; \
         }
 
 # define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \
 const SSL_METHOD *func_name(void)  \
         { \
         static const SSL_METHOD func_name##_data= { \
                 SSL2_VERSION, \
                 ssl2_new,       /* local */ \
                 ssl2_clear,     /* local */ \
                 ssl2_free,      /* local */ \
                 s_accept, \
                 s_connect, \
                 ssl2_read, \
                 ssl2_peek, \
                 ssl2_write, \
                 ssl2_shutdown, \
                 ssl_ok, /* NULL - renegotiate */ \
                 ssl_ok, /* NULL - check renegotiate */ \
                 NULL, /* NULL - ssl_get_message */ \
                 NULL, /* NULL - ssl_get_record */ \
                 NULL, /* NULL - ssl_write_bytes */ \
                 NULL, /* NULL - dispatch_alert */ \
                 ssl2_ctrl,      /* local */ \
                 ssl2_ctx_ctrl,  /* local */ \
                 ssl2_get_cipher_by_char, \
                 ssl2_put_cipher_by_char, \
                 ssl2_pending, \
                 ssl2_num_ciphers, \
                 ssl2_get_cipher, \
                 s_get_meth, \
                 ssl2_default_timeout, \
                 &ssl3_undef_enc_method, \
                 ssl_undefined_void_function, \
                 ssl2_callback_ctrl,     /* local */ \
                 ssl2_ctx_callback_ctrl, /* local */ \
         }; \
         return &func_name##_data; \
         }
 
 # define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \
 const SSL_METHOD *func_name(void)  \
         { \
         static const SSL_METHOD func_name##_data= { \
                 DTLS1_VERSION, \
                 dtls1_new, \
                 dtls1_clear, \
                 dtls1_free, \
                 s_accept, \
                 s_connect, \
                 ssl3_read, \
                 ssl3_peek, \
                 ssl3_write, \
                 dtls1_shutdown, \
                 ssl3_renegotiate, \
                 ssl3_renegotiate_check, \
                 dtls1_get_message, \
                 dtls1_read_bytes, \
                 dtls1_write_app_data_bytes, \
                 dtls1_dispatch_alert, \
                 dtls1_ctrl, \
                 ssl3_ctx_ctrl, \
                 ssl3_get_cipher_by_char, \
                 ssl3_put_cipher_by_char, \
                 ssl3_pending, \
                 ssl3_num_ciphers, \
                 dtls1_get_cipher, \
                 s_get_meth, \
                 dtls1_default_timeout, \
                 &DTLSv1_enc_data, \
                 ssl_undefined_void_function, \
                 ssl3_callback_ctrl, \
                 ssl3_ctx_callback_ctrl, \
         }; \
         return &func_name##_data; \
         }
 
 struct openssl_ssl_test_functions {
     int (*p_ssl_init_wbio_buffer) (SSL *s, int push);
     int (*p_ssl3_setup_buffers) (SSL *s);
     int (*p_tls1_process_heartbeat) (SSL *s);
     int (*p_dtls1_process_heartbeat) (SSL *s);
 };
 
 # ifndef OPENSSL_UNIT_TEST
 
 void ssl_clear_cipher_ctx(SSL *s);
 int ssl_clear_bad_session(SSL *s);
 CERT *ssl_cert_new(void);
 CERT *ssl_cert_dup(CERT *cert);
 int ssl_cert_inst(CERT **o);
 void ssl_cert_free(CERT *c);
 SESS_CERT *ssl_sess_cert_new(void);
 void ssl_sess_cert_free(SESS_CERT *sc);
 int ssl_set_peer_cert_type(SESS_CERT *c, int type);
 int ssl_get_new_session(SSL *s, int session);
 int ssl_get_prev_session(SSL *s, unsigned char *session, int len,
                          const unsigned char *limit);
 SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket);
 int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b);
 DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id);
 int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap,
                           const SSL_CIPHER *const *bp);
 STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p,
                                                int num,
                                                STACK_OF(SSL_CIPHER) **skp);
 int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
                              unsigned char *p,
                              int (*put_cb) (const SSL_CIPHER *,
                                             unsigned char *));
 STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth,
                                              STACK_OF(SSL_CIPHER) **pref,
                                              STACK_OF(SSL_CIPHER) **sorted,
                                              const char *rule_str);
 void ssl_update_cache(SSL *s, int mode);
 int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc,
                        const EVP_MD **md, int *mac_pkey_type,
                        int *mac_secret_size, SSL_COMP **comp);
 int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md);
 int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
 int ssl_undefined_function(SSL *s);
 int ssl_undefined_void_function(void);
 int ssl_undefined_const_function(const SSL *s);
 CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
 X509 *ssl_get_server_send_cert(const SSL *);
 EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd);
 int ssl_cert_type(X509 *x, EVP_PKEY *pkey);
 void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher);
 STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s);
 int ssl_verify_alarm_type(long type);
 void ssl_load_ciphers(void);
 int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len);
 
 int ssl2_enc_init(SSL *s, int client);
 int ssl2_generate_key_material(SSL *s);
 int ssl2_enc(SSL *s, int send_data);
 void ssl2_mac(SSL *s, unsigned char *mac, int send_data);
 const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p);
 int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
 int ssl2_part_read(SSL *s, unsigned long f, int i);
 int ssl2_do_write(SSL *s);
 int ssl2_set_certificate(SSL *s, int type, int len,
                          const unsigned char *data);
 void ssl2_return_error(SSL *s, int reason);
 void ssl2_write_error(SSL *s);
 int ssl2_num_ciphers(void);
 const SSL_CIPHER *ssl2_get_cipher(unsigned int u);
 int ssl2_new(SSL *s);
 void ssl2_free(SSL *s);
 int ssl2_accept(SSL *s);
 int ssl2_connect(SSL *s);
 int ssl2_read(SSL *s, void *buf, int len);
 int ssl2_peek(SSL *s, void *buf, int len);
 int ssl2_write(SSL *s, const void *buf, int len);
 int ssl2_shutdown(SSL *s);
 void ssl2_clear(SSL *s);
 long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg);
 long ssl2_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
 long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void));
 long ssl2_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void));
 int ssl2_pending(const SSL *s);
 long ssl2_default_timeout(void);
 
 const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
 int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
 void ssl3_init_finished_mac(SSL *s);
 int ssl3_send_server_certificate(SSL *s);
 int ssl3_send_newsession_ticket(SSL *s);
 int ssl3_send_cert_status(SSL *s);
 int ssl3_get_finished(SSL *s, int state_a, int state_b);
 int ssl3_setup_key_block(SSL *s);
 int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b);
 int ssl3_change_cipher_state(SSL *s, int which);
 void ssl3_cleanup_key_block(SSL *s);
 int ssl3_do_write(SSL *s, int type);
 int ssl3_send_alert(SSL *s, int level, int desc);
 int ssl3_generate_master_secret(SSL *s, unsigned char *out,
                                 unsigned char *p, int len);
 int ssl3_get_req_cert_type(SSL *s, unsigned char *p);
 long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen);
 int ssl3_num_ciphers(void);
 const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
 int ssl3_renegotiate(SSL *ssl);
 int ssl3_renegotiate_check(SSL *ssl);
 int ssl3_dispatch_alert(SSL *s);
 int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
 int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
 int ssl3_final_finish_mac(SSL *s, const char *sender, int slen,
                           unsigned char *p);
 int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
 void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len);
 int ssl3_enc(SSL *s, int send_data);
 int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data);
 void ssl3_free_digest_list(SSL *s);
 unsigned long ssl3_output_cert_chain(SSL *s, X509 *x);
 SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt,
                                STACK_OF(SSL_CIPHER) *srvr);
 int ssl3_setup_buffers(SSL *s);
 int ssl3_setup_read_buffer(SSL *s);
 int ssl3_setup_write_buffer(SSL *s);
 int ssl3_release_read_buffer(SSL *s);
 int ssl3_release_write_buffer(SSL *s);
 int ssl3_digest_cached_records(SSL *s);
 int ssl3_new(SSL *s);
 void ssl3_free(SSL *s);
 int ssl3_accept(SSL *s);
 int ssl3_connect(SSL *s);
 int ssl3_read(SSL *s, void *buf, int len);
 int ssl3_peek(SSL *s, void *buf, int len);
 int ssl3_write(SSL *s, const void *buf, int len);
 int ssl3_shutdown(SSL *s);
 void ssl3_clear(SSL *s);
 long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg);
 long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
 long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void));
 long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void));
 int ssl3_pending(const SSL *s);
 
 void ssl3_record_sequence_update(unsigned char *seq);
 int ssl3_do_change_cipher_spec(SSL *ssl);
 long ssl3_default_timeout(void);
 
 int ssl23_num_ciphers(void);
 const SSL_CIPHER *ssl23_get_cipher(unsigned int u);
 int ssl23_read(SSL *s, void *buf, int len);
 int ssl23_peek(SSL *s, void *buf, int len);
 int ssl23_write(SSL *s, const void *buf, int len);
 int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
 const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p);
 long ssl23_default_timeout(void);
 
 long tls1_default_timeout(void);
 int dtls1_do_write(SSL *s, int type);
 int ssl3_read_n(SSL *s, int n, int max, int extend);
 int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek);
 int ssl3_do_compress(SSL *ssl);
 int ssl3_do_uncompress(SSL *ssl);
 int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
                        unsigned int len);
 unsigned char *dtls1_set_message_header(SSL *s,
                                         unsigned char *p, unsigned char mt,
                                         unsigned long len,
                                         unsigned long frag_off,
                                         unsigned long frag_len);
 
 int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len);
 int dtls1_write_bytes(SSL *s, int type, const void *buf, int len);
 
 int dtls1_send_change_cipher_spec(SSL *s, int a, int b);
 int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen);
 unsigned long dtls1_output_cert_chain(SSL *s, X509 *x);
 int dtls1_read_failed(SSL *s, int code);
 int dtls1_buffer_message(SSL *s, int ccs);
 int dtls1_retransmit_message(SSL *s, unsigned short seq,
                              unsigned long frag_off, int *found);
 int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
 int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
 void dtls1_get_message_header(unsigned char *data,
                               struct hm_header_st *msg_hdr);
 void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
 void dtls1_reset_seq_numbers(SSL *s, int rw);
 long dtls1_default_timeout(void);
 struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft);
 int dtls1_check_timeout_num(SSL *s);
 int dtls1_handle_timeout(SSL *s);
 const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
 void dtls1_start_timer(SSL *s);
 void dtls1_stop_timer(SSL *s);
 int dtls1_is_timer_expired(SSL *s);
 void dtls1_double_timeout(SSL *s);
 int dtls1_send_newsession_ticket(SSL *s);
 unsigned int dtls1_min_mtu(SSL *s);
 unsigned int dtls1_link_min_mtu(void);
 void dtls1_hm_fragment_free(hm_fragment *frag);
 
 /* some client-only functions */
 int ssl3_client_hello(SSL *s);
 int ssl3_get_server_hello(SSL *s);
 int ssl3_get_certificate_request(SSL *s);
 int ssl3_get_new_session_ticket(SSL *s);
 int ssl3_get_cert_status(SSL *s);
 int ssl3_get_server_done(SSL *s);
 int ssl3_send_client_verify(SSL *s);
 int ssl3_send_client_certificate(SSL *s);
 int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
 int ssl3_send_client_key_exchange(SSL *s);
 int ssl3_get_key_exchange(SSL *s);
 int ssl3_get_server_certificate(SSL *s);
 int ssl3_check_cert_and_algorithm(SSL *s);
 #  ifndef OPENSSL_NO_TLSEXT
 #   ifndef OPENSSL_NO_NEXTPROTONEG
 int ssl3_send_next_proto(SSL *s);
 #   endif
 #  endif
 
 int dtls1_client_hello(SSL *s);
 int dtls1_send_client_certificate(SSL *s);
 int dtls1_send_client_key_exchange(SSL *s);
 int dtls1_send_client_verify(SSL *s);
 
 /* some server-only functions */
 int ssl3_get_client_hello(SSL *s);
 int ssl3_send_server_hello(SSL *s);
 int ssl3_send_hello_request(SSL *s);
 int ssl3_send_server_key_exchange(SSL *s);
 int ssl3_send_certificate_request(SSL *s);
 int ssl3_send_server_done(SSL *s);
 int ssl3_check_client_hello(SSL *s);
 int ssl3_get_client_certificate(SSL *s);
 int ssl3_get_client_key_exchange(SSL *s);
 int ssl3_get_cert_verify(SSL *s);
 #  ifndef OPENSSL_NO_NEXTPROTONEG
 int ssl3_get_next_proto(SSL *s);
 #  endif
 
 int dtls1_send_hello_request(SSL *s);
 int dtls1_send_server_hello(SSL *s);
 int dtls1_send_server_certificate(SSL *s);
 int dtls1_send_server_key_exchange(SSL *s);
 int dtls1_send_certificate_request(SSL *s);
 int dtls1_send_server_done(SSL *s);
 
 int ssl23_accept(SSL *s);
 int ssl23_connect(SSL *s);
 int ssl23_read_bytes(SSL *s, int n);
 int ssl23_write_bytes(SSL *s);
 
 int tls1_new(SSL *s);
 void tls1_free(SSL *s);
 void tls1_clear(SSL *s);
 long tls1_ctrl(SSL *s, int cmd, long larg, void *parg);
 long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void));
 
 int dtls1_new(SSL *s);
 int dtls1_accept(SSL *s);
 int dtls1_connect(SSL *s);
 void dtls1_free(SSL *s);
 void dtls1_clear(SSL *s);
 long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg);
 int dtls1_shutdown(SSL *s);
 
 long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok);
 int dtls1_get_record(SSL *s);
 int do_dtls1_write(SSL *s, int type, const unsigned char *buf,
                    unsigned int len, int create_empty_fragement);
 int dtls1_dispatch_alert(SSL *s);
 int dtls1_enc(SSL *s, int snd);
 
 int ssl_init_wbio_buffer(SSL *s, int push);
 void ssl_free_wbio_buffer(SSL *s);
 
 int tls1_change_cipher_state(SSL *s, int which);
 int tls1_setup_key_block(SSL *s);
 int tls1_enc(SSL *s, int snd);
 int tls1_final_finish_mac(SSL *s,
                           const char *str, int slen, unsigned char *p);
 int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p);
 int tls1_mac(SSL *ssl, unsigned char *md, int snd);
 int tls1_generate_master_secret(SSL *s, unsigned char *out,
                                 unsigned char *p, int len);
 int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen,
                                 const char *label, size_t llen,
                                 const unsigned char *p, size_t plen,
                                 int use_context);
 int tls1_alert_code(int code);
 int ssl3_alert_code(int code);
 int ssl_ok(SSL *s);
 
 #  ifndef OPENSSL_NO_ECDH
 int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
 #  endif
 
 SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n);
 
 #  ifndef OPENSSL_NO_EC
 int tls1_ec_curve_id2nid(int curve_id);
 int tls1_ec_nid2curve_id(int nid);
 #  endif                        /* OPENSSL_NO_EC */
 
 #  ifndef OPENSSL_NO_TLSEXT
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
                                           unsigned char *limit);
 unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
                                           unsigned char *limit);
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *limit, int *al);
 int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
                                  unsigned char *d, int n, int *al);
 int ssl_prepare_clienthello_tlsext(SSL *s);
 int ssl_prepare_serverhello_tlsext(SSL *s);
 int ssl_check_clienthello_tlsext_early(SSL *s);
 int ssl_check_clienthello_tlsext_late(SSL *s);
 int ssl_check_serverhello_tlsext(SSL *s);
 
 #   ifndef OPENSSL_NO_HEARTBEATS
 int tls1_heartbeat(SSL *s);
 int dtls1_heartbeat(SSL *s);
 int tls1_process_heartbeat(SSL *s);
 int dtls1_process_heartbeat(SSL *s);
 #   endif
 
 #   ifdef OPENSSL_NO_SHA256
 #    define tlsext_tick_md  EVP_sha1
 #   else
 #    define tlsext_tick_md  EVP_sha256
 #   endif
 int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
                         const unsigned char *limit, SSL_SESSION **ret);
 
 int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
                          const EVP_MD *md);
 int tls12_get_sigid(const EVP_PKEY *pk);
 const EVP_MD *tls12_get_hash(unsigned char hash_alg);
 
 #  endif
 EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md);
 void ssl_clear_hash_ctx(EVP_MD_CTX **hash);
 int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
                                         int maxlen);
 int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len,
                                           int *al);
 int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
                                         int maxlen);
 int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
                                           int *al);
 long ssl_get_algorithm2(SSL *s);
 int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize);
 int tls12_get_req_sig_algs(SSL *s, unsigned char *p);
 
 int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
                                      int maxlen);
 int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len,
                                        int *al);
 int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
                                      int maxlen);
 int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len,
                                        int *al);
 
 /* s3_cbc.c */
 void ssl3_cbc_copy_mac(unsigned char *out,
                        const SSL3_RECORD *rec,
                        unsigned md_size, unsigned orig_len);
 int ssl3_cbc_remove_padding(const SSL *s,
                             SSL3_RECORD *rec,
                             unsigned block_size, unsigned mac_size);
 int tls1_cbc_remove_padding(const SSL *s,
                             SSL3_RECORD *rec,
                             unsigned block_size, unsigned mac_size);
 char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx);
 int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx,
                            unsigned char *md_out,
                            size_t *md_out_size,
                            const unsigned char header[13],
                            const unsigned char *data,
                            size_t data_plus_mac_size,
                            size_t data_plus_mac_plus_padding_size,
                            const unsigned char *mac_secret,
                            unsigned mac_secret_length, char is_sslv3);
 
 void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx,
                            EVP_MD_CTX *mac_ctx, const unsigned char *data,
                            size_t data_len, size_t orig_len);
 
 int srp_verify_server_param(SSL *s, int *al);
 
 # else
 
 #  define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer
 #  define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers
 #  define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat
 #  define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat
 
 # endif
 #endif
Index: vendor-crypto/openssl/dist-1.0.1/ssl/ssl_sess.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/ssl_sess.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/ssl_sess.c	(revision 306191)
@@ -1,1302 +1,1302 @@
 /* ssl/ssl_sess.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-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
  *    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 2005 Nokia. All rights reserved.
  *
  * The portions of the attached software ("Contribution") is developed by
  * Nokia Corporation and is licensed pursuant to the OpenSSL open source
  * license.
  *
  * The Contribution, originally written by Mika Kousa and Pasi Eronen of
  * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites
  * support (see RFC 4279) to OpenSSL.
  *
  * No patent licenses or other rights except those expressly stated in
  * the OpenSSL open source license shall be deemed granted or received
  * expressly, by implication, estoppel, or otherwise.
  *
  * No assurances are provided by Nokia that the Contribution does not
  * infringe the patent or other intellectual property rights of any third
  * party or that the license provides you with all the necessary rights
  * to make use of the Contribution.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN
  * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA
  * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY
  * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
  * OTHERWISE.
  */
 
 #include <stdio.h>
 #include <openssl/lhash.h>
 #include <openssl/rand.h>
 #ifndef OPENSSL_NO_ENGINE
 # include <openssl/engine.h>
 #endif
 #include "ssl_locl.h"
 
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
 static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
 
 SSL_SESSION *SSL_get_session(const SSL *ssl)
 /* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */
 {
     return (ssl->session);
 }
 
 SSL_SESSION *SSL_get1_session(SSL *ssl)
 /* variant of SSL_get_session: caller really gets something */
 {
     SSL_SESSION *sess;
     /*
      * Need to lock this all up rather than just use CRYPTO_add so that
      * somebody doesn't free ssl->session between when we check it's non-null
      * and when we up the reference count.
      */
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION);
     sess = ssl->session;
     if (sess)
         sess->references++;
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION);
     return (sess);
 }
 
 int SSL_SESSION_get_ex_new_index(long argl, void *argp,
                                  CRYPTO_EX_new *new_func,
                                  CRYPTO_EX_dup *dup_func,
                                  CRYPTO_EX_free *free_func)
 {
     return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp,
                                    new_func, dup_func, free_func);
 }
 
 int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg)
 {
     return (CRYPTO_set_ex_data(&s->ex_data, idx, arg));
 }
 
 void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx)
 {
     return (CRYPTO_get_ex_data(&s->ex_data, idx));
 }
 
 SSL_SESSION *SSL_SESSION_new(void)
 {
     SSL_SESSION *ss;
 
     ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
     if (ss == NULL) {
         SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE);
         return (0);
     }
     memset(ss, 0, sizeof(SSL_SESSION));
 
     ss->verify_result = 1;      /* avoid 0 (= X509_V_OK) just in case */
     ss->references = 1;
     ss->timeout = 60 * 5 + 4;   /* 5 minute timeout by default */
     ss->time = (unsigned long)time(NULL);
     ss->prev = NULL;
     ss->next = NULL;
     ss->compress_meth = 0;
 #ifndef OPENSSL_NO_TLSEXT
     ss->tlsext_hostname = NULL;
 # ifndef OPENSSL_NO_EC
     ss->tlsext_ecpointformatlist_length = 0;
     ss->tlsext_ecpointformatlist = NULL;
     ss->tlsext_ellipticcurvelist_length = 0;
     ss->tlsext_ellipticcurvelist = NULL;
 # endif
 #endif
     CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
 #ifndef OPENSSL_NO_PSK
     ss->psk_identity_hint = NULL;
     ss->psk_identity = NULL;
 #endif
 #ifndef OPENSSL_NO_SRP
     ss->srp_username = NULL;
 #endif
     return (ss);
 }
 
 /*
  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
  * ticket == 0 then no ticket information is duplicated, otherwise it is.
  */
 SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket)
 {
     SSL_SESSION *dest;
 
     dest = OPENSSL_malloc(sizeof(*src));
     if (dest == NULL) {
         goto err;
     }
     memcpy(dest, src, sizeof(*dest));
 
     /*
      * Set the various pointers to NULL so that we can call SSL_SESSION_free in
      * the case of an error whilst halfway through constructing dest
      */
 #ifndef OPENSSL_NO_PSK
     dest->psk_identity_hint = NULL;
     dest->psk_identity = NULL;
 #endif
     dest->ciphers = NULL;
 #ifndef OPENSSL_NO_TLSEXT
     dest->tlsext_hostname = NULL;
 # ifndef OPENSSL_NO_EC
     dest->tlsext_ecpointformatlist = NULL;
     dest->tlsext_ellipticcurvelist = NULL;
 # endif
     dest->tlsext_tick = NULL;
 #endif
 #ifndef OPENSSL_NO_SRP
     dest->srp_username = NULL;
 #endif
     memset(&dest->ex_data, 0, sizeof(dest->ex_data));
 
     /* We deliberately don't copy the prev and next pointers */
     dest->prev = NULL;
     dest->next = NULL;
 
     dest->references = 1;
 
     if (src->sess_cert != NULL)
         CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT);
 
     if (src->peer != NULL)
         CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509);
 
 #ifndef OPENSSL_NO_PSK
     if (src->psk_identity_hint) {
         dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint);
         if (dest->psk_identity_hint == NULL) {
             goto err;
         }
     }
     if (src->psk_identity) {
         dest->psk_identity = BUF_strdup(src->psk_identity);
         if (dest->psk_identity == NULL) {
             goto err;
         }
     }
 #endif
 
     if(src->ciphers != NULL) {
         dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers);
         if (dest->ciphers == NULL)
             goto err;
     }
 
     if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION,
                                             &dest->ex_data, &src->ex_data)) {
         goto err;
     }
 
 #ifndef OPENSSL_NO_TLSEXT
     if (src->tlsext_hostname) {
         dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname);
         if (dest->tlsext_hostname == NULL) {
             goto err;
         }
     }
 # ifndef OPENSSL_NO_EC
     if (src->tlsext_ecpointformatlist) {
         dest->tlsext_ecpointformatlist =
             BUF_memdup(src->tlsext_ecpointformatlist,
                        src->tlsext_ecpointformatlist_length);
         if (dest->tlsext_ecpointformatlist == NULL)
             goto err;
     }
     if (src->tlsext_ellipticcurvelist) {
         dest->tlsext_ellipticcurvelist =
             BUF_memdup(src->tlsext_ellipticcurvelist,
                        src->tlsext_ellipticcurvelist_length);
         if (dest->tlsext_ellipticcurvelist == NULL)
             goto err;
     }
 # endif
 
     if (ticket != 0) {
         dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen);
         if(dest->tlsext_tick == NULL)
             goto err;
     } else {
         dest->tlsext_tick_lifetime_hint = 0;
         dest->tlsext_ticklen = 0;
     }
 #endif
 
 #ifndef OPENSSL_NO_SRP
     if (src->srp_username) {
         dest->srp_username = BUF_strdup(src->srp_username);
         if (dest->srp_username == NULL) {
             goto err;
         }
     }
 #endif
 
     return dest;
 err:
     SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE);
     SSL_SESSION_free(dest);
     return NULL;
 }
 
 const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s,
                                         unsigned int *len)
 {
     if (len)
         *len = s->session_id_length;
     return s->session_id;
 }
 
 unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s)
 {
     return s->compress_meth;
 }
 
 /*
  * Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
  * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random
  * gunk repeatedly until we have no conflict is going to complete in one
  * iteration pretty much "most" of the time (btw: understatement). So, if it
  * takes us 10 iterations and we still can't avoid a conflict - well that's a
  * reasonable point to call it quits. Either the RAND code is broken or
  * someone is trying to open roughly very close to 2^128 (or 2^256) SSL
  * sessions to our server. How you might store that many sessions is perhaps
  * a more interesting question ...
  */
 
 #define MAX_SESS_ID_ATTEMPTS 10
 static int def_generate_session_id(const SSL *ssl, unsigned char *id,
                                    unsigned int *id_len)
 {
     unsigned int retry = 0;
     do
-        if (RAND_pseudo_bytes(id, *id_len) <= 0)
+        if (RAND_bytes(id, *id_len) <= 0)
             return 0;
     while (SSL_has_matching_session_id(ssl, id, *id_len) &&
            (++retry < MAX_SESS_ID_ATTEMPTS)) ;
     if (retry < MAX_SESS_ID_ATTEMPTS)
         return 1;
     /* else - woops a session_id match */
     /*
      * XXX We should also check the external cache -- but the probability of
      * a collision is negligible, and we could not prevent the concurrent
      * creation of sessions with identical IDs since we currently don't have
      * means to atomically check whether a session ID already exists and make
      * a reservation for it if it does not (this problem applies to the
      * internal cache as well).
      */
     return 0;
 }
 
 int ssl_get_new_session(SSL *s, int session)
 {
     /* This gets used by clients and servers. */
 
     unsigned int tmp;
     SSL_SESSION *ss = NULL;
     GEN_SESSION_CB cb = def_generate_session_id;
 
     if ((ss = SSL_SESSION_new()) == NULL)
         return (0);
 
     /* If the context has a default timeout, use it */
     if (s->session_ctx->session_timeout == 0)
         ss->timeout = SSL_get_default_timeout(s);
     else
         ss->timeout = s->session_ctx->session_timeout;
 
     if (s->session != NULL) {
         SSL_SESSION_free(s->session);
         s->session = NULL;
     }
 
     if (session) {
         if (s->version == SSL2_VERSION) {
             ss->ssl_version = SSL2_VERSION;
             ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH;
         } else if (s->version == SSL3_VERSION) {
             ss->ssl_version = SSL3_VERSION;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else if (s->version == TLS1_VERSION) {
             ss->ssl_version = TLS1_VERSION;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else if (s->version == TLS1_1_VERSION) {
             ss->ssl_version = TLS1_1_VERSION;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else if (s->version == TLS1_2_VERSION) {
             ss->ssl_version = TLS1_2_VERSION;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else if (s->version == DTLS1_BAD_VER) {
             ss->ssl_version = DTLS1_BAD_VER;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else if (s->version == DTLS1_VERSION) {
             ss->ssl_version = DTLS1_VERSION;
             ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
         } else {
             SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION);
             SSL_SESSION_free(ss);
             return (0);
         }
 #ifndef OPENSSL_NO_TLSEXT
         /*-
          * If RFC5077 ticket, use empty session ID (as server).
          * Note that:
          * (a) ssl_get_prev_session() does lookahead into the
          *     ClientHello extensions to find the session ticket.
          *     When ssl_get_prev_session() fails, s3_srvr.c calls
          *     ssl_get_new_session() in ssl3_get_client_hello().
          *     At that point, it has not yet parsed the extensions,
          *     however, because of the lookahead, it already knows
          *     whether a ticket is expected or not.
          *
          * (b) s3_clnt.c calls ssl_get_new_session() before parsing
          *     ServerHello extensions, and before recording the session
          *     ID received from the server, so this block is a noop.
          */
         if (s->tlsext_ticket_expected) {
             ss->session_id_length = 0;
             goto sess_id_done;
         }
 #endif
         /* Choose which callback will set the session ID */
         CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
         if (s->generate_session_id)
             cb = s->generate_session_id;
         else if (s->session_ctx->generate_session_id)
             cb = s->session_ctx->generate_session_id;
         CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
         /* Choose a session ID */
         tmp = ss->session_id_length;
         if (!cb(s, ss->session_id, &tmp)) {
             /* The callback failed */
             SSLerr(SSL_F_SSL_GET_NEW_SESSION,
                    SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
             SSL_SESSION_free(ss);
             return (0);
         }
         /*
          * Don't allow the callback to set the session length to zero. nor
          * set it higher than it was.
          */
         if (!tmp || (tmp > ss->session_id_length)) {
             /* The callback set an illegal length */
             SSLerr(SSL_F_SSL_GET_NEW_SESSION,
                    SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
             SSL_SESSION_free(ss);
             return (0);
         }
         /* If the session length was shrunk and we're SSLv2, pad it */
         if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION))
             memset(ss->session_id + tmp, 0, ss->session_id_length - tmp);
         else
             ss->session_id_length = tmp;
         /* Finally, check for a conflict */
         if (SSL_has_matching_session_id(s, ss->session_id,
                                         ss->session_id_length)) {
             SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT);
             SSL_SESSION_free(ss);
             return (0);
         }
 #ifndef OPENSSL_NO_TLSEXT
  sess_id_done:
         if (s->tlsext_hostname) {
             ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
             if (ss->tlsext_hostname == NULL) {
                 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
                 SSL_SESSION_free(ss);
                 return 0;
             }
         }
 # ifndef OPENSSL_NO_EC
         if (s->tlsext_ecpointformatlist) {
             if (ss->tlsext_ecpointformatlist != NULL)
                 OPENSSL_free(ss->tlsext_ecpointformatlist);
             if ((ss->tlsext_ecpointformatlist =
                  OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) ==
                 NULL) {
                 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
                 SSL_SESSION_free(ss);
                 return 0;
             }
             ss->tlsext_ecpointformatlist_length =
                 s->tlsext_ecpointformatlist_length;
             memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist,
                    s->tlsext_ecpointformatlist_length);
         }
         if (s->tlsext_ellipticcurvelist) {
             if (ss->tlsext_ellipticcurvelist != NULL)
                 OPENSSL_free(ss->tlsext_ellipticcurvelist);
             if ((ss->tlsext_ellipticcurvelist =
                  OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) ==
                 NULL) {
                 SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE);
                 SSL_SESSION_free(ss);
                 return 0;
             }
             ss->tlsext_ellipticcurvelist_length =
                 s->tlsext_ellipticcurvelist_length;
             memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist,
                    s->tlsext_ellipticcurvelist_length);
         }
 # endif
 #endif
     } else {
         ss->session_id_length = 0;
     }
 
     if (s->sid_ctx_length > sizeof ss->sid_ctx) {
         SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR);
         SSL_SESSION_free(ss);
         return 0;
     }
     memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length);
     ss->sid_ctx_length = s->sid_ctx_length;
     s->session = ss;
     ss->ssl_version = s->version;
     ss->verify_result = X509_V_OK;
 
     return (1);
 }
 
 /*-
  * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
  * connection. It is only called by servers.
  *
  *   session_id: points at the session ID in the ClientHello. This code will
  *       read past the end of this in order to parse out the session ticket
  *       extension, if any.
  *   len: the length of the session ID.
  *   limit: a pointer to the first byte after the ClientHello.
  *
  * Returns:
  *   -1: error
  *    0: a session may have been found.
  *
  * Side effects:
  *   - If a session is found then s->session is pointed at it (after freeing an
  *     existing session if need be) and s->verify_result is set from the session.
  *   - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
  *     if the server should issue a new session ticket (to 0 otherwise).
  */
 int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
                          const unsigned char *limit)
 {
     /* This is used only by servers. */
 
     SSL_SESSION *ret = NULL;
     int fatal = 0;
     int try_session_cache = 1;
 #ifndef OPENSSL_NO_TLSEXT
     int r;
 #endif
 
-    if (session_id + len > limit) {
+    if (limit - session_id < len) {
         fatal = 1;
         goto err;
     }
 
     if (len == 0)
         try_session_cache = 0;
 
 #ifndef OPENSSL_NO_TLSEXT
     /* sets s->tlsext_ticket_expected */
     r = tls1_process_ticket(s, session_id, len, limit, &ret);
     switch (r) {
     case -1:                   /* Error during processing */
         fatal = 1;
         goto err;
     case 0:                    /* No ticket found */
     case 1:                    /* Zero length ticket found */
         break;                  /* Ok to carry on processing session id. */
     case 2:                    /* Ticket found but not decrypted. */
     case 3:                    /* Ticket decrypted, *ret has been set. */
         try_session_cache = 0;
         break;
     default:
         abort();
     }
 #endif
 
     if (try_session_cache &&
         ret == NULL &&
         !(s->session_ctx->session_cache_mode &
           SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
         SSL_SESSION data;
         data.ssl_version = s->version;
         data.session_id_length = len;
         if (len == 0)
             return 0;
         memcpy(data.session_id, session_id, len);
         CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX);
         ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);
         if (ret != NULL) {
             /* don't allow other threads to steal it: */
             CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION);
         }
         CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX);
         if (ret == NULL)
             s->session_ctx->stats.sess_miss++;
     }
 
     if (try_session_cache &&
         ret == NULL && s->session_ctx->get_session_cb != NULL) {
         int copy = 1;
 
         if ((ret = s->session_ctx->get_session_cb(s, session_id, len, &copy))) {
             s->session_ctx->stats.sess_cb_hit++;
 
             /*
              * Increment reference count now if the session callback asks us
              * to do so (note that if the session structures returned by the
              * callback are shared between threads, it must handle the
              * reference count itself [i.e. copy == 0], or things won't be
              * thread-safe).
              */
             if (copy)
                 CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION);
 
             /*
              * Add the externally cached session to the internal cache as
              * well if and only if we are supposed to.
              */
             if (!
                 (s->session_ctx->session_cache_mode &
                  SSL_SESS_CACHE_NO_INTERNAL_STORE))
                 /*
                  * The following should not return 1, otherwise, things are
                  * very strange
                  */
                 SSL_CTX_add_session(s->session_ctx, ret);
         }
     }
 
     if (ret == NULL)
         goto err;
 
     /* Now ret is non-NULL and we own one of its reference counts. */
 
     if (ret->sid_ctx_length != s->sid_ctx_length
         || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
         /*
          * We have the session requested by the client, but we don't want to
          * use it in this context.
          */
         goto err;               /* treat like cache miss */
     }
 
     if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
         /*
          * We can't be sure if this session is being used out of context,
          * which is especially important for SSL_VERIFY_PEER. The application
          * should have used SSL[_CTX]_set_session_id_context. For this error
          * case, we generate an error instead of treating the event like a
          * cache miss (otherwise it would be easy for applications to
          * effectively disable the session cache by accident without anyone
          * noticing).
          */
 
         SSLerr(SSL_F_SSL_GET_PREV_SESSION,
                SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
         fatal = 1;
         goto err;
     }
 
     if (ret->cipher == NULL) {
         unsigned char buf[5], *p;
         unsigned long l;
 
         p = buf;
         l = ret->cipher_id;
         l2n(l, p);
         if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR)
             ret->cipher = ssl_get_cipher_by_char(s, &(buf[2]));
         else
             ret->cipher = ssl_get_cipher_by_char(s, &(buf[1]));
         if (ret->cipher == NULL)
             goto err;
     }
 
     if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */
         s->session_ctx->stats.sess_timeout++;
         if (try_session_cache) {
             /* session was from the cache, so remove it */
             SSL_CTX_remove_session(s->session_ctx, ret);
         }
         goto err;
     }
 
     s->session_ctx->stats.sess_hit++;
 
     if (s->session != NULL)
         SSL_SESSION_free(s->session);
     s->session = ret;
     s->verify_result = s->session->verify_result;
     return 1;
 
  err:
     if (ret != NULL) {
         SSL_SESSION_free(ret);
 #ifndef OPENSSL_NO_TLSEXT
         if (!try_session_cache) {
             /*
              * The session was from a ticket, so we should issue a ticket for
              * the new session
              */
             s->tlsext_ticket_expected = 1;
         }
 #endif
     }
     if (fatal)
         return -1;
     else
         return 0;
 }
 
 int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
 {
     int ret = 0;
     SSL_SESSION *s;
 
     /*
      * add just 1 reference count for the SSL_CTX's session cache even though
      * it has two ways of access: each session is in a doubly linked list and
      * an lhash
      */
     CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION);
     /*
      * if session c is in already in cache, we take back the increment later
      */
 
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
     s = lh_SSL_SESSION_insert(ctx->sessions, c);
 
     /*
      * s != NULL iff we already had a session with the given PID. In this
      * case, s == c should hold (then we did not really modify
      * ctx->sessions), or we're in trouble.
      */
     if (s != NULL && s != c) {
         /* We *are* in trouble ... */
         SSL_SESSION_list_remove(ctx, s);
         SSL_SESSION_free(s);
         /*
          * ... so pretend the other session did not exist in cache (we cannot
          * handle two SSL_SESSION structures with identical session ID in the
          * same cache, which could happen e.g. when two threads concurrently
          * obtain the same session from an external cache)
          */
         s = NULL;
     }
 
     /* Put at the head of the queue unless it is already in the cache */
     if (s == NULL)
         SSL_SESSION_list_add(ctx, c);
 
     if (s != NULL) {
         /*
          * existing cache entry -- decrement previously incremented reference
          * count because it already takes into account the cache
          */
 
         SSL_SESSION_free(s);    /* s == c */
         ret = 0;
     } else {
         /*
          * new cache entry -- remove old ones if cache has become too large
          */
 
         ret = 1;
 
         if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
             while (SSL_CTX_sess_number(ctx) >
                    SSL_CTX_sess_get_cache_size(ctx)) {
                 if (!remove_session_lock(ctx, ctx->session_cache_tail, 0))
                     break;
                 else
                     ctx->stats.sess_cache_full++;
             }
         }
     }
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
     return (ret);
 }
 
 int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c)
 {
     return remove_session_lock(ctx, c, 1);
 }
 
 static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck)
 {
     SSL_SESSION *r;
     int ret = 0;
 
     if ((c != NULL) && (c->session_id_length != 0)) {
         if (lck)
             CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
         if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) {
             ret = 1;
             r = lh_SSL_SESSION_delete(ctx->sessions, c);
             SSL_SESSION_list_remove(ctx, c);
         }
 
         if (lck)
             CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
 
         if (ret) {
             r->not_resumable = 1;
             if (ctx->remove_session_cb != NULL)
                 ctx->remove_session_cb(ctx, r);
             SSL_SESSION_free(r);
         }
     } else
         ret = 0;
     return (ret);
 }
 
 void SSL_SESSION_free(SSL_SESSION *ss)
 {
     int i;
 
     if (ss == NULL)
         return;
 
     i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION);
 #ifdef REF_PRINT
     REF_PRINT("SSL_SESSION", ss);
 #endif
     if (i > 0)
         return;
 #ifdef REF_CHECK
     if (i < 0) {
         fprintf(stderr, "SSL_SESSION_free, bad reference count\n");
         abort();                /* ok */
     }
 #endif
 
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data);
 
     OPENSSL_cleanse(ss->key_arg, sizeof ss->key_arg);
     OPENSSL_cleanse(ss->master_key, sizeof ss->master_key);
     OPENSSL_cleanse(ss->session_id, sizeof ss->session_id);
     if (ss->sess_cert != NULL)
         ssl_sess_cert_free(ss->sess_cert);
     if (ss->peer != NULL)
         X509_free(ss->peer);
     if (ss->ciphers != NULL)
         sk_SSL_CIPHER_free(ss->ciphers);
 #ifndef OPENSSL_NO_TLSEXT
     if (ss->tlsext_hostname != NULL)
         OPENSSL_free(ss->tlsext_hostname);
     if (ss->tlsext_tick != NULL)
         OPENSSL_free(ss->tlsext_tick);
 # ifndef OPENSSL_NO_EC
     ss->tlsext_ecpointformatlist_length = 0;
     if (ss->tlsext_ecpointformatlist != NULL)
         OPENSSL_free(ss->tlsext_ecpointformatlist);
     ss->tlsext_ellipticcurvelist_length = 0;
     if (ss->tlsext_ellipticcurvelist != NULL)
         OPENSSL_free(ss->tlsext_ellipticcurvelist);
 # endif                         /* OPENSSL_NO_EC */
 #endif
 #ifndef OPENSSL_NO_PSK
     if (ss->psk_identity_hint != NULL)
         OPENSSL_free(ss->psk_identity_hint);
     if (ss->psk_identity != NULL)
         OPENSSL_free(ss->psk_identity);
 #endif
 #ifndef OPENSSL_NO_SRP
     if (ss->srp_username != NULL)
         OPENSSL_free(ss->srp_username);
 #endif
     OPENSSL_cleanse(ss, sizeof(*ss));
     OPENSSL_free(ss);
 }
 
 int SSL_set_session(SSL *s, SSL_SESSION *session)
 {
     int ret = 0;
     const SSL_METHOD *meth;
 
     if (session != NULL) {
         meth = s->ctx->method->get_ssl_method(session->ssl_version);
         if (meth == NULL)
             meth = s->method->get_ssl_method(session->ssl_version);
         if (meth == NULL) {
             SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD);
             return (0);
         }
 
         if (meth != s->method) {
             if (!SSL_set_ssl_method(s, meth))
                 return (0);
         }
 #ifndef OPENSSL_NO_KRB5
         if (s->kssl_ctx && !s->kssl_ctx->client_princ &&
             session->krb5_client_princ_len > 0) {
             s->kssl_ctx->client_princ =
                 (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
             memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ,
                    session->krb5_client_princ_len);
             s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
         }
 #endif                          /* OPENSSL_NO_KRB5 */
 
         /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */
         CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION);
         if (s->session != NULL)
             SSL_SESSION_free(s->session);
         s->session = session;
         s->verify_result = s->session->verify_result;
         /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */
         ret = 1;
     } else {
         if (s->session != NULL) {
             SSL_SESSION_free(s->session);
             s->session = NULL;
         }
 
         meth = s->ctx->method;
         if (meth != s->method) {
             if (!SSL_set_ssl_method(s, meth))
                 return (0);
         }
         ret = 1;
     }
     return (ret);
 }
 
 long SSL_SESSION_set_timeout(SSL_SESSION *s, long t)
 {
     if (s == NULL)
         return (0);
     s->timeout = t;
     return (1);
 }
 
 long SSL_SESSION_get_timeout(const SSL_SESSION *s)
 {
     if (s == NULL)
         return (0);
     return (s->timeout);
 }
 
 long SSL_SESSION_get_time(const SSL_SESSION *s)
 {
     if (s == NULL)
         return (0);
     return (s->time);
 }
 
 long SSL_SESSION_set_time(SSL_SESSION *s, long t)
 {
     if (s == NULL)
         return (0);
     s->time = t;
     return (t);
 }
 
 X509 *SSL_SESSION_get0_peer(SSL_SESSION *s)
 {
     return s->peer;
 }
 
 int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
                                 unsigned int sid_ctx_len)
 {
     if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
         SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT,
                SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
         return 0;
     }
     s->sid_ctx_length = sid_ctx_len;
     memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
 
     return 1;
 }
 
 long SSL_CTX_set_timeout(SSL_CTX *s, long t)
 {
     long l;
     if (s == NULL)
         return (0);
     l = s->session_timeout;
     s->session_timeout = t;
     return (l);
 }
 
 long SSL_CTX_get_timeout(const SSL_CTX *s)
 {
     if (s == NULL)
         return (0);
     return (s->session_timeout);
 }
 
 #ifndef OPENSSL_NO_TLSEXT
 int SSL_set_session_secret_cb(SSL *s,
                               int (*tls_session_secret_cb) (SSL *s,
                                                             void *secret,
                                                             int *secret_len,
                                                             STACK_OF(SSL_CIPHER)
                                                             *peer_ciphers,
                                                             SSL_CIPHER
                                                             **cipher,
                                                             void *arg),
                               void *arg)
 {
     if (s == NULL)
         return (0);
     s->tls_session_secret_cb = tls_session_secret_cb;
     s->tls_session_secret_cb_arg = arg;
     return (1);
 }
 
 int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb,
                                   void *arg)
 {
     if (s == NULL)
         return (0);
     s->tls_session_ticket_ext_cb = cb;
     s->tls_session_ticket_ext_cb_arg = arg;
     return (1);
 }
 
 int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len)
 {
     if (s->version >= TLS1_VERSION) {
         if (s->tlsext_session_ticket) {
             OPENSSL_free(s->tlsext_session_ticket);
             s->tlsext_session_ticket = NULL;
         }
 
         s->tlsext_session_ticket =
             OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len);
         if (!s->tlsext_session_ticket) {
             SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE);
             return 0;
         }
 
         if (ext_data) {
             s->tlsext_session_ticket->length = ext_len;
             s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1;
             memcpy(s->tlsext_session_ticket->data, ext_data, ext_len);
         } else {
             s->tlsext_session_ticket->length = 0;
             s->tlsext_session_ticket->data = NULL;
         }
 
         return 1;
     }
 
     return 0;
 }
 #endif                          /* OPENSSL_NO_TLSEXT */
 
 typedef struct timeout_param_st {
     SSL_CTX *ctx;
     long time;
     LHASH_OF(SSL_SESSION) *cache;
 } TIMEOUT_PARAM;
 
 static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p)
 {
     if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */
         /*
          * The reason we don't call SSL_CTX_remove_session() is to save on
          * locking overhead
          */
         (void)lh_SSL_SESSION_delete(p->cache, s);
         SSL_SESSION_list_remove(p->ctx, s);
         s->not_resumable = 1;
         if (p->ctx->remove_session_cb != NULL)
             p->ctx->remove_session_cb(p->ctx, s);
         SSL_SESSION_free(s);
     }
 }
 
 static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM)
 
 void SSL_CTX_flush_sessions(SSL_CTX *s, long t)
 {
     unsigned long i;
     TIMEOUT_PARAM tp;
 
     tp.ctx = s;
     tp.cache = s->sessions;
     if (tp.cache == NULL)
         return;
     tp.time = t;
     CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
     i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load;
     CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0;
     lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout),
                              TIMEOUT_PARAM, &tp);
     CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i;
     CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
 }
 
 int ssl_clear_bad_session(SSL *s)
 {
     if ((s->session != NULL) &&
         !(s->shutdown & SSL_SENT_SHUTDOWN) &&
         !(SSL_in_init(s) || SSL_in_before(s))) {
         SSL_CTX_remove_session(s->ctx, s->session);
         return (1);
     } else
         return (0);
 }
 
 /* locked by SSL_CTX in the calling function */
 static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s)
 {
     if ((s->next == NULL) || (s->prev == NULL))
         return;
 
     if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) {
         /* last element in list */
         if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
             /* only one element in list */
             ctx->session_cache_head = NULL;
             ctx->session_cache_tail = NULL;
         } else {
             ctx->session_cache_tail = s->prev;
             s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
         }
     } else {
         if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) {
             /* first element in list */
             ctx->session_cache_head = s->next;
             s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
         } else {
             /* middle of list */
             s->next->prev = s->prev;
             s->prev->next = s->next;
         }
     }
     s->prev = s->next = NULL;
 }
 
 static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s)
 {
     if ((s->next != NULL) && (s->prev != NULL))
         SSL_SESSION_list_remove(ctx, s);
 
     if (ctx->session_cache_head == NULL) {
         ctx->session_cache_head = s;
         ctx->session_cache_tail = s;
         s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
         s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
     } else {
         s->next = ctx->session_cache_head;
         s->next->prev = s;
         s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
         ctx->session_cache_head = s;
     }
 }
 
 void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
                              int (*cb) (struct ssl_st *ssl,
                                         SSL_SESSION *sess))
 {
     ctx->new_session_cb = cb;
 }
 
 int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) {
     return ctx->new_session_cb;
 }
 
 void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
                                 void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess))
 {
     ctx->remove_session_cb = cb;
 }
 
 void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx,
                                                   SSL_SESSION *sess) {
     return ctx->remove_session_cb;
 }
 
 void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
                              SSL_SESSION *(*cb) (struct ssl_st *ssl,
                                                  unsigned char *data, int len,
                                                  int *copy))
 {
     ctx->get_session_cb = cb;
 }
 
 SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl,
                                                        unsigned char *data,
                                                        int len, int *copy) {
     return ctx->get_session_cb;
 }
 
 void SSL_CTX_set_info_callback(SSL_CTX *ctx,
                                void (*cb) (const SSL *ssl, int type, int val))
 {
     ctx->info_callback = cb;
 }
 
 void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type,
                                                  int val) {
     return ctx->info_callback;
 }
 
 void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx,
                                 int (*cb) (SSL *ssl, X509 **x509,
                                            EVP_PKEY **pkey))
 {
     ctx->client_cert_cb = cb;
 }
 
 int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509,
                                                  EVP_PKEY **pkey) {
     return ctx->client_cert_cb;
 }
 
 #ifndef OPENSSL_NO_ENGINE
 int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e)
 {
     if (!ENGINE_init(e)) {
         SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB);
         return 0;
     }
     if (!ENGINE_get_ssl_client_cert_function(e)) {
         SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE,
                SSL_R_NO_CLIENT_CERT_METHOD);
         ENGINE_finish(e);
         return 0;
     }
     ctx->client_cert_engine = e;
     return 1;
 }
 #endif
 
 void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx,
                                     int (*cb) (SSL *ssl,
                                                unsigned char *cookie,
                                                unsigned int *cookie_len))
 {
     ctx->app_gen_cookie_cb = cb;
 }
 
 void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx,
                                   int (*cb) (SSL *ssl, unsigned char *cookie,
                                              unsigned int cookie_len))
 {
     ctx->app_verify_cookie_cb = cb;
 }
 
 IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION,
                  SSL_SESSION)
Index: vendor-crypto/openssl/dist-1.0.1/ssl/t1_lib.c
===================================================================
--- vendor-crypto/openssl/dist-1.0.1/ssl/t1_lib.c	(revision 306190)
+++ vendor-crypto/openssl/dist-1.0.1/ssl/t1_lib.c	(revision 306191)
@@ -1,2706 +1,2725 @@
 /* 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 <openssl/rand.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,
     tls1_export_keying_material,
 };
 
 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 = s->method->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) */
 };
 
 static int pref_list[] = {
 # ifndef OPENSSL_NO_EC2M
     NID_sect571r1,              /* sect571r1 (14) */
     NID_sect571k1,              /* sect571k1 (13) */
 # endif
     NID_secp521r1,              /* secp521r1 (25) */
 # ifndef OPENSSL_NO_EC2M
     NID_sect409k1,              /* sect409k1 (11) */
     NID_sect409r1,              /* sect409r1 (12) */
 # endif
     NID_secp384r1,              /* secp384r1 (24) */
 # ifndef OPENSSL_NO_EC2M
     NID_sect283k1,              /* sect283k1 (9) */
     NID_sect283r1,              /* sect283r1 (10) */
 # endif
     NID_secp256k1,              /* secp256k1 (22) */
     NID_X9_62_prime256v1,       /* secp256r1 (23) */
 # ifndef OPENSSL_NO_EC2M
     NID_sect239k1,              /* sect239k1 (8) */
     NID_sect233k1,              /* sect233k1 (6) */
     NID_sect233r1,              /* sect233r1 (7) */
 # endif
     NID_secp224k1,              /* secp224k1 (20) */
     NID_secp224r1,              /* secp224r1 (21) */
 # ifndef OPENSSL_NO_EC2M
     NID_sect193r1,              /* sect193r1 (4) */
     NID_sect193r2,              /* sect193r2 (5) */
 # endif
     NID_secp192k1,              /* secp192k1 (18) */
     NID_X9_62_prime192v1,       /* secp192r1 (19) */
 # ifndef OPENSSL_NO_EC2M
     NID_sect163k1,              /* sect163k1 (1) */
     NID_sect163r1,              /* sect163r1 (2) */
     NID_sect163r2,              /* sect163r2 (3) */
 # endif
     NID_secp160k1,              /* secp160k1 (15) */
     NID_secp160r1,              /* secp160r1 (16) */
     NID_secp160r2,              /* secp160r2 (17) */
 };
 
 int tls1_ec_curve_id2nid(int curve_id)
 {
     /* ECC curves from RFC 4492 */
     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 RFC 4492 */
     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
 
 /*
  * List of supported signature algorithms and hashes. Should make this
  * customisable at some point, for now include everything we support.
  */
 
 # ifdef OPENSSL_NO_RSA
 #  define tlsext_sigalg_rsa(md) /* */
 # else
 #  define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa,
 # endif
 
 # ifdef OPENSSL_NO_DSA
 #  define tlsext_sigalg_dsa(md) /* */
 # else
 #  define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa,
 # endif
 
 # ifdef OPENSSL_NO_ECDSA
 #  define tlsext_sigalg_ecdsa(md)
                                 /* */
 # else
 #  define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa,
 # endif
 
 # define tlsext_sigalg(md) \
                 tlsext_sigalg_rsa(md) \
                 tlsext_sigalg_dsa(md) \
                 tlsext_sigalg_ecdsa(md)
 
 static unsigned char tls12_sigalgs[] = {
 # ifndef OPENSSL_NO_SHA512
     tlsext_sigalg(TLSEXT_hash_sha512)
         tlsext_sigalg(TLSEXT_hash_sha384)
 # endif
 # ifndef OPENSSL_NO_SHA256
         tlsext_sigalg(TLSEXT_hash_sha256)
         tlsext_sigalg(TLSEXT_hash_sha224)
 # endif
 # ifndef OPENSSL_NO_SHA
         tlsext_sigalg(TLSEXT_hash_sha1)
 # endif
 };
 
 int tls12_get_req_sig_algs(SSL *s, unsigned char *p)
 {
     size_t slen = sizeof(tls12_sigalgs);
     if (p)
         memcpy(p, tls12_sigalgs, slen);
     return (int)slen;
 }
 
 unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
                                           unsigned char *limit)
 {
     int extdatalen = 0;
     unsigned char *orig = buf;
     unsigned char *ret = buf;
 
     /* don't add extensions for SSLv3 unless doing secure renegotiation */
     if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding)
         return orig;
 
     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->renegotiate) {
         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 - ret - 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_SRP
     /* Add SRP username if there is one */
     if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
                                      * Client Hello message */
 
         int login_len = strlen(s->srp_ctx.login);
         if (login_len > 255 || login_len == 0) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
 
         /*-
          * check for enough space.
          * 4 for the srp type type and entension length
          * 1 for the srp user identity
          * + srp user identity length
          */
         if ((limit - ret - 5 - login_len) < 0)
             return NULL;
 
         /* fill in the extension */
         s2n(TLSEXT_TYPE_srp, ret);
         s2n(login_len + 1, ret);
         (*ret++) = (unsigned char)login_len;
         memcpy(ret, s->srp_ctx.login, login_len);
         ret += login_len;
     }
 # endif
 
 # ifndef OPENSSL_NO_EC
     if (s->tlsext_ecpointformatlist != NULL) {
         /*
          * 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) {
         /*
          * 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);
 
         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:
 
     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
         if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6)
             return NULL;
         s2n(TLSEXT_TYPE_signature_algorithms, ret);
         s2n(sizeof(tls12_sigalgs) + 2, ret);
         s2n(sizeof(tls12_sigalgs), ret);
         memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs));
         ret += sizeof(tls12_sigalgs);
     }
 # 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);
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension */
     if ((limit - ret - 4 - 1) < 0)
         return NULL;
     s2n(TLSEXT_TYPE_heartbeat, ret);
     s2n(1, ret);
     /*-
      * Set mode:
      * 1: peer may send requests
      * 2: peer not allowed to send requests
      */
     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
         *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
     else
         *(ret++) = SSL_TLSEXT_HB_ENABLED;
 # endif
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
     if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) {
         /*
          * The client advertises an emtpy extension to indicate its support
          * for Next Protocol Negotiation
          */
         if (limit - ret - 4 < 0)
             return NULL;
         s2n(TLSEXT_TYPE_next_proto_neg, ret);
         s2n(0, ret);
     }
 # endif
 
 # ifndef OPENSSL_NO_SRTP
     if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) {
         int el;
 
         ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
 
         if ((limit - ret - 4 - el) < 0)
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
         s2n(el, ret);
 
         if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
             SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
         ret += el;
     }
 # endif
     /*
      * Add padding to workaround bugs in F5 terminators. See
      * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this
      * code works out the length of all existing extensions it MUST always
      * appear last.
      */
     if (s->options & SSL_OP_TLSEXT_PADDING) {
         int hlen = ret - (unsigned char *)s->init_buf->data;
         /*
          * The code in s23_clnt.c to build ClientHello messages includes the
          * 5-byte record header in the buffer, while the code in s3_clnt.c
          * does not.
          */
         if (s->state == SSL23_ST_CW_CLNT_HELLO_A)
             hlen -= 5;
         if (hlen > 0xff && hlen < 0x200) {
             hlen = 0x200 - hlen;
             if (hlen >= 4)
                 hlen -= 4;
             else
                 hlen = 0;
 
             s2n(TLSEXT_TYPE_padding, ret);
             s2n(hlen, ret);
             memset(ret, 0, hlen);
             ret += hlen;
         }
     }
 
     if ((extdatalen = ret - orig - 2) == 0)
         return orig;
 
     s2n(extdatalen, orig);
     return ret;
 }
 
 unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
                                           unsigned char *limit)
 {
     int extdatalen = 0;
     unsigned char *orig = buf;
     unsigned char *ret = buf;
 # ifndef OPENSSL_NO_NEXTPROTONEG
     int next_proto_neg_seen;
 # endif
 
     /*
      * don't add extensions for SSLv3, unless doing secure renegotiation
      */
     if (s->version == SSL3_VERSION && !s->s3->send_connection_binding)
         return orig;
 
     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 - ret - 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) {
         /*
          * 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
 
 # ifndef OPENSSL_NO_SRTP
     if (SSL_IS_DTLS(s) && s->srtp_profile) {
         int el;
 
         ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
 
         if ((limit - ret - 4 - el) < 0)
             return NULL;
 
         s2n(TLSEXT_TYPE_use_srtp, ret);
         s2n(el, ret);
 
         if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
             SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
             return NULL;
         }
         ret += el;
     }
 # 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;
 
     }
 # ifndef OPENSSL_NO_HEARTBEATS
     /* Add Heartbeat extension if we've received one */
     if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
         if ((limit - ret - 4 - 1) < 0)
             return NULL;
         s2n(TLSEXT_TYPE_heartbeat, ret);
         s2n(1, ret);
         /*-
          * Set mode:
          * 1: peer may send requests
          * 2: peer not allowed to send requests
          */
         if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS)
             *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
         else
             *(ret++) = SSL_TLSEXT_HB_ENABLED;
 
     }
 # endif
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
     next_proto_neg_seen = s->s3->next_proto_neg_seen;
     s->s3->next_proto_neg_seen = 0;
     if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
         const unsigned char *npa;
         unsigned int npalen;
         int r;
 
         r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen,
                                               s->
                                               ctx->next_protos_advertised_cb_arg);
         if (r == SSL_TLSEXT_ERR_OK) {
             if ((long)(limit - ret - 4 - npalen) < 0)
                 return NULL;
             s2n(TLSEXT_TYPE_next_proto_neg, ret);
             s2n(npalen, ret);
             memcpy(ret, npa, npalen);
             ret += npalen;
             s->s3->next_proto_neg_seen = 1;
         }
     }
 # endif
 
     if ((extdatalen = ret - orig - 2) == 0)
         return orig;
 
     s2n(extdatalen, orig);
     return ret;
 }
 
 # ifndef OPENSSL_NO_EC
 /*-
  * ssl_check_for_safari attempts to fingerprint Safari using OS X
  * SecureTransport using the TLS extension block in |d|, of length |n|.
  * Safari, since 10.6, sends exactly these extensions, in this order:
  *   SNI,
  *   elliptic_curves
  *   ec_point_formats
  *
  * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8,
  * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them.
  * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from
  * 10.8..10.8.3 (which don't work).
  */
 static void ssl_check_for_safari(SSL *s, const unsigned char *data,
                                  const unsigned char *limit)
 {
     unsigned short type, size;
     static const unsigned char kSafariExtensionsBlock[] = {
         0x00, 0x0a,             /* elliptic_curves extension */
         0x00, 0x08,             /* 8 bytes */
         0x00, 0x06,             /* 6 bytes of curve ids */
         0x00, 0x17,             /* P-256 */
         0x00, 0x18,             /* P-384 */
         0x00, 0x19,             /* P-521 */
 
         0x00, 0x0b,             /* ec_point_formats */
         0x00, 0x02,             /* 2 bytes */
         0x01,                   /* 1 point format */
         0x00,                   /* uncompressed */
     };
 
     /* The following is only present in TLS 1.2 */
     static const unsigned char kSafariTLS12ExtensionsBlock[] = {
         0x00, 0x0d,             /* signature_algorithms */
         0x00, 0x0c,             /* 12 bytes */
         0x00, 0x0a,             /* 10 bytes */
         0x05, 0x01,             /* SHA-384/RSA */
         0x04, 0x01,             /* SHA-256/RSA */
         0x02, 0x01,             /* SHA-1/RSA */
         0x04, 0x03,             /* SHA-256/ECDSA */
         0x02, 0x03,             /* SHA-1/ECDSA */
     };
 
-    if (data >= (limit - 2))
+    if (limit - data <= 2)
         return;
     data += 2;
 
-    if (data > (limit - 4))
+    if (limit - data < 4)
         return;
     n2s(data, type);
     n2s(data, size);
 
     if (type != TLSEXT_TYPE_server_name)
         return;
 
-    if (data + size > limit)
+    if (limit - data < size)
         return;
     data += size;
 
     if (TLS1_get_client_version(s) >= TLS1_2_VERSION) {
         const size_t len1 = sizeof(kSafariExtensionsBlock);
         const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
 
-        if (data + len1 + len2 != limit)
+        if (limit - data != (int)(len1 + len2))
             return;
         if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
             return;
         if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0)
             return;
     } else {
         const size_t len = sizeof(kSafariExtensionsBlock);
 
-        if (data + len != limit)
+        if (limit - data != (int)(len))
             return;
         if (memcmp(data, kSafariExtensionsBlock, len) != 0)
             return;
     }
 
     s->s3->is_probably_safari = 1;
 }
 # endif                         /* !OPENSSL_NO_EC */
 
 int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
                                  unsigned char *limit, int *al)
 {
     unsigned short type;
     unsigned short size;
     unsigned short len;
     unsigned char *data = *p;
     int renegotiate_seen = 0;
     int sigalg_seen = 0;
 
     s->servername_done = 0;
     s->tlsext_status_type = -1;
 # ifndef OPENSSL_NO_NEXTPROTONEG
     s->s3->next_proto_neg_seen = 0;
 # endif
 
 # ifndef OPENSSL_NO_HEARTBEATS
     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
 # endif
 
 # ifndef OPENSSL_NO_EC
     if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG)
         ssl_check_for_safari(s, data, limit);
 # endif                         /* !OPENSSL_NO_EC */
 
 # ifndef OPENSSL_NO_SRP
     if (s->srp_ctx.login != NULL) {
         OPENSSL_free(s->srp_ctx.login);
         s->srp_ctx.login = NULL;
     }
 # endif
 
     s->srtp_profile = NULL;
 
     if (data == limit)
         goto ri_check;
 
-    if (data > (limit - 2))
+    if (limit - data < 2)
         goto err;
 
     n2s(data, len);
 
-    if (data + len != limit)
+    if (limit - data != len)
         goto err;
 
-    while (data <= (limit - 4)) {
+    while (limit - data >= 4) {
         n2s(data, type);
         n2s(data, size);
 
-        if (data + size > (limit))
+        if (limit - data < size)
             goto err;
 # 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)
                 goto err;
             n2s(data, dsize);
             size -= 2;
             if (dsize > size)
                 goto err;
 
             sdata = data;
             while (dsize > 3) {
                 servname_type = *(sdata++);
                 n2s(sdata, len);
                 dsize -= 3;
 
                 if (len > dsize)
                     goto err;
 
                 if (s->servername_done == 0)
                     switch (servname_type) {
                     case TLSEXT_NAMETYPE_host_name:
                         if (!s->hit) {
                             if (s->session->tlsext_hostname)
                                 goto err;
 
                             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)
                 goto err;
 
         }
 # ifndef OPENSSL_NO_SRP
         else if (type == TLSEXT_TYPE_srp) {
             if (size == 0 || ((len = data[0])) != (size - 1))
                 goto err;
             if (s->srp_ctx.login != NULL)
                 goto err;
             if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL)
                 return -1;
             memcpy(s->srp_ctx.login, &data[1], len);
             s->srp_ctx.login[len] = '\0';
 
             if (strlen(s->srp_ctx.login) != len)
                 goto err;
         }
 # endif
 
 # ifndef OPENSSL_NO_EC
         else if (type == TLSEXT_TYPE_ec_point_formats) {
             unsigned char *sdata = data;
             int ecpointformatlist_length = *(sdata++);
 
             if (ecpointformatlist_length != size - 1)
                 goto err;
             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) {
             unsigned char *sdata = data;
             int ellipticcurvelist_length = (*(sdata++) << 8);
             ellipticcurvelist_length += (*(sdata++));
 
             if (ellipticcurvelist_length != size - 2 ||
                 ellipticcurvelist_length < 1 ||
                 /* Each NamedCurve is 2 bytes. */
                 ellipticcurvelist_length & 1)
                     goto err;
 
             if (!s->hit) {
                 if (s->session->tlsext_ellipticcurvelist)
                     goto err;
 
                 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);
             }
 
             /* dummy byte just to get non-NULL */
             if (s->s3->client_opaque_prf_input_len == 0)
                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
             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_signature_algorithms) {
             int dsize;
             if (sigalg_seen || size < 2)
                 goto err;
             sigalg_seen = 1;
             n2s(data, dsize);
             size -= 2;
             if (dsize != size || dsize & 1)
                 goto err;
             if (!tls1_process_sigalgs(s, data, dsize))
                 goto err;
         } else if (type == TLSEXT_TYPE_status_request &&
                    s->version != DTLS1_VERSION) {
 
             if (size < 5)
                 goto err;
 
             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)
                     goto err;
+
+                /*
+                 * We remove any OCSP_RESPIDs from a previous handshake
+                 * to prevent unbounded memory growth - CVE-2016-6304
+                 */
+                sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+                                        OCSP_RESPID_free);
+                if (dsize > 0) {
+                    s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+                    if (s->tlsext_ocsp_ids == NULL) {
+                        *al = SSL_AD_INTERNAL_ERROR;
+                        return 0;
+                    }
+                } else {
+                    s->tlsext_ocsp_ids = NULL;
+                }
+
                 while (dsize > 0) {
                     OCSP_RESPID *id;
                     int idsize;
                     if (dsize < 4)
                         goto err;
                     n2s(data, idsize);
                     dsize -= 2 + idsize;
                     size -= 2 + idsize;
                     if (dsize < 0)
                         goto err;
                     sdata = data;
                     data += idsize;
                     id = d2i_OCSP_RESPID(NULL, &sdata, idsize);
                     if (!id)
                         goto err;
                     if (data != sdata) {
                         OCSP_RESPID_free(id);
                         goto err;
                     }
-                    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)
                     goto err;
                 n2s(data, dsize);
                 size -= 2;
                 if (dsize != size)
                     goto err;
                 sdata = data;
                 if (dsize > 0) {
                     if (s->tlsext_ocsp_exts) {
                         sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts,
                                                    X509_EXTENSION_free);
                     }
 
                     s->tlsext_ocsp_exts =
                         d2i_X509_EXTENSIONS(NULL, &sdata, dsize);
                     if (!s->tlsext_ocsp_exts || (data + dsize != sdata))
                         goto err;
                 }
             }
             /*
              * We don't know what to do with any other type * so ignore it.
              */
             else
                 s->tlsext_status_type = -1;
         }
 # ifndef OPENSSL_NO_HEARTBEATS
         else if (type == TLSEXT_TYPE_heartbeat) {
             switch (data[0]) {
             case 0x01:         /* Client allows us to send HB requests */
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
                 break;
             case 0x02:         /* Client doesn't accept HB requests */
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
                 break;
             default:
                 *al = SSL_AD_ILLEGAL_PARAMETER;
                 return 0;
             }
         }
 # endif
 # ifndef OPENSSL_NO_NEXTPROTONEG
         else if (type == TLSEXT_TYPE_next_proto_neg &&
                  s->s3->tmp.finish_md_len == 0) {
             /*-
              * We shouldn't accept this extension on a
              * renegotiation.
              *
              * s->new_session will be set on renegotiation, but we
              * probably shouldn't rely that it couldn't be set on
              * the initial renegotation too in certain cases (when
              * there's some other reason to disallow resuming an
              * earlier session -- the current code won't be doing
              * anything like that, but this might change).
              *
              * A valid sign that there's been a previous handshake
              * in this connection is if s->s3->tmp.finish_md_len >
              * 0.  (We are talking about a check that will happen
              * in the Hello protocol round, well before a new
              * Finished message could have been computed.)
              */
             s->s3->next_proto_neg_seen = 1;
         }
 # endif
 
         /* session ticket processed earlier */
 # ifndef OPENSSL_NO_SRTP
         else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)
                  && type == TLSEXT_TYPE_use_srtp) {
             if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al))
                 return 0;
         }
 # endif
 
         data += size;
     }
 
     /* Spurious data on the end */
     if (data != limit)
         goto err;
 
     *p = data;
 
  ri_check:
 
     /* Need RI if renegotiating */
 
     if (!renegotiate_seen && s->renegotiate &&
         !(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;
 err:
     *al = SSL_AD_DECODE_ERROR;
     return 0;
 }
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
 /*
  * ssl_next_proto_validate validates a Next Protocol Negotiation block. No
  * elements of zero length are allowed and the set of elements must exactly
  * fill the length of the block.
  */
 static char ssl_next_proto_validate(unsigned char *d, unsigned len)
 {
     unsigned int off = 0;
 
     while (off < len) {
         if (d[off] == 0)
             return 0;
         off += d[off];
         off++;
     }
 
     return off == len;
 }
 # endif
 
 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;
 
 # ifndef OPENSSL_NO_NEXTPROTONEG
     s->s3->next_proto_neg_seen = 0;
 # endif
     s->tlsext_ticket_expected = 0;
 
 # ifndef OPENSSL_NO_HEARTBEATS
     s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED |
                              SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
 # endif
 
-    if (data >= (d + n - 2))
+    if ((d + n) - data <= 2)
         goto ri_check;
 
     n2s(data, length);
-    if (data + length != d + n) {
+    if ((d + n) - data != length) {
         *al = SSL_AD_DECODE_ERROR;
         return 0;
     }
 
-    while (data <= (d + n - 4)) {
+    while ((d + n) - data >= 4) {
         n2s(data, type);
         n2s(data, size);
 
-        if (data + size > (d + n))
+        if ((d + n) - data < size)
             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) {
             unsigned char *sdata = data;
             int ecpointformatlist_length = *(sdata++);
 
             if (ecpointformatlist_length != size - 1 ||
                 ecpointformatlist_length < 1) {
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
             }
             if (!s->hit) {
                 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) {
                 /* dummy byte just to get non-NULL */
                 s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
             } 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;
         }
 # ifndef OPENSSL_NO_NEXTPROTONEG
         else if (type == TLSEXT_TYPE_next_proto_neg &&
                  s->s3->tmp.finish_md_len == 0) {
             unsigned char *selected;
             unsigned char selected_len;
 
             /* We must have requested it. */
             if (s->ctx->next_proto_select_cb == NULL) {
                 *al = TLS1_AD_UNSUPPORTED_EXTENSION;
                 return 0;
             }
             /* The data must be valid */
             if (!ssl_next_proto_validate(data, size)) {
                 *al = TLS1_AD_DECODE_ERROR;
                 return 0;
             }
             if (s->
                 ctx->next_proto_select_cb(s, &selected, &selected_len, data,
                                           size,
                                           s->ctx->next_proto_select_cb_arg) !=
                 SSL_TLSEXT_ERR_OK) {
                 *al = TLS1_AD_INTERNAL_ERROR;
                 return 0;
             }
             s->next_proto_negotiated = OPENSSL_malloc(selected_len);
             if (!s->next_proto_negotiated) {
                 *al = TLS1_AD_INTERNAL_ERROR;
                 return 0;
             }
             memcpy(s->next_proto_negotiated, selected, selected_len);
             s->next_proto_negotiated_len = selected_len;
             s->s3->next_proto_neg_seen = 1;
         }
 # endif
         else if (type == TLSEXT_TYPE_renegotiate) {
             if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al))
                 return 0;
             renegotiate_seen = 1;
         }
 # ifndef OPENSSL_NO_HEARTBEATS
         else if (type == TLSEXT_TYPE_heartbeat) {
             switch (data[0]) {
             case 0x01:         /* Server allows us to send HB requests */
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
                 break;
             case 0x02:         /* Server doesn't accept HB requests */
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED;
                 s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS;
                 break;
             default:
                 *al = SSL_AD_ILLEGAL_PARAMETER;
                 return 0;
             }
         }
 # endif
 # ifndef OPENSSL_NO_SRTP
         else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) {
             if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al))
                 return 0;
         }
 # endif
 
         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 RFC 4492 */
         if (s->tlsext_ellipticcurvelist != NULL)
             OPENSSL_free(s->tlsext_ellipticcurvelist);
         s->tlsext_ellipticcurvelist_length =
             sizeof(pref_list) / sizeof(pref_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 = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i <
              sizeof(pref_list) / sizeof(pref_list[0]); i++) {
             int id = tls1_ec_nid2curve_id(pref_list[i]);
             s2n(id, 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) {
                 /* dummy byte just to get non-NULL */
                 s->s3->client_opaque_prf_input = OPENSSL_malloc(1);
             } 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_early(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);
 
 # 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_early().
          */
 
         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) {
                     /* dummy byte just to get non-NULL */
                     s->s3->server_opaque_prf_input = OPENSSL_malloc(1);
                 } 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;
         }
     }
 
  err:
 # endif
     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_clienthello_tlsext_late(SSL *s)
 {
     int ret = SSL_TLSEXT_ERR_OK;
     int al;
 
     /*
      * If status request then ask callback what to do. Note: this must be
      * called after servername callbacks in case the certificate has
      * changed, and must be called after the cipher has been chosen because
      * this may influence which certificate is sent
      */
     if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
         int r;
         CERT_PKEY *certpkey;
         certpkey = ssl_get_server_send_pkey(s);
         /* If no certificate can't return certificate status */
         if (certpkey == NULL) {
             s->tlsext_status_expected = 0;
             return 1;
         }
         /*
          * Set current certificate to one we will use so SSL_get_certificate
          * et al can pick it up.
          */
         s->cert->key = certpkey;
         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;
 
  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;
 
     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
 
     OPENSSL_free(s->tlsext_ocsp_resp);
     s->tlsext_ocsp_resp = NULL;
     s->tlsext_ocsp_resplen = -1;
     /*
      * 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->hit) && s->ctx && s->ctx->tlsext_status_cb) {
         int r;
         /*
          * Call callback with resp == NULL and resplen == -1 so callback
          * knows there is no response
          */
         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 the
  * ClientHello, and other operations depend on the result, we need to handle
  * any TLS session ticket extension at the same time.
  *
  *   session_id: points at the session ID in the ClientHello. This code will
  *       read past the end of this in order to parse out the session ticket
  *       extension, if any.
  *   len: the length of the session ID.
  *   limit: a pointer to the first byte after the ClientHello.
  *   ret: (output) on return, if a ticket was decrypted, then this is set to
  *       point to the resulting session.
  *
  * If s->tls_session_secret_cb is set then we are expecting a pre-shared key
  * ciphersuite, in which case we have no use for session tickets and one will
  * never be decrypted, nor will s->tlsext_ticket_expected be set to 1.
  *
  * Returns:
  *   -1: fatal error, either from parsing or decrypting the ticket.
  *    0: no ticket was found (or was ignored, based on settings).
  *    1: a zero length extension was found, indicating that the client supports
  *       session tickets but doesn't currently have one to offer.
  *    2: either s->tls_session_secret_cb was set, or a ticket was offered but
  *       couldn't be decrypted because of a non-fatal error.
  *    3: a ticket was successfully decrypted and *ret was set.
  *
  * Side effects:
  *   Sets s->tlsext_ticket_expected to 1 if the server will have to issue
  *   a new session ticket to the client because the client indicated support
  *   (and s->tls_session_secret_cb is NULL) but the client either doesn't have
  *   a session ticket or we couldn't use the one it gave us, or if
  *   s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket.
  *   Otherwise, s->tlsext_ticket_expected is set to 0.
  */
 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;
 
     *ret = NULL;
     s->tlsext_ticket_expected = 0;
 
     /*
      * If tickets disabled behave as if no ticket present to permit stateful
      * resumption.
      */
     if (SSL_get_options(s) & SSL_OP_NO_TICKET)
         return 0;
     if ((s->version <= SSL3_VERSION) || !limit)
         return 0;
     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)
+
+        if (limit - p <= i)
             return -1;
+
+        p += i;
     }
     /* Skip past cipher list */
     n2s(p, i);
-    p += i;
-    if (p >= limit)
+    if (limit - p <= i)
         return -1;
+    p += i;
+
     /* Skip past compression algorithm list */
     i = *(p++);
-    p += i;
-    if (p > limit)
+    if (limit - p < i)
         return -1;
+    p += i;
+
     /* Now at start of extensions */
-    if ((p + 2) >= limit)
+    if (limit - p <= 2)
         return 0;
     n2s(p, i);
-    while ((p + 4) <= limit) {
+    while (limit - p >= 4) {
         unsigned short type, size;
         n2s(p, type);
         n2s(p, size);
-        if (p + size > limit)
+        if (limit - p < size)
             return 0;
         if (type == TLSEXT_TYPE_session_ticket) {
             int r;
             if (size == 0) {
                 /*
                  * The client will accept a ticket but doesn't currently have
                  * one.
                  */
                 s->tlsext_ticket_expected = 1;
                 return 1;
             }
             if (s->tls_session_secret_cb) {
                 /*
                  * Indicate that the ticket couldn't be decrypted rather than
                  * generating the session from ticket now, trigger
                  * abbreviated handshake based on external mechanism to
                  * calculate the master secret later.
                  */
                 return 2;
             }
             r = tls_decrypt_ticket(s, p, size, session_id, len, ret);
             switch (r) {
             case 2:            /* ticket couldn't be decrypted */
                 s->tlsext_ticket_expected = 1;
                 return 2;
             case 3:            /* ticket was decrypted */
                 return r;
             case 4:            /* ticket decrypted but need to renew */
                 s->tlsext_ticket_expected = 1;
                 return 3;
             default:           /* fatal error */
                 return -1;
             }
         }
         p += size;
     }
     return 0;
 }
 
 /*-
  * tls_decrypt_ticket attempts to decrypt a session ticket.
  *
  *   etick: points to the body of the session ticket extension.
  *   eticklen: the length of the session tickets extenion.
  *   sess_id: points at the session ID.
  *   sesslen: the length of the session ID.
  *   psess: (output) on return, if a ticket was decrypted, then this is set to
  *       point to the resulting session.
  *
  * Returns:
  *   -1: fatal error, either from parsing or decrypting the ticket.
  *    2: the ticket couldn't be decrypted.
  *    3: a ticket was successfully decrypted and *psess was set.
  *    4: same as 3, but the ticket needs to be renewed.
  */
 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)
-        return 2;
+
     /* 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)
             return 2;
         if (rv == 2)
             renew_ticket = 1;
     } else {
         /* Check key name matches */
         if (memcmp(etick, tctx->tlsext_tick_key_name, 16))
             return 2;
         if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16,
                          tlsext_tick_md(), NULL) <= 0
                 || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
                                       tctx->tlsext_tick_aes_key,
                                       etick + 16) <= 0) {
             goto err;
        }
     }
     /*
      * Attempt to process session ticket, first conduct sanity and integrity
      * checks on ticket.
      */
     mlen = HMAC_size(&hctx);
     if (mlen < 0) {
         goto err;
     }
+    /* Sanity check ticket length: must exceed keyname + IV + HMAC */
+    if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
+        HMAC_CTX_cleanup(&hctx);
+        EVP_CIPHER_CTX_cleanup(&ctx);
+        return 2;
+    }
+
     eticklen -= mlen;
     /* Check HMAC of encrypted ticket */
     if (HMAC_Update(&hctx, etick, eticklen) <= 0
             || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) {
         goto err;
     }
     HMAC_CTX_cleanup(&hctx);
     if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         return 2;
     }
     /* 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 == NULL
             || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         OPENSSL_free(sdec);
         return -1;
     }
     if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) {
         EVP_CIPHER_CTX_cleanup(&ctx);
         OPENSSL_free(sdec);
         return 2;
     }
     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;
         if (renew_ticket)
             return 4;
         else
             return 3;
     }
     ERR_clear_error();
     /*
      * For session parse failure, indicate that we need to send a new ticket.
      */
     return 2;
 err:
     EVP_CIPHER_CTX_cleanup(&ctx);
     HMAC_CTX_cleanup(&hctx);
     return -1;
 }
 
 /* Tables to translate from NIDs to TLS v1.2 ids */
 
 typedef struct {
     int nid;
     int id;
 } tls12_lookup;
 
 static tls12_lookup tls12_md[] = {
 # ifndef OPENSSL_NO_MD5
     {NID_md5, TLSEXT_hash_md5},
 # endif
 # ifndef OPENSSL_NO_SHA
     {NID_sha1, TLSEXT_hash_sha1},
 # endif
 # ifndef OPENSSL_NO_SHA256
     {NID_sha224, TLSEXT_hash_sha224},
     {NID_sha256, TLSEXT_hash_sha256},
 # endif
 # ifndef OPENSSL_NO_SHA512
     {NID_sha384, TLSEXT_hash_sha384},
     {NID_sha512, TLSEXT_hash_sha512}
 # endif
 };
 
 static tls12_lookup tls12_sig[] = {
 # ifndef OPENSSL_NO_RSA
     {EVP_PKEY_RSA, TLSEXT_signature_rsa},
 # endif
 # ifndef OPENSSL_NO_DSA
     {EVP_PKEY_DSA, TLSEXT_signature_dsa},
 # endif
 # ifndef OPENSSL_NO_ECDSA
     {EVP_PKEY_EC, TLSEXT_signature_ecdsa}
 # endif
 };
 
 static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen)
 {
     size_t i;
     for (i = 0; i < tlen; i++) {
         if (table[i].nid == nid)
             return table[i].id;
     }
     return -1;
 }
 
 # if 0
 static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen)
 {
     size_t i;
     for (i = 0; i < tlen; i++) {
         if (table[i].id == id)
             return table[i].nid;
     }
     return -1;
 }
 # endif
 
 int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk,
                          const EVP_MD *md)
 {
     int sig_id, md_id;
     if (!md)
         return 0;
     md_id = tls12_find_id(EVP_MD_type(md), tls12_md,
                           sizeof(tls12_md) / sizeof(tls12_lookup));
     if (md_id == -1)
         return 0;
     sig_id = tls12_get_sigid(pk);
     if (sig_id == -1)
         return 0;
     p[0] = (unsigned char)md_id;
     p[1] = (unsigned char)sig_id;
     return 1;
 }
 
 int tls12_get_sigid(const EVP_PKEY *pk)
 {
     return tls12_find_id(pk->type, tls12_sig,
                          sizeof(tls12_sig) / sizeof(tls12_lookup));
 }
 
 const EVP_MD *tls12_get_hash(unsigned char hash_alg)
 {
     switch (hash_alg) {
 # ifndef OPENSSL_NO_SHA
     case TLSEXT_hash_sha1:
         return EVP_sha1();
 # endif
 # ifndef OPENSSL_NO_SHA256
     case TLSEXT_hash_sha224:
         return EVP_sha224();
 
     case TLSEXT_hash_sha256:
         return EVP_sha256();
 # endif
 # ifndef OPENSSL_NO_SHA512
     case TLSEXT_hash_sha384:
         return EVP_sha384();
 
     case TLSEXT_hash_sha512:
         return EVP_sha512();
 # endif
     default:
         return NULL;
 
     }
 }
 
 /* Set preferred digest for each key type */
 
 int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize)
 {
     int i, idx;
     const EVP_MD *md;
     CERT *c = s->cert;
     /* Extension ignored for TLS versions below 1.2 */
     if (TLS1_get_version(s) < TLS1_2_VERSION)
         return 1;
     /* Should never happen */
     if (!c)
         return 0;
 
     c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL;
     c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL;
     c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL;
     c->pkeys[SSL_PKEY_ECC].digest = NULL;
 
     for (i = 0; i < dsize; i += 2) {
         unsigned char hash_alg = data[i], sig_alg = data[i + 1];
 
         switch (sig_alg) {
 # ifndef OPENSSL_NO_RSA
         case TLSEXT_signature_rsa:
             idx = SSL_PKEY_RSA_SIGN;
             break;
 # endif
 # ifndef OPENSSL_NO_DSA
         case TLSEXT_signature_dsa:
             idx = SSL_PKEY_DSA_SIGN;
             break;
 # endif
 # ifndef OPENSSL_NO_ECDSA
         case TLSEXT_signature_ecdsa:
             idx = SSL_PKEY_ECC;
             break;
 # endif
         default:
             continue;
         }
 
         if (c->pkeys[idx].digest == NULL) {
             md = tls12_get_hash(hash_alg);
             if (md) {
                 c->pkeys[idx].digest = md;
                 if (idx == SSL_PKEY_RSA_SIGN)
                     c->pkeys[SSL_PKEY_RSA_ENC].digest = md;
             }
         }
 
     }
 
     /*
      * Set any remaining keys to default values. NOTE: if alg is not
      * supported it stays as NULL.
      */
 # ifndef OPENSSL_NO_DSA
     if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest)
         c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1();
 # endif
 # ifndef OPENSSL_NO_RSA
     if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) {
         c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1();
         c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1();
     }
 # endif
 # ifndef OPENSSL_NO_ECDSA
     if (!c->pkeys[SSL_PKEY_ECC].digest)
         c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1();
 # endif
     return 1;
 }
 
 #endif
 
 #ifndef OPENSSL_NO_HEARTBEATS
 int tls1_process_heartbeat(SSL *s)
 {
     unsigned char *p = &s->s3->rrec.data[0], *pl;
     unsigned short hbtype;
     unsigned int payload;
     unsigned int padding = 16;  /* Use minimum padding */
 
     if (s->msg_callback)
         s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT,
                         &s->s3->rrec.data[0], s->s3->rrec.length,
                         s, s->msg_callback_arg);
 
     /* Read type and payload length first */
     if (1 + 2 + 16 > s->s3->rrec.length)
         return 0;               /* silently discard */
     hbtype = *p++;
     n2s(p, payload);
     if (1 + 2 + payload + 16 > s->s3->rrec.length)
         return 0;               /* silently discard per RFC 6520 sec. 4 */
     pl = p;
 
     if (hbtype == TLS1_HB_REQUEST) {
         unsigned char *buffer, *bp;
         int r;
 
         /*
          * Allocate memory for the response, size is 1 bytes message type,
          * plus 2 bytes payload length, plus payload, plus padding
          */
         buffer = OPENSSL_malloc(1 + 2 + payload + padding);
         if (buffer == NULL)
             return -1;
         bp = buffer;
 
         /* Enter response type, length and copy payload */
         *bp++ = TLS1_HB_RESPONSE;
         s2n(payload, bp);
         memcpy(bp, pl, payload);
         bp += payload;
         /* Random padding */
-        if (RAND_pseudo_bytes(bp, padding) < 0) {
+        if (RAND_bytes(bp, padding) <= 0) {
             OPENSSL_free(buffer);
             return -1;
         }
 
         r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer,
                              3 + payload + padding);
 
         if (r >= 0 && s->msg_callback)
             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
                             buffer, 3 + payload + padding,
                             s, s->msg_callback_arg);
 
         OPENSSL_free(buffer);
 
         if (r < 0)
             return r;
     } else if (hbtype == TLS1_HB_RESPONSE) {
         unsigned int seq;
 
         /*
          * We only send sequence numbers (2 bytes unsigned int), and 16
          * random bytes, so we just try to read the sequence number
          */
         n2s(pl, seq);
 
         if (payload == 18 && seq == s->tlsext_hb_seq) {
             s->tlsext_hb_seq++;
             s->tlsext_hb_pending = 0;
         }
     }
 
     return 0;
 }
 
 int tls1_heartbeat(SSL *s)
 {
     unsigned char *buf, *p;
     int ret = -1;
     unsigned int payload = 18;  /* Sequence number + random bytes */
     unsigned int padding = 16;  /* Use minimum padding */
 
     /* Only send if peer supports and accepts HB requests... */
     if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) ||
         s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) {
         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT);
         return -1;
     }
 
     /* ...and there is none in flight yet... */
     if (s->tlsext_hb_pending) {
         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING);
         return -1;
     }
 
     /* ...and no handshake in progress. */
     if (SSL_in_init(s) || s->in_handshake) {
         SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE);
         return -1;
     }
 
     /*
      * Check if padding is too long, payload and padding must not exceed 2^14
      * - 3 = 16381 bytes in total.
      */
     OPENSSL_assert(payload + padding <= 16381);
 
     /*-
      * Create HeartBeat message, we just use a sequence number
      * as payload to distuingish different messages and add
      * some random stuff.
      *  - Message Type, 1 byte
      *  - Payload Length, 2 bytes (unsigned int)
      *  - Payload, the sequence number (2 bytes uint)
      *  - Payload, random bytes (16 bytes uint)
      *  - Padding
      */
     buf = OPENSSL_malloc(1 + 2 + payload + padding);
     p = buf;
     /* Message Type */
     *p++ = TLS1_HB_REQUEST;
     /* Payload length (18 bytes here) */
     s2n(payload, p);
     /* Sequence number */
     s2n(s->tlsext_hb_seq, p);
     /* 16 random bytes */
-    if (RAND_pseudo_bytes(p, 16) < 0) {
+    if (RAND_bytes(p, 16) <= 0) {
         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
         goto err;
     }
     p += 16;
     /* Random padding */
-    if (RAND_pseudo_bytes(p, padding) < 0) {
+    if (RAND_bytes(p, padding) <= 0) {
         SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
         goto err;
     }
 
     ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
     if (ret >= 0) {
         if (s->msg_callback)
             s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT,
                             buf, 3 + payload + padding,
                             s, s->msg_callback_arg);
 
         s->tlsext_hb_pending = 1;
     }
 
 err:
     OPENSSL_free(buf);
 
     return ret;
 }
 #endif