Browse Source

First public commit of dev branch

Source commit: 98cb9d870efc1c60826db4398ec35c5cbe809e6a
Martin Prikryl 10 years ago
parent
commit
d8f92984b9
100 changed files with 13425 additions and 2199 deletions
  1. 5 5
      deployment/WinSCPnet.nuspec
  2. 285 286
      deployment/license.setup.txt
  3. 721 722
      deployment/license.txt
  4. 6 1
      deployment/winscp.isl
  5. BIN
      deployment/winscpsetup.ico
  6. 324 167
      deployment/winscpsetup.iss
  7. 6 6
      dotnet/App.config
  8. 1 1
      dotnet/CommandExecutionResult.cs
  9. 1 1
      dotnet/FilePermissions.cs
  10. 20 12
      dotnet/GlobalSuppressions.cs
  11. 4 1
      dotnet/RemoteFileInfo.cs
  12. 249 18
      dotnet/Session.cs
  13. 57 35
      dotnet/SessionOptions.cs
  14. 26 0
      dotnet/TransferOptions.cs
  15. 5 3
      dotnet/WinSCPnet.csproj
  16. 1 1
      dotnet/WinSCPnet.ruleset
  17. 1 3
      dotnet/internal/CallstackAndLock.cs
  18. 5 1
      dotnet/internal/ConsoleCommStruct.cs
  19. 14 0
      dotnet/internal/CustomLogReader.cs
  20. 146 20
      dotnet/internal/ExeSessionProcess.cs
  21. 71 0
      dotnet/internal/GenericSecurity.cs
  22. 0 1
      dotnet/internal/Job.cs
  23. 12 4
      dotnet/internal/Logger.cs
  24. 1 1
      dotnet/internal/OperationResultGuard.cs
  25. 42 0
      dotnet/internal/PatientFileStream.cs
  26. 1 5
      dotnet/internal/SessionElementLogReader.cs
  27. 10 10
      dotnet/internal/SessionLogReader.cs
  28. 74 2
      dotnet/internal/UnsafeNativeMethods.cs
  29. 373 373
      dotnet/license-dotnet.txt
  30. 4 5
      dotnet/properties/AssemblyInfo.cs
  31. 20 0
      libs/buildlibs.bat
  32. 5 0
      libs/cleaninterm.bat
  33. 30 0
      libs/neon/src/ne_locks.c
  34. 9 0
      libs/neon/src/ne_locks.h
  35. 23 0
      libs/neon/src/ne_openssl.c
  36. 10 5
      libs/neon/src/ne_socket.c
  37. 6 0
      libs/neon/src/ne_ssl.h
  38. 82 11
      libs/openssl/Makefile
  39. 4 182
      libs/openssl/crypto/aes/aes_wrap.c
  40. 46 0
      libs/openssl/crypto/arm64cpuid.S
  41. 31 4
      libs/openssl/crypto/arm_arch.h
  42. 90 7
      libs/openssl/crypto/armcap.c
  43. 82 27
      libs/openssl/crypto/armv4cpuid.S
  44. 44 2
      libs/openssl/crypto/asn1/a_gentm.c
  45. 30 0
      libs/openssl/crypto/asn1/a_time.c
  46. 57 35
      libs/openssl/crypto/asn1/a_utctm.c
  47. 23 1
      libs/openssl/crypto/asn1/ameth_lib.c
  48. 6 4
      libs/openssl/crypto/asn1/asn1.h
  49. 3 0
      libs/openssl/crypto/asn1/asn1_locl.h
  50. 482 0
      libs/openssl/crypto/asn1/bio_asn1.c
  51. 248 0
      libs/openssl/crypto/asn1/bio_ndef.c
  52. 15 0
      libs/openssl/crypto/asn1/t_x509.c
  53. 3 1
      libs/openssl/crypto/asn1/x_crl.c
  54. 20 0
      libs/openssl/crypto/asn1/x_x509.c
  55. 25 0
      libs/openssl/crypto/bio/b_dump.c
  56. 6 2
      libs/openssl/crypto/bio/b_sock.c
  57. 6 2
      libs/openssl/crypto/bio/bio.h
  58. 1 1
      libs/openssl/crypto/bio/bio_err.c
  59. 1 1
      libs/openssl/crypto/bio/bss_acpt.c
  60. 1 1
      libs/openssl/crypto/bio/bss_conn.c
  61. 20 2
      libs/openssl/crypto/bio/bss_fd.c
  62. 0 18
      libs/openssl/crypto/bn/bn.h
  63. 121 122
      libs/openssl/crypto/bn/bn_asm.c
  64. 300 26
      libs/openssl/crypto/bn/bn_exp.c
  65. 1 2
      libs/openssl/crypto/bn/bn_gf2m.c
  66. 27 0
      libs/openssl/crypto/bn/bn_lcl.h
  67. 346 0
      libs/openssl/crypto/bn/rsaz_exp.c
  68. 56 0
      libs/openssl/crypto/bn/rsaz_exp.h
  69. 11 0
      libs/openssl/crypto/buffer/buf_str.c
  70. 1 0
      libs/openssl/crypto/buffer/buffer.h
  71. 3 3
      libs/openssl/crypto/buildinf.h
  72. 2 0
      libs/openssl/crypto/cast/cast_lcl.h
  73. 555 0
      libs/openssl/crypto/cms/cms.h
  74. 459 0
      libs/openssl/crypto/cms/cms_asn1.c
  75. 197 0
      libs/openssl/crypto/cms/cms_att.c
  76. 134 0
      libs/openssl/crypto/cms/cms_cd.c
  77. 145 0
      libs/openssl/crypto/cms/cms_dd.c
  78. 260 0
      libs/openssl/crypto/cms/cms_enc.c
  79. 974 0
      libs/openssl/crypto/cms/cms_env.c
  80. 309 0
      libs/openssl/crypto/cms/cms_err.c
  81. 395 0
      libs/openssl/crypto/cms/cms_ess.c
  82. 133 0
      libs/openssl/crypto/cms/cms_io.c
  83. 465 0
      libs/openssl/crypto/cms/cms_kari.c
  84. 471 0
      libs/openssl/crypto/cms/cms_lcl.h
  85. 652 0
      libs/openssl/crypto/cms/cms_lib.c
  86. 432 0
      libs/openssl/crypto/cms/cms_pwri.c
  87. 955 0
      libs/openssl/crypto/cms/cms_sd.c
  88. 836 0
      libs/openssl/crypto/cms/cms_smime.c
  89. 30 5
      libs/openssl/crypto/cryptlib.c
  90. 4 0
      libs/openssl/crypto/cversion.c
  91. 3 2
      libs/openssl/crypto/des/asm/d_win32.asm
  92. 3 1
      libs/openssl/crypto/des/des_locl.h
  93. 105 0
      libs/openssl/crypto/dh/dh.h
  94. 492 27
      libs/openssl/crypto/dh/dh_ameth.c
  95. 96 2
      libs/openssl/crypto/dh/dh_asn1.c
  96. 36 10
      libs/openssl/crypto/dh/dh_check.c
  97. 7 1
      libs/openssl/crypto/dh/dh_err.c
  98. 187 0
      libs/openssl/crypto/dh/dh_kdf.c
  99. 14 0
      libs/openssl/crypto/dh/dh_key.c
  100. 314 8
      libs/openssl/crypto/dh/dh_pmeth.c

+ 5 - 5
deployment/WinSCPnet.nuspec

@@ -11,19 +11,19 @@
     <iconUrl>http://winscp.net/pad/winscp.png</iconUrl>
     <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <summary>The WinSCP .NET assembly is a .NET wrapper around WinSCP’s scripting interface.</summary>
-    <description>The WinSCP .NET assembly is a .NET wrapper around WinSCP’s scripting interface that allows your code to connect to a remote machine and manipulate remote files over SFTP, SCP, and FTP sessions.
-    
+    <description>The WinSCP .NET assembly is a .NET wrapper around WinSCP’s scripting interface that allows your code to connect to a remote machine and manipulate remote files over SFTP, SCP, WebDAV and FTP sessions.
+
 The library is primarily intended for advanced automation tasks that require conditional processing, loops or other control structures for which the basic scripting interface is too limited. The library is not a general purpose file transfer library. It particularly lacks support for interactive processing and as such it is not well suited for use in GUI applications.
 
 For documentation and examples of use, see project website.
 
 The NuGet package includes the assembly itself and a required WinSCP executable. When installed, it adds the assembly as reference to your project and sets up WinSCP executable to be copied to project output directory, so that it can be found on run-time.</description>
     <copyright>Copyright © 2012-2015 Martin Prikryl</copyright>
-    <tags>winscp sftp ftp ftps scp transfer</tags>
+    <tags>winscp sftp ftp ftps webdav scp transfer</tags>
   </metadata>
   <files>
-    <file src="$BuildConfigDir$\WinSCPnet.dll" target="lib"/>
+    <file src="$DotNetBuildConfigDir$\WinSCPnet.dll" target="lib"/>
     <file src="$BuildConfigDir$\WinSCP.exe" target="content"/>
     <file src="install.ps1" target="tools"/>
   </files>
-</package>
+</package>

+ 285 - 286
deployment/license.setup.txt

@@ -1,286 +1,285 @@
-You can also review this license and further details online at:
-http://winscp.net/eng/docs/license
-
-  
-  A. GNU General Public License
-  B. License of WinSCP Icon Set
-  C. Privacy Policy
-
-
-  A. GNU GENERAL PUBLIC LICENSE
-  Version 3, 29 June 2007
-
-Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
-Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
-
-  Preamble
-
-The GNU General Public License is a free, copyleft license for software and other kinds of works.
-
-The licenses for most software and other practical works are designed to take away your freedom to share and change the works.  By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.  We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors.  You can apply it to your programs, too. 
-
-When we speak of free software, we are referring to freedom, not price.  Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. 
-
-To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights.  Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
-
-For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received.  You must make sure that they, too, receive or can get the source code.  And you must show them these terms so they know their rights.
-
-Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
-
-For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software.  For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
-
-Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so.  This is fundamentally incompatible with the aim of protecting users' freedom to change the software.  The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable.  Therefore, we have designed this version of the GPL to prohibit the practice for those products.  If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
-
-Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary.  To prevent this, the GPL assures that patents cannot be used to render the program non-free.
-
-The precise terms and conditions for copying, distribution and modification follow.
-
-  TERMS AND CONDITIONS
-
-  0. Definitions.
-
-"This License" refers to version 3 of the GNU General Public License.
-
-"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
-
-"The Program" refers to any copyrightable work licensed under this License.  Each licensee is addressed as "you".  "Licensees" and "recipients" may be individuals or organizations.
-
-To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy.  The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.
-
-A "covered work" means either the unmodified Program or a work based on the Program.
-
-To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy.  Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
-
-To "convey" a work means any kind of propagation that enables other parties to make or receive copies.  Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
-
-An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License.  If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-The "source code" for a work means the preferred form of the work for making modifications to it.  "Object code" means any non-source form of a work.
-
-A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
-
-The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form.  A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
-
-The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities.  However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work.  For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
-
-The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
-
-The Corresponding Source for a work in source code form is that same work.
-
-  2. Basic Permissions.
-
-All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met.  This License explicitly affirms your unlimited permission to run the unmodified Program.  The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work.  This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
-
-You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force.  You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright.  Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
-
-Conveying under any other circumstances is permitted solely under the conditions stated below.  Sublicensing is not allowed; section 10 makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
-
-When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
-
-  4. Conveying Verbatim Copies.
-
-You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
-
-You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
-
-a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
-
-b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7.  This requirement modifies the requirement in section 4 to "keep intact all notices".
-
-c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy.  This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged.  This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
-
-d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
-
-A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit.  Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
-
-a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
-
-b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
-
-c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source.  This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
-
-d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge.  You need not require recipients to copy the Corresponding Source along with the object code.  If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source.  Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
-
-e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
-
-A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
-
-A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling.  In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage.  For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product.  A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
-
-"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source.  The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
-
-If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information.  But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
-
-The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed.  Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
-
-Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
-
-  7. Additional Terms.
-
-"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law.  If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
-
-When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it.  (Additional permissions may be written to require their own removal in certain cases when you modify the work.)  You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
-
-Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
-
-a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
-
-b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
-
-c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
-
-d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
-
-e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
-
-f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
-
-All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10.  If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term.  If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
-
-If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
-
-Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
-
-  8. Termination.
-
-You may not propagate or modify a covered work except as expressly provided under this License.  Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
-
-However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
-
-Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License.  If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-You are not required to accept this License in order to receive or run a copy of the Program.  Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance.  However, nothing other than this License grants you permission to propagate or modify any covered work.  These actions infringe copyright if you do not accept this License.  Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License.  You are not responsible for enforcing compliance by third parties with this License.
-
-An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations.  If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
-
-You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License.  For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based.  The work thus licensed is called the contributor's "contributor version".
-
-A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version.  For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
-
-Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
-
-In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement).  To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
-
-If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients.  "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
-
-If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
-
-A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License.  You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
-
-Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License.  If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all.  For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work.  The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
-
-  14. Revised Versions of this License.
-
-The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time.  Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Softwar  Foundation.  If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
-
-If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
-
-Later license versions may give you additional or different permissions.  However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
-
-  15. Disclaimer of Warranty.
-
-THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
-
-  END OF TERMS AND CONDITIONS
-
-  How to Apply These Terms to Your New Programs
-
-If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
-
-To do so, attach the following notices to the program.  It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
-
-  <one line to give the program's name and a brief idea of what it does.>
-  Copyright (C) <year>  <name of author>
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  This program is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
-
-  <program>  Copyright (C) <year>  <name of author>
-  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-  This is free software, and you are welcome to redistribute it
-  under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License.  Of course, your program's commands might be different; for a GUI interface, you would use an "about box".
-
-You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.
-
-The GNU General Public License does not permit incorporating your program into proprietary programs.  If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library.  If this is what you want to do, use the GNU Lesser General Public License instead of this License.  But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
-
-  B. License of WinSCP Icon Set
-  
-Note that all images distributed in or with WinSCP application are NOT published under the GNU General Public License. It means that it is not allowed to redistribute or reuse these images or parts of them or modifications of them without WinSCP separately or in or with another software.
-
-You agree that all ownership and copyright of the licensed stock icons remain the property of York Technologies Limited. WinSCP was granted a license to display this graphical media royalty-free in WinSCP software applications, web design, presentations, and multimedia projects that WinSCP creates and/or distributes.
-
-
-  C. WinSCP Privacy Policy
-
-Please take time to read WinSCP Privacy policy at http://winscp.net/eng/docs/privacy
-
-WinSCP includes functionality to collect and send non-personal WinSCP Usage statistics and to automatically check for application updates. The only potentially personal information sent to WinSCP is IP addresses. Users can opt-out from using this functionality in the installer or anytime later in WinSCP Preferences. WinSCP Usage statistics help improve future versions of WinSCP. Once sent, usage statistics are stored for analysis (except IP addresses) and made available to the core WinSCP team only.
-
-Before disabling WinSCP Usage statistics, be so kind and consider that it plays very important role in the WinSCP development. We work very hard to make WinSCP reliable and useful. We also love improving WinSCP with every release. And last but not least, we provide WinSCP application to you for free and we want this to stay so! However our resources and time are unfortunately very limited. We want to focus our effort on improving the right features for you. That is why we need to learn more about how you use WinSCP.
-
-If you still want to disable WinSCP Usage statistics already during installation, you may do so using Custom installation.
-
-Thank you!
-
+You can also review this license and further details online at:
+http://winscp.net/eng/docs/license
+
+
+  A. GNU General Public License
+  B. License of WinSCP Icon Set
+  C. Privacy Policy
+
+
+  A. GNU GENERAL PUBLIC LICENSE
+  Version 3, 29 June 2007
+
+Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+  Preamble
+
+The GNU General Public License is a free, copyleft license for software and other kinds of works.
+
+The licenses for most software and other practical works are designed to take away your freedom to share and change the works.  By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users.  We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors.  You can apply it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price.  Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things.
+
+To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights.  Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others.
+
+For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received.  You must make sure that they, too, receive or can get the source code.  And you must show them these terms so they know their rights.
+
+Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it.
+
+For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software.  For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions.
+
+Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so.  This is fundamentally incompatible with the aim of protecting users' freedom to change the software.  The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable.  Therefore, we have designed this version of the GPL to prohibit the practice for those products.  If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users.
+
+Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary.  To prevent this, the GPL assures that patents cannot be used to render the program non-free.
+
+The precise terms and conditions for copying, distribution and modification follow.
+
+  TERMS AND CONDITIONS
+
+  0. Definitions.
+
+"This License" refers to version 3 of the GNU General Public License.
+
+"Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks.
+
+"The Program" refers to any copyrightable work licensed under this License.  Each licensee is addressed as "you".  "Licensees" and "recipients" may be individuals or organizations.
+
+To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy.  The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work.
+
+A "covered work" means either the unmodified Program or a work based on the Program.
+
+To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy.  Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well.
+
+To "convey" a work means any kind of propagation that enables other parties to make or receive copies.  Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying.
+
+An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License.  If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+The "source code" for a work means the preferred form of the work for making modifications to it.  "Object code" means any non-source form of a work.
+
+A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language.
+
+The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form.  A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it.
+
+The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities.  However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work.  For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work.
+
+The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source.
+
+The Corresponding Source for a work in source code form is that same work.
+
+  2. Basic Permissions.
+
+All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met.  This License explicitly affirms your unlimited permission to run the unmodified Program.  The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work.  This License acknowledges your rights of fair use or other equivalent, as provided by copyright law.
+
+You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force.  You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright.  Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you.
+
+Conveying under any other circumstances is permitted solely under the conditions stated below.  Sublicensing is not allowed; section 10 makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures.
+
+When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures.
+
+  4. Conveying Verbatim Copies.
+
+You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program.
+
+You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:
+
+a) The work must carry prominent notices stating that you modified it, and giving a relevant date.
+
+b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7.  This requirement modifies the requirement in section 4 to "keep intact all notices".
+
+c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy.  This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged.  This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it.
+
+d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so.
+
+A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit.  Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:
+
+a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange.
+
+b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge.
+
+c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source.  This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b.
+
+d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge.  You need not require recipients to copy the Corresponding Source along with the object code.  If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source.  Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements.
+
+e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d.
+
+A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work.
+
+A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling.  In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage.  For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product.  A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product.
+
+"Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source.  The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made.
+
+If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information.  But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM).
+
+The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed.  Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network.
+
+Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying.
+
+  7. Additional Terms.
+
+"Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law.  If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions.
+
+When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it.  (Additional permissions may be written to require their own removal in certain cases when you modify the work.)  You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission.
+
+Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms:
+
+a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or
+
+b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or
+
+c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or
+
+d) Limiting the use for publicity purposes of names of licensors or authors of the material; or
+
+e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or
+
+f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors.
+
+All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10.  If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term.  If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying.
+
+If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms.
+
+Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way.
+
+  8. Termination.
+
+You may not propagate or modify a covered work except as expressly provided under this License.  Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11).
+
+However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.
+
+Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License.  If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+You are not required to accept this License in order to receive or run a copy of the Program.  Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance.  However, nothing other than this License grants you permission to propagate or modify any covered work.  These actions infringe copyright if you do not accept this License.  Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License.  You are not responsible for enforcing compliance by third parties with this License.
+
+An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations.  If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts.
+
+You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License.  For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based.  The work thus licensed is called the contributor's "contributor version".
+
+A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version.  For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License.
+
+Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version.
+
+In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement).  To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party.
+
+If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients.  "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid.
+
+If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it.
+
+A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License.  You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007.
+
+Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License.  If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all.  For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work.  The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such.
+
+  14. Revised Versions of this License.
+
+The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time.  Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Softwar  Foundation.  If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation.
+
+If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program.
+
+Later license versions may give you additional or different permissions.  However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version.
+
+  15. Disclaimer of Warranty.
+
+THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee.
+
+  END OF TERMS AND CONDITIONS
+
+  How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program.  It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found.
+
+  <one line to give the program's name and a brief idea of what it does.>
+  Copyright (C) <year>  <name of author>
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode:
+
+  <program>  Copyright (C) <year>  <name of author>
+  This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+  This is free software, and you are welcome to redistribute it
+  under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License.  Of course, your program's commands might be different; for a GUI interface, you would use an "about box".
+
+You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see <http://www.gnu.org/licenses/>.
+
+The GNU General Public License does not permit incorporating your program into proprietary programs.  If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library.  If this is what you want to do, use the GNU Lesser General Public License instead of this License.  But first, please read <http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+
+  B. License of WinSCP Icon Set
+
+Note that all images distributed in or with WinSCP application are NOT published under the GNU General Public License. It means that it is not allowed to redistribute or reuse these images or parts of them or modifications of them without WinSCP separately or in or with another software.
+
+You agree that all ownership and copyright of the licensed stock icons remain the property of York Technologies Limited. WinSCP was granted a license to display this graphical media royalty-free in WinSCP software applications, web design, presentations, and multimedia projects that WinSCP creates and/or distributes.
+
+
+  C. WinSCP Privacy Policy
+
+Please take time to read WinSCP Privacy policy at http://winscp.net/eng/docs/privacy
+
+WinSCP includes functionality to collect and send non-personal WinSCP Usage statistics and to automatically check for application updates. The only potentially personal information sent to WinSCP is IP addresses. Users can opt-out from using this functionality in the installer or anytime later in WinSCP Preferences. WinSCP Usage statistics help improve future versions of WinSCP. Once sent, usage statistics are stored for analysis (except IP addresses) and made available to the core WinSCP team only.
+
+Before disabling WinSCP Usage statistics, be so kind and consider that it plays very important role in the WinSCP development. We work very hard to make WinSCP reliable and useful. We also love improving WinSCP with every release. And last but not least, we provide WinSCP application to you for free and we want this to stay so! However our resources and time are unfortunately very limited. We want to focus our effort on improving the right features for you. That is why we need to learn more about how you use WinSCP.
+
+If you still want to disable WinSCP Usage statistics already during installation, you may do so using Custom installation.
+
+Thank you!

+ 721 - 722
deployment/license.txt

@@ -1,722 +1,721 @@
-  A. GNU General Public License
-  B. License of WinSCP Icon Set
-  C. Privacy Policy
-
-  
-  A. GNU GENERAL PUBLIC LICENSE
-  Version 3, 29 June 2007
-
-  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
-  Everyone is permitted to copy and distribute verbatim copies
-  of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
-
-
-  B. License of WinSCP Icon Set
-  
-Note that all images distributed in or with WinSCP application are NOT
-published under the GNU General Public License. It means that it is not
-allowed to redistribute or reuse these images or parts of them or modifications
-of them without WinSCP separately or in or with another software.
-
-You agree that all ownership and copyright of the licensed stock icons remain
-the property of York Technologies Limited. WinSCP was granted a license to
-display this graphical media royalty-free in WinSCP software applications,
-web design, presentations, and multimedia projects that WinSCP creates and/or
-distributes.
-
-
-  C. WinSCP Privacy Policy
-
-Please take time to read WinSCP Privacy policy at
-http://winscp.net/eng/docs/privacy
-
-WinSCP includes functionality to collect and send non-personal WinSCP
-Usage statistics and to automatically check for application updates. The only
-potentially personal information sent to WinSCP is IP addresses. Users can
-opt-out from using this functionality in the installer or anytime later
-in WinSCP Preferences. WinSCP Usage statistics help improve future versions
-of WinSCP. Once sent, usage statistics are stored for analysis (except
-IP addresses) and made available to the core WinSCP team only.
-
-Before disabling WinSCP Usage statistics, be so kind and consider that it
-plays very important role in the WinSCP development. We work very hard
-to make WinSCP reliable and useful. We also love improving WinSCP with every
-release. And last but not least, we provide WinSCP application to you
-for free and we want this to stay so! However our resources and time are
-unfortunately very limited. We want to focus our effort on improving
-the right features for you. That is why we need to learn more about how you
-use WinSCP.
-
-If you still want to disable WinSCP Usage statistics already during
-installation, you may do so using Custom installation.
-
-Thank you!
-
+  A. GNU General Public License
+  B. License of WinSCP Icon Set
+  C. Privacy Policy
+
+
+  A. GNU GENERAL PUBLIC LICENSE
+  Version 3, 29 June 2007
+
+  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+  Everyone is permitted to copy and distribute verbatim copies
+  of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
+
+  B. License of WinSCP Icon Set
+
+Note that all images distributed in or with WinSCP application are NOT
+published under the GNU General Public License. It means that it is not
+allowed to redistribute or reuse these images or parts of them or modifications
+of them without WinSCP separately or in or with another software.
+
+You agree that all ownership and copyright of the licensed stock icons remain
+the property of York Technologies Limited. WinSCP was granted a license to
+display this graphical media royalty-free in WinSCP software applications,
+web design, presentations, and multimedia projects that WinSCP creates and/or
+distributes.
+
+
+  C. WinSCP Privacy Policy
+
+Please take time to read WinSCP Privacy policy at
+http://winscp.net/eng/docs/privacy
+
+WinSCP includes functionality to collect and send non-personal WinSCP
+Usage statistics and to automatically check for application updates. The only
+potentially personal information sent to WinSCP is IP addresses. Users can
+opt-out from using this functionality in the installer or anytime later
+in WinSCP Preferences. WinSCP Usage statistics help improve future versions
+of WinSCP. Once sent, usage statistics are stored for analysis (except
+IP addresses) and made available to the core WinSCP team only.
+
+Before disabling WinSCP Usage statistics, be so kind and consider that it
+plays very important role in the WinSCP development. We work very hard
+to make WinSCP reliable and useful. We also love improving WinSCP with every
+release. And last but not least, we provide WinSCP application to you
+for free and we want this to stay so! However our resources and time are
+unfortunately very limited. We want to focus our effort on improving
+the right features for you. That is why we need to learn more about how you
+use WinSCP.
+
+If you still want to disable WinSCP Usage statistics already during
+installation, you may do so using Custom installation.
+
+Thank you!

+ 6 - 1
deployment/winscp.isl

@@ -1,5 +1,6 @@
 [CustomMessages]
 LanguageISOCode=en
+LocalLanguageName=English
 
 ApplicationComponent=WinSCP application
 ShellExtComponent=Drag & drop shell extension (allows direct downloads, may require restart)
@@ -26,7 +27,7 @@ Launch=Launch &WinSCP
 OpenGettingStarted=Open &Getting started page
 
 HelpButton=&Help
-ProgramComment=SFTP, FTP and SCP client
+ProgramComment2=WinSCP: SFTP, FTP, WebDAV and SCP client
 
 ; WinSCP Runtime
 Recommended=%1 (recommended)
@@ -66,3 +67,7 @@ Currency=USD
 ImportSites=Looking for sites to import...
 ApplicationsFoundDragExt=The following applications have loaded WinSCP Drag & drop shell extension that needs to be updated by Setup. It is recommended that you allow Setup to automatically close these applications. After the installation has completed, Setup will attempt to restart the applications. You can restart your computer later instead, if you do not need to use the extension.
 AcceptButton=&Accept >
+IncompleteTranslation=You are about to use an incomplete translation. It is completed by %1%% only.%n%nUntranslated parts of the user interface will be shown in their original English version.%n%nVisit WinSCP website at winscp.net to check, if newer version of the translation is available.
+
+[CustomOptions]
+TranslationCompleteness=100

BIN
deployment/winscpsetup.ico


File diff suppressed because it is too large
+ 324 - 167
deployment/winscpsetup.iss


+ 6 - 6
dotnet/App.config

@@ -1,9 +1,9 @@
 <?xml version="1.0"?>
 <configuration>
-	<startup useLegacyV2RuntimeActivationPolicy="true">
-		<supportedRuntime version="v2.0"/>
-		<supportedRuntime version="v3.0"/>
-		<supportedRuntime version="v3.5"/>
-		<supportedRuntime version="v4.0"/>
-	</startup>
+  <startup useLegacyV2RuntimeActivationPolicy="true">
+    <supportedRuntime version="v2.0"/>
+    <supportedRuntime version="v3.0"/>
+    <supportedRuntime version="v3.5"/>
+    <supportedRuntime version="v4.0"/>
+  </startup>
 </configuration>

+ 1 - 1
dotnet/CommandExecutionResult.cs

@@ -10,7 +10,7 @@ namespace WinSCP
         public string Output { get; internal set; }
         public string ErrorOutput { get; internal set; }
         public int ExitCode { get; internal set; }
-        
+
         internal CommandExecutionResult()
         {
         }

+ 1 - 1
dotnet/FilePermissions.cs

@@ -231,7 +231,7 @@ namespace WinSCP
                 {
                     symbol = UnsetSymbol;
                 }
-                
+
                 buf[i] = symbol;
 
                 flag <<= 1;

+ 20 - 12
dotnet/GlobalSuppressions.cs

@@ -1,10 +1,10 @@
-// This file is used by Code Analysis to maintain SuppressMessage 
+// This file is used by Code Analysis to maintain SuppressMessage
 // attributes that are applied to this project.
-// Project-level suppressions either have no target or are given 
+// Project-level suppressions either have no target or are given
 // a specific target and scoped to a namespace, type, member, etc.
 //
-// To add a suppression to this file, right-click the message in the 
-// Error List, point to "Suppress Message(s)", and click 
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click
 // "In Project Suppression File".
 // You do not need to add suppressions to this file manually.
 
@@ -143,11 +143,19 @@ using System.Diagnostics.CodeAnalysis;
 [assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#MapViewOfFile(Microsoft.Win32.SafeHandles.SafeFileHandle,WinSCP.FileMapAccess,System.UInt32,System.UInt32,System.UIntPtr)")]
 [assembly: SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Scope = "member", Target = "WinSCP.ExeSessionProcess.#InitializeConsole()")]
 [assembly: SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Scope = "member", Target = "WinSCP.ExeSessionProcess.#Dispose()")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Job.#.ctor(WinSCP.Logger,System.String)")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Logger.#LastWin32ErrorMessage()")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "WinSCP.Session.#GuardProcessWithJobInternal")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "WinSCP.Session.#TestHandlesClosedInternal")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.SessionOptions.#GetPassword()")]
-[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Scope = "member", Target = "WinSCP.SessionOptions.#ParseUrl(System.String)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Job.#.ctor(WinSCP.Logger,System.String)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.Logger.#LastWin32ErrorMessage()")]
+[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "WinSCP.Session.#GuardProcessWithJobInternal")]
+[assembly: SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Scope = "member", Target = "WinSCP.Session.#TestHandlesClosedInternal")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
+[assembly: SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Runtime.InteropServices.SafeHandle.DangerousGetHandle", Scope = "member", Target = "WinSCP.ExeSessionProcess.#TryCreateEvent(System.String,System.Threading.EventWaitHandle&)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.SessionOptions.#GetPassword()")]
+[assembly: SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings", MessageId = "0#", Scope = "member", Target = "WinSCP.SessionOptions.#ParseUrl(System.String)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess+NoopSafeHandle.#.ctor(System.IntPtr)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Scope = "member", Target = "WinSCP.ExeSessionProcess.#CreateFileMapping(System.String)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#GetProcessWindowStation()")]
+[assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#GetThreadDesktop(System.Int32)")]
+[assembly: SuppressMessage("Microsoft.Security", "CA5122:PInvokesShouldNotBeSafeCriticalFxCopRule", Scope = "member", Target = "WinSCP.UnsafeNativeMethods.#GetCurrentThreadId()")]
+[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.ExeSessionProcess.#CreateFileMapping(System.String)")]
+[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.Logger.#CreateCounters()")]
+[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "WinSCP.SessionLogReader.#LogContents()")]

+ 4 - 1
dotnet/RemoteFileInfo.cs

@@ -10,6 +10,7 @@ namespace WinSCP
     public sealed class RemoteFileInfo
     {
         public string Name { get; internal set; }
+        public string FullName { get; internal set; }
         public char FileType { get; internal set; }
         public long Length { get; internal set; }
         public int Length32 { get { return GetLength32(); } set { SetLength32(value); } }
@@ -21,6 +22,8 @@ namespace WinSCP
         public string Group { get; internal set; }
 
         public bool IsDirectory { get { return (Char.ToUpper(FileType, CultureInfo.InvariantCulture) == 'D'); } }
+        public bool IsThisDirectory { get { return IsDirectory && (Name == "."); } }
+        public bool IsParentDirectory { get { return IsDirectory && (Name == ".."); } }
 
         internal RemoteFileInfo()
         {
@@ -30,7 +33,7 @@ namespace WinSCP
         {
             return Name;
         }
-    
+
         private int GetLength32()
         {
             if ((Length < int.MinValue) || (Length > int.MaxValue))

+ 249 - 18
dotnet/Session.cs

@@ -8,6 +8,8 @@ using System.Threading;
 using System.Xml;
 using Microsoft.Win32;
 using System.Diagnostics;
+using System.Security;
+using System.Text.RegularExpressions;
 
 namespace WinSCP
 {
@@ -31,6 +33,17 @@ namespace WinSCP
         Either = Time | Size,
     }
 
+    [Guid("6C441F60-26AA-44FC-9B93-08884768507B")]
+    [ComVisible(true)]
+    [Flags]
+    public enum EnumerationOptions
+    {
+        None = 0x00,
+        AllDirectories = 0x01,
+        MatchDirectories = 0x02,
+        EnumerateDirectories = 0x04,
+    }
+
     public delegate void OutputDataReceivedEventHandler(object sender, OutputDataReceivedEventArgs e);
     public delegate void FileTransferredEventHandler(object sender, TransferEventArgs e);
     public delegate void FileTransferProgressEventHandler(object sender, FileTransferProgressEventArgs e);
@@ -43,7 +56,10 @@ namespace WinSCP
     public sealed class Session : IDisposable, IReflect
     {
         public string ExecutablePath { get { return _executablePath; } set { CheckNotOpened(); _executablePath = value; } }
+        public string ExecutableProcessUserName { get { return _executableProcessUserName; } set { CheckNotOpened(); _executableProcessUserName = value; } }
+        public SecureString ExecutableProcessPassword { get { return _executableProcessPassword; } set { CheckNotOpened(); _executableProcessPassword = value; } }
         public string AdditionalExecutableArguments { get { return _additionalExecutableArguments; } set { CheckNotOpened(); _additionalExecutableArguments = value; } }
+        [Obsolete("Use AddRawConfiguration")]
         public bool DefaultConfiguration { get { return _defaultConfiguration; } set { CheckNotOpened(); _defaultConfiguration = value; } }
         public bool DisableVersionCheck { get { return _disableVersionCheck; } set { CheckNotOpened(); _disableVersionCheck = value; } }
         public string IniFilePath { get { return _iniFilePath; } set { CheckNotOpened(); _iniFilePath = value; } }
@@ -287,8 +303,15 @@ namespace WinSCP
                 using (ElementLogReader groupReader = _reader.WaitForGroupAndCreateLogReader())
                 using (ElementLogReader lsReader = groupReader.WaitForNonEmptyElementAndCreateLogReader("ls", LogReadFlags.ThrowFailures))
                 {
-                    if (lsReader.TryWaitForNonEmptyElement("files", 0))
+                    string destination = null;
+                    if (lsReader.TryWaitForEmptyElement("destination", 0))
+                    {
+                        lsReader.GetEmptyElementValue("destination", out destination);
+                    }
+                    if ((destination != null) && lsReader.TryWaitForNonEmptyElement("files", 0))
                     {
+                        destination = IncludeTrailingSlash(destination);
+
                         using (ElementLogReader filesReader = lsReader.CreateLogReader())
                         {
                             while (filesReader.TryWaitForNonEmptyElement("file", 0))
@@ -303,6 +326,7 @@ namespace WinSCP
                                         if (fileReader.GetEmptyElementValue("filename", out value))
                                         {
                                             fileInfo.Name = value;
+                                            fileInfo.FullName = destination + value;
                                         }
                                         else
                                         {
@@ -320,6 +344,9 @@ namespace WinSCP
                     else
                     {
                         // "files" not found, keep reading, we expect "failure"
+                        // This happens only in case of fatal errors,
+                        // in case of normal error (non existing folder),
+                        // the "failure" is caught in "group" already, before the "ls".
                         groupReader.ReadToEnd(LogReadFlags.ThrowFailures);
                         // only if not "failure", throw "files" not found
                         throw SessionLocalException.CreateElementNotFound(this, "files");
@@ -330,6 +357,105 @@ namespace WinSCP
             }
         }
 
+        private IEnumerable<RemoteFileInfo> DoEnumerateRemoteFiles(string path, Regex regex, EnumerationOptions options)
+        {
+            bool allDirectories = ((options & EnumerationOptions.AllDirectories) == EnumerationOptions.AllDirectories);
+            bool matchDirectories = ((options & EnumerationOptions.MatchDirectories) == EnumerationOptions.MatchDirectories);
+            bool enumerateDirectories = ((options & EnumerationOptions.EnumerateDirectories) == EnumerationOptions.EnumerateDirectories);
+
+            if (enumerateDirectories && !allDirectories)
+            {
+                throw new ArgumentException("Cannot use enumeration option EnumerateDirectories without AllDirectories");
+            }
+
+            if (enumerateDirectories && matchDirectories)
+            {
+                throw new ArgumentException("Cannot combine enumeration option EnumerateDirectories with MatchDirectories");
+            }
+
+            // Need to use guarded method for the listing, see a comment in EnumerateRemoteFiles
+            RemoteDirectoryInfo directoryInfo = ListDirectory(path);
+
+            foreach (RemoteFileInfo fileInfo in directoryInfo.Files)
+            {
+                if (!fileInfo.IsThisDirectory && !fileInfo.IsParentDirectory)
+                {
+                    bool matches = regex.IsMatch(fileInfo.Name);
+
+                    bool enumerate;
+                    if (!fileInfo.IsDirectory)
+                    {
+                        enumerate = matches;
+                    }
+                    else
+                    {
+                        if (enumerateDirectories)
+                        {
+                            enumerate = true;
+                        }
+                        else if (matchDirectories)
+                        {
+                            enumerate = matches;
+                        }
+                        else
+                        {
+                            enumerate = false;
+                        }
+                    }
+
+                    if (enumerate)
+                    {
+                        yield return fileInfo;
+                    }
+
+
+                    if (fileInfo.IsDirectory && allDirectories)
+                    {
+                        foreach (RemoteFileInfo fileInfo2 in DoEnumerateRemoteFiles(CombinePaths(path, fileInfo.Name), regex, options))
+                        {
+                            yield return fileInfo2;
+                        }
+                    }
+                }
+            }
+        }
+
+        public IEnumerable<RemoteFileInfo> EnumerateRemoteFiles(string path, string mask, EnumerationOptions options)
+        {
+            // Note that this method exits as soon as DoEnumerateRemoteFiles is entered,
+            // so the Session object is not guarded during the whole enumeration.
+            // Though it should not matter as it uses only guarded methods (ListDirectory)
+            // for the actual work on the session
+            using (Logger.CreateCallstackAndLock())
+            {
+                CheckOpened();
+
+                Regex regex = MaskToRegex(mask);
+
+                return DoEnumerateRemoteFiles(path, regex, options);
+            }
+        }
+
+        private static Regex MaskToRegex(string mask)
+        {
+            if (string.IsNullOrEmpty(mask) ||
+                // *.* has to match even filename without dot
+                (mask == "*.*"))
+            {
+                mask = "*";
+            }
+
+            return
+                new Regex(
+                    '^' +
+                    mask
+                        .Replace(".", "[.]")
+                        .Replace("*", ".*")
+                        .Replace("?", ".") +
+                    '$',
+                    RegexOptions.IgnoreCase);
+        }
+
         public TransferOperationResult PutFiles(string localPath, string remotePath, bool remove = false, TransferOptions options = null)
         {
             using (Logger.CreateCallstackAndLock())
@@ -686,7 +812,7 @@ namespace WinSCP
 
         public byte[] CalculateFileChecksum(string algorithm, string path)
         {
-            using (Logger.CreateCallstack())
+            using (Logger.CreateCallstackAndLock())
             {
                 WriteCommand(string.Format(CultureInfo.InvariantCulture, "checksum -- \"{0}\" \"{1}\"", Tools.ArgumentEscape(algorithm), Tools.ArgumentEscape(path)));
 
@@ -773,8 +899,90 @@ namespace WinSCP
             return path + mask;
         }
 
+        public string TranslateRemotePathToLocal(string remotePath, string remoteRoot, string localRoot)
+        {
+            if (remotePath == null)
+            {
+                throw new ArgumentNullException("remotePath");
+            }
+
+            if (remoteRoot == null)
+            {
+                throw new ArgumentNullException("remoteRoot");
+            }
+
+            if (localRoot == null)
+            {
+                throw new ArgumentNullException("localRoot");
+            }
+
+            if ((localRoot.Length > 0) && !localRoot.EndsWith("\\", StringComparison.Ordinal))
+            {
+                localRoot += "\\";
+            }
+
+            // not adding to empty root paths, because the path may not even start with slash
+            if ((remoteRoot.Length > 0) && !remoteRoot.EndsWith("/", StringComparison.Ordinal))
+            {
+                remoteRoot += "/";
+            }
+
+            string localPath;
+            // special case
+            if (remotePath == remoteRoot)
+            {
+                localPath = localRoot;
+            }
+            else
+            {
+                if (!remotePath.StartsWith(remoteRoot, StringComparison.Ordinal))
+                {
+                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "{0} does not start with {1}", remotePath, remoteRoot));
+                }
+
+                string subPath = remotePath.Substring(remoteRoot.Length);
+                // can happen only when remoteRoot is empty
+                if (subPath.StartsWith("/", StringComparison.Ordinal))
+                {
+                    subPath = subPath.Substring(1);
+                }
+                subPath = subPath.Replace('/', '\\');
+                localPath = localRoot + subPath;
+            }
+            return localPath;
+        }
+
+        public string CombinePaths(string path1, string path2)
+        {
+            if (path1 == null)
+            {
+                throw new ArgumentNullException("path1");
+            }
+
+            if (path2 == null)
+            {
+                throw new ArgumentNullException("path2");
+            }
+
+            string result;
+
+            if (path2.StartsWith("/", StringComparison.Ordinal))
+            {
+                result = path2;
+            }
+            else
+            {
+                result =
+                    path1 +
+                    ((path1.Length == 0) || (path2.Length == 0) || path1.EndsWith("/", StringComparison.Ordinal) ? string.Empty : "/") +
+                    path2;
+            }
+            return result;
+        }
+
         public void AddRawConfiguration(string setting, string value)
         {
+            CheckNotOpened();
             RawConfiguration.Add(setting, value);
         }
 
@@ -1084,7 +1292,7 @@ namespace WinSCP
                 }
                 else
                 {
-                    if (sessionOptions.IsSsh && DefaultConfiguration)
+                    if (sessionOptions.IsSsh && DefaultConfigurationInternal)
                     {
                         throw new ArgumentException("SessionOptions.Protocol is Protocol.Sftp or Protocol.Scp, but SessionOptions.SshHostKeyFingerprint is not set.");
                     }
@@ -1099,13 +1307,22 @@ namespace WinSCP
                     switches.Add(FormatSwitch("privatekey", sessionOptions.SshPrivateKeyPath));
                 }
 
-                if (!string.IsNullOrEmpty(sessionOptions.SshPrivateKeyPassphrase))
+                if (!string.IsNullOrEmpty(sessionOptions.TlsClientCertificatePath))
                 {
-                    if (string.IsNullOrEmpty(sessionOptions.SshPrivateKeyPath))
+                    if (!sessionOptions.IsTls)
                     {
-                        throw new ArgumentException("SessionOptions.SshPrivateKeyPassphrase is set, but sessionOptions.SshPrivateKeyPath is not.");
+                        throw new ArgumentException("SessionOptions.TlsClientCertificatePath is set, but neither SessionOptions.FtpSecure nor SessionOptions.WebdavSecure is enabled.");
                     }
-                    switches.Add(FormatSwitch("passphrase", sessionOptions.SshPrivateKeyPassphrase));
+                    switches.Add(FormatSwitch("clientcert", sessionOptions.TlsClientCertificatePath));
+                }
+
+                if (!string.IsNullOrEmpty(sessionOptions.PrivateKeyPassphrase))
+                {
+                    if (string.IsNullOrEmpty(sessionOptions.SshPrivateKeyPath) && string.IsNullOrEmpty(sessionOptions.TlsClientCertificatePath))
+                    {
+                        throw new ArgumentException("SessionOptions.PrivateKeyPassphrase is set, but neither SessionOptions.SshPrivateKeyPath nor SessionOptions.TlsClientCertificatePath is set.");
+                    }
+                    switches.Add(FormatSwitch("passphrase", sessionOptions.PrivateKeyPassphrase));
                 }
 
                 if (sessionOptions.FtpSecure != FtpSecure.None)
@@ -1121,16 +1338,10 @@ namespace WinSCP
                             switches.Add(FormatSwitch("implicit"));
                             break;
 
-                        case FtpSecure.Explicit: // and ExplicitTls
+                        case FtpSecure.Explicit:
                             switches.Add(FormatSwitch("explicit"));
                             break;
 
-#pragma warning disable 618
-                        case FtpSecure.ExplicitSsl:
-#pragma warning restore 618
-                            switches.Add(FormatSwitch("explicitssl"));
-                            break;
-
                         default:
                             throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "{0} is not supported", sessionOptions.FtpSecure));
                     }
@@ -1139,9 +1350,9 @@ namespace WinSCP
                 if (!string.IsNullOrEmpty(sessionOptions.TlsHostCertificateFingerprint) ||
                     sessionOptions.GiveUpSecurityAndAcceptAnyTlsHostCertificate)
                 {
-                    if ((sessionOptions.FtpSecure == FtpSecure.None) && !sessionOptions.WebdavSecure)
+                    if (!sessionOptions.IsTls)
                     {
-                        throw new ArgumentException("SessionOptions.TlsHostCertificateFingerprint or SessionOptions.GiveUpSecurityAndAcceptAnyTlsHostCertificate is set, neither SessionOptions.FtpSecure nor SessionOptions.WebdavSecure is enabled.");
+                        throw new ArgumentException("SessionOptions.TlsHostCertificateFingerprint or SessionOptions.GiveUpSecurityAndAcceptAnyTlsHostCertificate is set, but neither SessionOptions.FtpSecure nor SessionOptions.WebdavSecure is enabled.");
                     }
                     string tlsHostCertificateFingerprint = sessionOptions.TlsHostCertificateFingerprint;
                     if (sessionOptions.GiveUpSecurityAndAcceptAnyTlsHostCertificate)
@@ -1184,7 +1395,14 @@ namespace WinSCP
                         string value;
                         if (statReader.GetEmptyElementValue("filename", out value))
                         {
-                            fileInfo.Name = value;
+                            string name = value;
+                            int p = name.LastIndexOf('/');
+                            if (p >= 0)
+                            {
+                                name = name.Substring(p + 1);
+                            }
+                            fileInfo.Name = name;
+                            fileInfo.FullName = value;
                         }
                         else if (statReader.IsNonEmptyElement("file"))
                         {
@@ -1597,6 +1815,11 @@ namespace WinSCP
                         }
                     }
 
+                    if (target == null)
+                    {
+                        throw new ArgumentNullException("target");
+                    }
+
                     Type type = target.GetType();
 
                     // RuntimeType.InvokeMember below calls into Binder.BindToMethod (Binder is OleAutBinder)
@@ -1620,9 +1843,14 @@ namespace WinSCP
                             BindingFlags bindingFlags = invokeAttr | BindingFlags.Instance | BindingFlags.Public;
                             method = type.GetMethod(name, bindingFlags);
 
+                            if (args == null)
+                            {
+                                throw new ArgumentNullException("args");
+                            }
+
                             if (method != null)
                             {
-                                // MethodInfo.Invoke does not fill-in optional arguments (contrary to RuntimeType.InvokeMember) 
+                                // MethodInfo.Invoke does not fill-in optional arguments (contrary to RuntimeType.InvokeMember)
                                 ParameterInfo[] parameters = method.GetParameters();
                                 if (args.Length < parameters.Length)
                                 {
@@ -1706,6 +1934,7 @@ namespace WinSCP
         internal bool GuardProcessWithJobInternal { get { return _guardProcessWithJob; } set { CheckNotOpened(); _guardProcessWithJob = value; } }
         internal bool TestHandlesClosedInternal { get; set; }
         internal Dictionary<string, string> RawConfiguration { get; private set; }
+        internal bool DefaultConfigurationInternal { get { return _defaultConfiguration; } }
 
         private ExeSessionProcess _process;
         private DateTime _lastOutput;
@@ -1730,5 +1959,7 @@ namespace WinSCP
         private int _progressHandling;
         private bool _guardProcessWithJob;
         private string _homePath;
+        private string _executableProcessUserName;
+        private SecureString _executableProcessPassword;
     }
 }

+ 57 - 35
dotnet/SessionOptions.cs

@@ -32,10 +32,6 @@ namespace WinSCP
         None = 0,
         Implicit = 1,
         Explicit = 3,
-        [Obsolete("Use FtpSecure.Explicit")]
-        ExplicitTls = Explicit,
-        [Obsolete("Use FtpSecure.Explicit")]
-        ExplicitSsl = 2,
     }
 
     [Guid("2D4EF368-EE80-4C15-AE77-D12AEAF4B00A")]
@@ -57,12 +53,14 @@ namespace WinSCP
         public SecureString SecurePassword { get; set; }
         public TimeSpan Timeout { get { return _timeout; } set { SetTimeout(value); } }
         public int TimeoutInMilliseconds { get { return Tools.TimeSpanToMilliseconds(Timeout); } set { Timeout = Tools.MillisecondsToTimeSpan(value); } }
+        public string PrivateKeyPassphrase { get; set; }
 
         // SSH
         public string SshHostKeyFingerprint { get { return _sshHostKeyFingerprint; } set { SetSshHostKeyFingerprint(value); } }
         public bool GiveUpSecurityAndAcceptAnySshHostKey { get; set; }
         public string SshPrivateKeyPath { get; set; }
-        public string SshPrivateKeyPassphrase { get; set; }
+        [Obsolete("Use PrivateKeyPassphrase")]
+        public string SshPrivateKeyPassphrase { get { return PrivateKeyPassphrase; } set { PrivateKeyPassphrase = value; } }
 
         // FTP
         public FtpMode FtpMode { get; set; }
@@ -75,6 +73,7 @@ namespace WinSCP
         // TLS
         public string TlsHostCertificateFingerprint { get { return _tlsHostCertificateFingerprint; } set { SetHostTlsCertificateFingerprint(value); } }
         public bool GiveUpSecurityAndAcceptAnyTlsHostCertificate { get; set; }
+        public string TlsClientCertificatePath { get; set; }
 
         public void AddRawSettings(string setting, string value)
         {
@@ -83,6 +82,11 @@ namespace WinSCP
 
         public void ParseUrl(string url)
         {
+            if (url == null)
+            {
+                throw new ArgumentNullException("url");
+            }
+
             url = url.Trim();
             const string protocolSeparator = "://";
             int index = url.IndexOf(protocolSeparator, StringComparison.OrdinalIgnoreCase);
@@ -90,37 +94,9 @@ namespace WinSCP
             {
                 throw new ArgumentException("Protocol not specified", "url");
             }
-            string protocol = url.Substring(0, index).Trim();
 
-            FtpSecure = FtpSecure.None;
-
-            if (protocol.Equals("sftp", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Sftp;
-            }
-            else if (protocol.Equals("scp", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Scp;
-            }
-            else if (protocol.Equals("ftp", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Ftp;
-            }
-            else if (protocol.Equals("ftps", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Ftp;
-                FtpSecure = FtpSecure.Implicit;
-            }
-            else if (protocol.Equals("http", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Webdav;
-            }
-            else if (protocol.Equals("https", StringComparison.OrdinalIgnoreCase))
-            {
-                Protocol = Protocol.Webdav;
-                WebdavSecure = true;
-            }
-            else
+            string protocol = url.Substring(0, index).Trim();
+            if (!ParseProtocol(protocol))
             {
                 throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Unknown protocol {0}", protocol), "url");
             }
@@ -241,6 +217,44 @@ namespace WinSCP
             }
         }
 
+        private bool ParseProtocol(string protocol)
+        {
+            bool result = true;
+            FtpSecure = FtpSecure.None;
+
+            if (protocol.Equals("sftp", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Sftp;
+            }
+            else if (protocol.Equals("scp", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Scp;
+            }
+            else if (protocol.Equals("ftp", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Ftp;
+            }
+            else if (protocol.Equals("ftps", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Ftp;
+                FtpSecure = FtpSecure.Implicit;
+            }
+            else if (protocol.Equals("http", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Webdav;
+            }
+            else if (protocol.Equals("https", StringComparison.OrdinalIgnoreCase))
+            {
+                Protocol = Protocol.Webdav;
+                WebdavSecure = true;
+            }
+            else
+            {
+                result = false;
+            }
+            return result;
+        }
+
         private static string EmptyToNull(string s)
         {
             if (string.IsNullOrEmpty(s))
@@ -277,6 +291,14 @@ namespace WinSCP
 
         internal Dictionary<string, string> RawSettings { get; private set; }
         internal bool IsSsh { get { return (Protocol == Protocol.Sftp) || (Protocol == Protocol.Scp); } }
+        internal bool IsTls { get { return GetIsTls(); } }
+
+        private bool GetIsTls()
+        {
+            return
+                ((Protocol == Protocol.Ftp) && (FtpSecure != FtpSecure.None)) ||
+                ((Protocol == Protocol.Webdav) && WebdavSecure);
+        }
 
         private void SetSshHostKeyFingerprint(string s)
         {

+ 26 - 0
dotnet/TransferOptions.cs

@@ -14,6 +14,15 @@ namespace WinSCP
         Automatic = 2,
     }
 
+    [Guid("E0F3C3C2-C812-48F1-A711-E0BD0F703976")]
+    [ComVisible(true)]
+    public enum OverwriteMode
+    {
+        Overwrite = 0,
+        Resume = 1,
+        Append = 2,
+    }
+
     [Guid("155B841F-39D4-40C8-BA87-C79675E14CE3")]
     [ClassInterface(Constants.ClassInterface)]
     [ComVisible(true)]
@@ -25,12 +34,14 @@ namespace WinSCP
         public string FileMask { get; set; }
         public TransferResumeSupport ResumeSupport { get; private set; }
         public int SpeedLimit { get; set; }
+        public OverwriteMode OverwriteMode { get; set; }
 
         public TransferOptions()
         {
             PreserveTimestamp = true;
             TransferMode = TransferMode.Binary;
             ResumeSupport = new TransferResumeSupport();
+            OverwriteMode = OverwriteMode.Overwrite;
         }
 
         internal string ToSwitches()
@@ -80,6 +91,21 @@ namespace WinSCP
                 switches.Add(Session.FormatSwitch("speed", SpeedLimit.ToString(CultureInfo.InvariantCulture)));
             }
 
+            switch (OverwriteMode)
+            {
+                case OverwriteMode.Overwrite:
+                    // noop
+                    break;
+                case OverwriteMode.Resume:
+                    switches.Add(Session.FormatSwitch("resume"));
+                    break;
+                case OverwriteMode.Append:
+                    switches.Add(Session.FormatSwitch("append"));
+                    break;
+                default:
+                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "{0} is not supported", TransferMode));
+            }
+
             return string.Join(" ", switches.ToArray());
         }
     }

+ 5 - 3
dotnet/WinSCPnet.csproj

@@ -12,9 +12,9 @@
     <AssemblyName>WinSCPnet</AssemblyName>
     <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
-    <OutputPath>$(FINAL_PATH)\$(Configuration)</OutputPath>
-    <IntermediateOutputPath>$(INTERM_PATH)\$(Configuration)</IntermediateOutputPath>
-    <BaseIntermediateOutputPath>$(INTERM_PATH)\$(Configuration)</BaseIntermediateOutputPath>
+    <OutputPath>$(FINAL_PATH)\win32\$(Configuration)</OutputPath>
+    <IntermediateOutputPath>$(INTERM_PATH)\win32\$(Configuration)</IntermediateOutputPath>
+    <BaseIntermediateOutputPath>$(INTERM_PATH)\win32\$(Configuration)</BaseIntermediateOutputPath>
     <TargetFrameworkProfile />
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@@ -60,9 +60,11 @@
     <Compile Include="Internal\CallstackAndLock.cs" />
     <Compile Include="Internal\ConsoleCommStruct.cs" />
     <Compile Include="Internal\ExeSessionProcess.cs" />
+    <Compile Include="Internal\GenericSecurity.cs" />
     <Compile Include="Internal\Job.cs" />
     <Compile Include="Internal\Lock.cs" />
     <Compile Include="Internal\Logger.cs" />
+    <Compile Include="Internal\PatientFileStream.cs" />
     <Compile Include="Internal\ProgressHandler.cs" />
     <Compile Include="Internal\SessionElementLogReader.cs" />
     <Compile Include="Internal\Tools.cs" />

+ 1 - 1
dotnet/WinSCPnet.ruleset

@@ -6,4 +6,4 @@
     <Rule Id="CA1704" Action="None" />
     <Rule Id="CA2204" Action="None" />
   </Rules>
-</RuleSet>
+</RuleSet>

+ 1 - 3
dotnet/internal/CallstackAndLock.cs

@@ -1,6 +1,4 @@
-using System.Reflection;
-
-namespace WinSCP
+namespace WinSCP
 {
     internal class CallstackAndLock : Callstack
     {

+ 5 - 1
dotnet/internal/ConsoleCommStruct.cs

@@ -64,7 +64,7 @@ namespace WinSCP
         public enum ProgressSide { Local, Remote }
 
         public ProgressOperation Operation;
-        public ProgressSide Side; 
+        public ProgressSide Side;
 
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
         public string FileName;
@@ -95,7 +95,9 @@ namespace WinSCP
         {
             _session = session;
             _fileMapping = fileMapping;
+            _session.Logger.WriteLineLevel(1, "Acquiring communication structure");
             _ptr = UnsafeNativeMethods.MapViewOfFile(_fileMapping, FileMapAccess.FileMapAllAccess, 0, 0, UIntPtr.Zero);
+            _session.Logger.WriteLineLevel(1, "Acquired communication structure");
             _payloadPtr = new IntPtr(_ptr.ToInt64() + 12);
             _header = (ConsoleCommHeader)Marshal.PtrToStructure(_ptr, typeof(ConsoleCommHeader));
         }
@@ -122,10 +124,12 @@ namespace WinSCP
                     }
                 }
 
+                _session.Logger.WriteLineLevel(1, "Releasing communication structure");
                 if (!UnsafeNativeMethods.UnmapViewOfFile(_ptr))
                 {
                     throw new SessionLocalException(_session, "Cannot release file mapping");
                 }
+                _session.Logger.WriteLineLevel(1, "Released communication structure");
 
                 _ptr = IntPtr.Zero;
             }

+ 14 - 0
dotnet/internal/CustomLogReader.cs

@@ -101,6 +101,20 @@ namespace WinSCP
             }
         }
 
+        public bool TryWaitForEmptyElement(string localName, LogReadFlags flags)
+        {
+            bool result = false;
+            while (!result && Read(flags))
+            {
+                if (IsElement(localName) &&
+                    IsEmptyElement)
+                {
+                    result = true;
+                }
+            }
+            return result;
+        }
+
         public ElementLogReader CreateLogReader()
         {
             return new ElementLogReader(this);

+ 146 - 20
dotnet/internal/ExeSessionProcess.cs

@@ -8,6 +8,8 @@ using Microsoft.Win32;
 using Microsoft.Win32.SafeHandles;
 using System.Runtime.InteropServices;
 using System.Reflection;
+using System.Security.Principal;
+using System.Security.AccessControl;
 
 namespace WinSCP
 {
@@ -40,7 +42,7 @@ namespace WinSCP
                 CheckVersion(executablePath, assemblyVersion);
 
                 string configSwitch;
-                if (_session.DefaultConfiguration)
+                if (_session.DefaultConfigurationInternal)
                 {
                     configSwitch = "/ini=nul ";
                 }
@@ -83,11 +85,6 @@ namespace WinSCP
                 _process.StartInfo.Arguments = arguments;
                 _process.StartInfo.UseShellExecute = false;
                 _process.Exited += ProcessExited;
-                if (_logger.Logging)
-                {
-                    _process.OutputDataReceived += ProcessOutputDataReceived;
-                    _process.ErrorDataReceived += ProcessErrorDataReceived;
-                }
             }
         }
 
@@ -125,6 +122,47 @@ namespace WinSCP
             {
                 _process.StartInfo.Arguments += string.Format(CultureInfo.InvariantCulture, " /console /consoleinstance={0}", _instanceName);
 
+                // When running under IIS in "impersonated" mode, the process starts, but does not do anything.
+                // Supposedly it "displayes" some invisible error message when starting and hangs.
+                // Running it "as the user" helps, eventhough it already runs as the user.
+                // These's probably some difference between "run as" and impersonations
+                if (!string.IsNullOrEmpty(_session.ExecutableProcessUserName))
+                {
+                    _logger.WriteLine("Will run process as {0}", _session.ExecutableProcessUserName);
+
+                    _process.StartInfo.UserName = _session.ExecutableProcessUserName;
+                    _process.StartInfo.Password = _session.ExecutableProcessPassword;
+                    // One of the hints for resolving C0000142 error (see below)
+                    // was setting this property, so that an environment is correctly loaded,
+                    // so DLLs can be found and loaded.
+                    _process.StartInfo.LoadUserProfile = true;
+
+                    // Without granting both window station and desktop access permissions,
+                    // WinSCP process aborts with C0000142 (DLL Initialization Failed) error,
+                    // when "running as user"
+                    _logger.WriteLine("Granting access to window station");
+                    try
+                    {
+                        IntPtr windowStation = UnsafeNativeMethods.GetProcessWindowStation();
+                        GrantAccess(windowStation, (int)WindowStationRights.AllAccess);
+                    }
+                    catch (Exception e)
+                    {
+                        throw new SessionLocalException(_session, "Error granting access to window station", e);
+                    }
+
+                    _logger.WriteLine("Granting access to desktop");
+                    try
+                    {
+                        IntPtr desktop = UnsafeNativeMethods.GetThreadDesktop(UnsafeNativeMethods.GetCurrentThreadId());
+                        GrantAccess(desktop, (int)DesktopRights.AllAccess);
+                    }
+                    catch (Exception e)
+                    {
+                        throw new SessionLocalException(_session, "Error granting access to desktop", e);
+                    }
+                }
+
                 _logger.WriteLine("Starting \"{0}\" {1}", _process.StartInfo.FileName, _process.StartInfo.Arguments);
 
                 _process.Start();
@@ -137,19 +175,41 @@ namespace WinSCP
             }
         }
 
-        private void ProcessExited(object sender, EventArgs e)
+        // Handles returned by GetProcessWindowStation and GetThreadDesktop should not be closed
+        internal class NoopSafeHandle : SafeHandle
         {
-            _logger.WriteLine("Process {0} exited with exit code {1}", _process.Id, _process.ExitCode);
+            public NoopSafeHandle(IntPtr handle) :
+                base(handle, false)
+            {
+            }
+
+            public override bool IsInvalid
+            {
+                get { return false; }
+            }
+
+            protected override bool ReleaseHandle()
+            {
+                return true;
+            }
         }
 
-        private void ProcessOutputDataReceived(object sender, DataReceivedEventArgs e)
+        private void GrantAccess(IntPtr handle, int accessMask)
         {
-            _logger.WriteLine("Process output: {0}", e.Data);
+            using (SafeHandle safeHandle = new NoopSafeHandle(handle))
+            {
+                GenericSecurity security =
+                    new GenericSecurity(false, ResourceType.WindowObject, safeHandle, AccessControlSections.Access);
+
+                security.AddAccessRule(
+                    new GenericAccessRule(new NTAccount(_session.ExecutableProcessUserName), accessMask, AccessControlType.Allow));
+                security.Persist(safeHandle, AccessControlSections.Access);
+            }
         }
 
-        private void ProcessErrorDataReceived(object sender, DataReceivedEventArgs e)
+        private void ProcessExited(object sender, EventArgs e)
         {
-            _logger.WriteLine("Process error output: {0}", e.Data);
+            _logger.WriteLine("Process {0} exited with exit code {1}", _process.Id, _process.ExitCode);
         }
 
         private bool AbortedOrExited()
@@ -176,8 +236,10 @@ namespace WinSCP
             {
                 while (!AbortedOrExited())
                 {
+                    _logger.WriteLineLevel(1, "Waiting for request event");
                     if (_requestEvent.WaitOne(100, false))
                     {
+                        _logger.WriteLineLevel(1, "Got request event");
                         ProcessEvent();
                     }
                 }
@@ -431,12 +493,43 @@ namespace WinSCP
             }
         }
 
-        private static SafeFileHandle CreateFileMapping(string fileMappingName)
+        private SafeFileHandle CreateFileMapping(string fileMappingName)
         {
-            return
-                UnsafeNativeMethods.CreateFileMapping(
-                    new SafeFileHandle(new IntPtr(-1), true), IntPtr.Zero, FileMapProtection.PageReadWrite, 0,
-                    ConsoleCommStruct.Size, fileMappingName);
+            unsafe
+            {
+                IntPtr securityAttributesPtr = IntPtr.Zero;
+
+                // We use the EventWaitHandleSecurity only to generate the descriptor binary form
+                // that does not differ for object types, so we abuse the existing "event handle" implementation,
+                // not to have to create the file mapping SecurityAttributes via P/Invoke.
+
+                // .NET 4 supports MemoryMappedFile and MemoryMappedFileSecurity natively already
+
+                EventWaitHandleSecurity security = CreateSecurity((EventWaitHandleRights)FileMappingRights.AllAccess);
+
+                if (security != null)
+                {
+                    SecurityAttributes securityAttributes = new SecurityAttributes();
+                    securityAttributes.nLength = (uint)Marshal.SizeOf(securityAttributes);
+
+                    byte[] descriptorBinaryForm = security.GetSecurityDescriptorBinaryForm();
+                    byte * buffer = stackalloc byte[descriptorBinaryForm.Length];
+                    for (int i = 0; i < descriptorBinaryForm.Length; i++)
+                    {
+                        buffer[i] = descriptorBinaryForm[i];
+                    }
+                    securityAttributes.lpSecurityDescriptor = (IntPtr)buffer;
+
+                    int length = Marshal.SizeOf(typeof(SecurityAttributes));
+                    securityAttributesPtr = Marshal.AllocHGlobal(length);
+                    Marshal.StructureToPtr(securityAttributes, securityAttributesPtr, false);
+                }
+
+                return
+                    UnsafeNativeMethods.CreateFileMapping(
+                        new SafeFileHandle(new IntPtr(-1), true), securityAttributesPtr, FileMapProtection.PageReadWrite, 0,
+                        ConsoleCommStruct.Size, fileMappingName);
+            }
         }
 
         private ConsoleCommStruct AcquireCommStruct()
@@ -448,11 +541,44 @@ namespace WinSCP
         {
             bool createdNew;
             _logger.WriteLine("Creating event {0}", name);
-            ev = new EventWaitHandle(false, EventResetMode.AutoReset, name, out createdNew);
-            _logger.WriteLine("Created event {0} with handle {1}, new {2}", name, ev.SafeWaitHandle.DangerousGetHandle(), createdNew);
+
+            EventWaitHandleSecurity security = CreateSecurity(EventWaitHandleRights.FullControl);
+
+            ev = new EventWaitHandle(false, EventResetMode.AutoReset, name, out createdNew, security);
+            _logger.WriteLine(
+                "Created event {0} with handle {1} with security {2}, new {3}",
+                name, ev.SafeWaitHandle.DangerousGetHandle(),
+                (security != null ? security.GetSecurityDescriptorSddlForm(AccessControlSections.All) : "none"), createdNew);
             return createdNew;
         }
 
+        private EventWaitHandleSecurity CreateSecurity(EventWaitHandleRights eventRights)
+        {
+            EventWaitHandleSecurity security = null;
+
+            // When "running as user", we have to grant the target user permissions to the objects (events and file mapping) explicitly
+            if (!string.IsNullOrEmpty(_session.ExecutableProcessUserName))
+            {
+                security = new EventWaitHandleSecurity();
+                IdentityReference si;
+                try
+                {
+                    si = new NTAccount(_session.ExecutableProcessUserName);
+                }
+                catch (Exception e)
+                {
+                    throw new SessionLocalException(_session, string.Format(CultureInfo.CurrentCulture, "Error resolving account {0}", _session.ExecutableProcessUserName), e);
+                }
+
+                EventWaitHandleAccessRule rule =
+                    new EventWaitHandleAccessRule(
+                        si, eventRights, AccessControlType.Allow);
+                security.AddAccessRule(rule);
+            }
+
+            return security;
+        }
+
         private EventWaitHandle CreateEvent(string name)
         {
             EventWaitHandle ev;
@@ -701,7 +827,7 @@ namespace WinSCP
                 {
                     throw new SessionLocalException(
                         _session, string.Format(CultureInfo.CurrentCulture,
-                            "The version of {0} ({1}) does not match version of this assembly {2} ({3}). You can disable this check using Session.DisableVersionCheck (not recommended).",
+                            "The version of {0} ({1}) does not match version of this assembly {2} ({3}).",
                             exePath, version.ProductVersion, _logger.GetAssemblyFilePath(), assemblyVersion.ProductVersion));
                 }
             }

+ 71 - 0
dotnet/internal/GenericSecurity.cs

@@ -0,0 +1,71 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Security.AccessControl;
+using System.Security.Principal;
+
+namespace WinSCP
+{
+    // All the code to manipulate security object is available in .NET framework,
+    // but its API tries to be type-safe and handle-safe, enforcing special implemnentation
+    // (to otherwise a generic WinAPI) for each handle type. This is to make sure
+    // only correct set of permissions can be set for corresponding object types and
+    // mainly that handles do not leak.
+    // Hence the AccessRule and NativeObjectSecurity clases are abstract.
+    // This is the simplest possible implementation that yet allows us to make use
+    // of the existing .NET implementation, sparing necessity to P/Invoke the underlying WinAPI.
+
+    internal class GenericAccessRule : AccessRule
+    {
+        public GenericAccessRule(IdentityReference identity, int accessMask, AccessControlType type) :
+            base(identity, accessMask, false, InheritanceFlags.None, PropagationFlags.None, type)
+        {
+        }
+    }
+
+    internal class GenericSecurity : NativeObjectSecurity
+    {
+        public GenericSecurity(bool isContainer, ResourceType resType, SafeHandle objectHandle, AccessControlSections sectionsRequested)
+            : base(isContainer, resType, objectHandle, sectionsRequested)
+        {
+        }
+
+        new public void Persist(SafeHandle handle, AccessControlSections includeSections)
+        {
+            base.Persist(handle, includeSections);
+        }
+
+        new public void AddAccessRule(AccessRule rule)
+        {
+            base.AddAccessRule(rule);
+        }
+
+        #region NativeObjectSecurity Abstract Method Overrides
+
+        public override Type AccessRightType
+        {
+            get { throw new NotImplementedException(); }
+        }
+
+        public override AccessRule AccessRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override Type AccessRuleType
+        {
+            get { return typeof(AccessRule); }
+        }
+
+        public override AuditRule AuditRuleFactory(System.Security.Principal.IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
+        {
+            throw new NotImplementedException();
+        }
+
+        public override Type AuditRuleType
+        {
+            get { return typeof(AuditRule); }
+        }
+
+        #endregion
+    }
+}

+ 0 - 1
dotnet/internal/Job.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Diagnostics;
 using System.Runtime.InteropServices;
 
 namespace WinSCP

+ 12 - 4
dotnet/internal/Logger.cs

@@ -86,13 +86,13 @@ namespace WinSCP
             _performanceCounters.Add(counter);
         }
 
-        public void WriteLine(string message)
+        public void WriteLine(string line)
         {
             lock (_logLock)
             {
                 if (Logging)
                 {
-                    DoWriteLine(message);
+                    DoWriteLine(line);
                 }
             }
         }
@@ -108,6 +108,14 @@ namespace WinSCP
             }
         }
 
+        public void WriteLineLevel(int level, string line)
+        {
+            if (LogLevel >= level)
+            {
+                WriteLine(line);
+            }
+        }
+
         private static int GetThread()
         {
             return Thread.CurrentThread.ManagedThreadId;
@@ -157,7 +165,7 @@ namespace WinSCP
 
         public void WriteCounters()
         {
-            if (Logging && (_logLevel >= 1))
+            if (Logging && (LogLevel >= 1))
             {
                 try
                 {
@@ -179,7 +187,7 @@ namespace WinSCP
 
         public void WriteProcesses()
         {
-            if (Logging && (_logLevel >= 1))
+            if (Logging && (LogLevel >= 1))
             {
                 try
                 {

+ 1 - 1
dotnet/internal/OperationResultGuard.cs

@@ -14,7 +14,7 @@ namespace WinSCP
         {
             _session.UnregisterOperationResult(_operationResult);
         }
-        
+
         private readonly Session _session;
         private readonly OperationResultBase _operationResult;
     }

+ 42 - 0
dotnet/internal/PatientFileStream.cs

@@ -0,0 +1,42 @@
+using System.IO;
+
+namespace WinSCP
+{
+    internal class PatientFileStream : FileStream
+    {
+        public PatientFileStream(Session session, string path, FileMode mode, FileAccess access, FileShare share) :
+            base(path, mode, access, share)
+        {
+            _session = session;
+        }
+
+        public override int Read(byte[] array, int offset, int count)
+        {
+            int result;
+
+            int interval = 50;
+            do
+            {
+                result = base.Read(array, offset, count);
+                if (result == 0)
+                {
+                    _session.Logger.WriteLine("Waiting for log update and dispatching events for {0}", interval);
+                    _session.DispatchEvents(interval);
+                    _session.CheckForTimeout();
+                    if (interval < 500)
+                    {
+                        interval *= 2;
+                    }
+                }
+            }
+            // We always want to return something.
+            // No attempt to detect end real of file is needed,
+            // as we should not try to read beyond the final closing tag
+            while (result == 0);
+
+            return result;
+        }
+
+        private Session _session;
+    }
+}

+ 1 - 5
dotnet/internal/SessionElementLogReader.cs

@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace WinSCP
+namespace WinSCP
 {
     internal class SessionElementLogReader : ElementLogReader
     {

+ 10 - 10
dotnet/internal/SessionLogReader.cs

@@ -77,7 +77,7 @@ namespace WinSCP
 
         private bool DoRead()
         {
-            int interval = 125;
+            int interval = 50;
             bool result;
 
             do
@@ -120,6 +120,10 @@ namespace WinSCP
                 {
                     Cleanup();
 
+                    // We hope this code is not needed anymore.
+                    // keeping it just in case the XmlLogReader by passes
+                    // our override of PatientFileStream.Read uing other read method.
+#if !DEBUG
                     if (!_closed)
                     {
                         // If log was not closed, it is likely the XML is not well-formed
@@ -129,6 +133,7 @@ namespace WinSCP
                         result = false;
                     }
                     else
+#endif
                     {
                         // check if the the root cause was session abort
                         Session.CheckForTimeout();
@@ -165,7 +170,7 @@ namespace WinSCP
                 {
                     // alterative to File.ReadAllText with write-sharing
                     // (note that the StreamReader disposes the Stream)
-                    using (StreamReader reader = new StreamReader(OpenLogFileWithWriteSharing(), Encoding.UTF8))
+                    using (StreamReader reader = new StreamReader(new FileStream(Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8))
                     {
                         string contents = reader.ReadToEnd();
                         if ((_logged == null) || (_logged != contents))
@@ -199,7 +204,7 @@ namespace WinSCP
                 // First try to open file without write sharing.
                 // This fails, if WinSCP is still writing to the log file.
                 // This is done only as a way to detect that log file is not complete yet.
-                _stream = File.Open(Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+                _stream = new PatientFileStream(Session, Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                 _closed = true;
                 LogContents();
             }
@@ -207,7 +212,7 @@ namespace WinSCP
             {
                 Session.Logger.WriteLine("Opening log with write sharing");
                 // If log file is still being written to, open it with write sharing
-                _stream = OpenLogFileWithWriteSharing();
+                _stream = new PatientFileStream(Session, Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                 _closed = false;
             }
 
@@ -227,11 +232,6 @@ namespace WinSCP
             }
         }
 
-        private FileStream OpenLogFileWithWriteSharing()
-        {
-            return File.Open(Session.XmlLogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-        }
-
         internal override XmlReader Reader
         {
             get
@@ -246,7 +246,7 @@ namespace WinSCP
 
         private int _position;
         private XmlReader _reader;
-        private FileStream _stream;
+        private PatientFileStream _stream;
         private bool _closed;
         private string _logged;
     }

+ 74 - 2
dotnet/internal/UnsafeNativeMethods.cs

@@ -82,11 +82,74 @@ namespace WinSCP
         FileMapAllAccess = 0x001f,
         FileMapExecute = 0x0020,
     }
-    
+
+    [Flags]
+    internal enum StandardRights
+    {
+        Delete = 0x00010000,
+        ReadPermissions = 0x00020000,
+        WritePermissions = 0x00040000,
+        TakeOwnership = 0x00080000,
+        Synchronize = 0x00100000,
+
+        Required = Delete | ReadPermissions | WritePermissions | TakeOwnership,
+    }
+
+    // Isn't this the same as FileMapAccess?
+    [Flags]
+    internal enum FileMappingRights
+    {
+        FileMapCopy = 1,
+        FileMapWrite = 2,
+        FileMapRead = 4,
+        SectionMapExecute = 8,
+        SectionExtendSize = 16,
+        FileMapExecute = 32,
+
+        AllAccess = FileMapCopy | FileMapWrite | FileMapRead | SectionMapExecute | SectionExtendSize |
+            StandardRights.Required
+    }
+
+    [Flags]
+    internal enum DesktopRights
+    {
+        ReadObjects       = 1,
+        CreateWindow      = 2,
+        CreateMenu        = 4,
+        HookControl       = 8,
+        JournalRecord     = 16,
+        JournalPlayback   = 32,
+        Enumerate         = 64,
+        WriteObjects      = 128,
+        SwitchDesktop     = 256,
+
+        AllAccess = ReadObjects | CreateWindow | CreateMenu | HookControl |
+            JournalRecord | JournalPlayback | Enumerate | WriteObjects | SwitchDesktop |
+            StandardRights.Required
+    }
+
+    [Flags]
+    internal enum WindowStationRights
+    {
+        EnumDesktops = 1,
+        ReadAttributes = 2,
+        AccessClipboard = 4,
+        CreateDesktop = 8,
+        WriteAttributes = 16,
+        AccessGlobalAtoms = 32,
+        ExitWindows = 64,
+        Enumerate = 256,
+        ReadScreen = 512,
+
+        AllAccess = EnumDesktops  | ReadAttributes  | AccessClipboard | CreateDesktop |
+            WriteAttributes | AccessGlobalAtoms | ExitWindows | Enumerate | ReadScreen |
+            StandardRights.Required
+    }
+
     internal static class UnsafeNativeMethods
     {
         public const int ERROR_ALREADY_EXISTS = 183;
-        
+
         [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
         public static extern SafeFileHandle CreateFileMapping(SafeFileHandle hFile, IntPtr lpAttributes, FileMapProtection fProtect, int dwMaximumSizeHigh, int dwMaximumSizeLow, string lpName);
 
@@ -106,5 +169,14 @@ namespace WinSCP
         [DllImport("kernel32", SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
         public static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
+
+        [DllImport("user32.dll", SetLastError = true)]
+        public static extern IntPtr GetProcessWindowStation();
+
+        [DllImport("user32.dll", SetLastError = true)]
+        public static extern IntPtr GetThreadDesktop(int dwThreadId);
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        public static extern int GetCurrentThreadId();
     }
 }

+ 373 - 373
dotnet/license-dotnet.txt

@@ -1,373 +1,373 @@
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
-    means each individual or legal entity that creates, contributes to
-    the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
-    means the combination of the Contributions of others (if any) used
-    by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
-    means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
-    means Source Code Form to which the initial Contributor has attached
-    the notice in Exhibit A, the Executable Form of such Source Code
-    Form, and Modifications of such Source Code Form, in each case
-    including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
-    means
-
-    (a) that the initial Contributor has attached the notice described
-        in Exhibit B to the Covered Software; or
-
-    (b) that the Covered Software was made available under the terms of
-        version 1.1 or earlier of the License, but not also under the
-        terms of a Secondary License.
-
-1.6. "Executable Form"
-    means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
-    means a work that combines Covered Software with other material, in 
-    a separate file or files, that is not Covered Software.
-
-1.8. "License"
-    means this document.
-
-1.9. "Licensable"
-    means having the right to grant, to the maximum extent possible,
-    whether at the time of the initial grant or subsequently, any and
-    all of the rights conveyed by this License.
-
-1.10. "Modifications"
-    means any of the following:
-
-    (a) any file in Source Code Form that results from an addition to,
-        deletion from, or modification of the contents of Covered
-        Software; or
-
-    (b) any new file in Source Code Form that contains any Covered
-        Software.
-
-1.11. "Patent Claims" of a Contributor
-    means any patent claim(s), including without limitation, method,
-    process, and apparatus claims, in any patent Licensable by such
-    Contributor that would be infringed, but for the grant of the
-    License, by the making, using, selling, offering for sale, having
-    made, import, or transfer of either its Contributions or its
-    Contributor Version.
-
-1.12. "Secondary License"
-    means either the GNU General Public License, Version 2.0, the GNU
-    Lesser General Public License, Version 2.1, the GNU Affero General
-    Public License, Version 3.0, or any later versions of those
-    licenses.
-
-1.13. "Source Code Form"
-    means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
-    means an individual or a legal entity exercising rights under this
-    License. For legal entities, "You" includes any entity that
-    controls, is controlled by, or is under common control with You. For
-    purposes of this definition, "control" means (a) the power, direct
-    or indirect, to cause the direction or management of such entity,
-    whether by contract or otherwise, or (b) ownership of more than
-    fifty percent (50%) of the outstanding shares or beneficial
-    ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
-    Licensable by such Contributor to use, reproduce, make available,
-    modify, display, perform, distribute, and otherwise exploit its
-    Contributions, either on an unmodified basis, with Modifications, or
-    as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
-    for sale, have made, import, and otherwise transfer either its
-    Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
-    or
-
-(b) for infringements caused by: (i) Your and any other third party's
-    modifications of Covered Software, or (ii) the combination of its
-    Contributions with other software (except as part of its Contributor
-    Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
-    its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
-    Form, as described in Section 3.1, and You must inform recipients of
-    the Executable Form how they can obtain a copy of such Source Code
-    Form by reasonable means in a timely manner, at a charge no more
-    than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
-    License, or sublicense it under different terms, provided that the
-    license for the Executable Form does not attempt to limit or alter
-    the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-*                                                                      *
-*  6. Disclaimer of Warranty                                           *
-*  -------------------------                                           *
-*                                                                      *
-*  Covered Software is provided under this License on an "as is"       *
-*  basis, without warranty of any kind, either expressed, implied, or  *
-*  statutory, including, without limitation, warranties that the       *
-*  Covered Software is free of defects, merchantable, fit for a        *
-*  particular purpose or non-infringing. The entire risk as to the     *
-*  quality and performance of the Covered Software is with You.        *
-*  Should any Covered Software prove defective in any respect, You     *
-*  (not any Contributor) assume the cost of any necessary servicing,   *
-*  repair, or correction. This disclaimer of warranty constitutes an   *
-*  essential part of this License. No use of any Covered Software is   *
-*  authorized under this License except under this disclaimer.         *
-*                                                                      *
-************************************************************************
-
-************************************************************************
-*                                                                      *
-*  7. Limitation of Liability                                          *
-*  --------------------------                                          *
-*                                                                      *
-*  Under no circumstances and under no legal theory, whether tort      *
-*  (including negligence), contract, or otherwise, shall any           *
-*  Contributor, or anyone who distributes Covered Software as          *
-*  permitted above, be liable to You for any direct, indirect,         *
-*  special, incidental, or consequential damages of any character      *
-*  including, without limitation, damages for lost profits, loss of    *
-*  goodwill, work stoppage, computer failure or malfunction, or any    *
-*  and all other commercial damages or losses, even if such party      *
-*  shall have been informed of the possibility of such damages. This   *
-*  limitation of liability shall not apply to liability for death or   *
-*  personal injury resulting from such party's negligence to the       *
-*  extent applicable law prohibits such limitation. Some               *
-*  jurisdictions do not allow the exclusion or limitation of           *
-*  incidental or consequential damages, so this exclusion and          *
-*  limitation may not apply to You.                                    *
-*                                                                      *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
-  This Source Code Form is subject to the terms of the Mozilla Public
-  License, v. 2.0. If a copy of the MPL was not distributed with this
-  file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
-  This Source Code Form is "Incompatible With Secondary Licenses", as
-  defined by the Mozilla Public License, v. 2.0.
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.

+ 4 - 5
dotnet/properties/AssemblyInfo.cs

@@ -2,7 +2,7 @@
 using System.Reflection;
 using System.Runtime.InteropServices;
 
-// General Information about an assembly is controlled through the following 
+// General Information about an assembly is controlled through the following
 // set of attributes. Change these attribute values to modify the information
 // associated with an assembly.
 [assembly: AssemblyTitle("WinSCPnet")]
@@ -19,9 +19,8 @@ using System.Runtime.InteropServices;
 // The following GUID is for the ID of the typelib if this project is exposed to COM
 [assembly: Guid("a0b93468-d98a-4845-a234-8076229ad93f")]
 
-[assembly: AssemblyVersion("1.2.10.0")]
-[assembly: AssemblyFileVersion("1.2.10.0")]
-[assembly: AssemblyInformationalVersionAttribute("5.7.7.0")]
+[assembly: AssemblyVersion("1.3.0.0")]
+[assembly: AssemblyFileVersion("1.3.0.0")]
+[assembly: AssemblyInformationalVersionAttribute("5.8.0.0")]
 
 [assembly: CLSCompliant(true)]
-

+ 20 - 0
libs/buildlibs.bat

@@ -1,4 +1,5 @@
 @echo off
+set BUILDTOOLS_PATH=%1
 if not exist lib mkdir lib
 
 rem ==== OpenSSL ====
@@ -61,4 +62,23 @@ exit
 
 :SKIP_NEON
 
+rem ==== PuTTY VS ====
+
+if exist lib\PuTTYVS.lib (
+echo PuTTYVS already built
+goto SKIP_PUTTYVS
+)
+
+echo Building PuTTYVS ...
+cd puttyvs
+call build.bat %BUILDTOOLS_PATH%
+cd ..
+
+if not exist lib\PuTTYVS.lib (
+echo PuTTYVS build failed
+exit
+)
+
+:SKIP_PUTTYVS
+
 echo All done

+ 5 - 0
libs/cleaninterm.bat

@@ -18,4 +18,9 @@ rem ==== neon ====
 echo Cleaning up neon ...
 rmdir /s /q neon\tmp
 
+rem ==== PuTTYVS ====
+
+echo Cleaning up PuTTYVS ...
+rmdir /s /q puttyvs\Release
+
 echo All done

+ 30 - 0
libs/neon/src/ne_locks.c

@@ -676,6 +676,36 @@ int ne_lock_discover(ne_session *sess, const char *uri,
     return ret;
 }
 
+#ifdef WINSCP
+
+void * ne_lock_register_discovery(ne_propfind_handler * handler)
+{
+    struct discover_ctx * ctx = ne_calloc(sizeof *ctx);
+    
+    ctx->results = NULL;
+    ctx->userdata = NULL;
+    ctx->cdata = ne_buffer_create();
+    ctx->phandler = handler;
+ 
+    ne_propfind_set_private(handler, ld_create, ld_destroy, ctx);
+    
+    ne_xml_push_handler(ne_propfind_get_parser(handler), 
+                        ld_startelm, ld_cdata, end_element_ldisc, ctx);
+
+    return ctx;
+}
+
+void ne_lock_discovery_free(void * actx)
+{
+    struct discover_ctx * ctx = actx;
+    
+    ne_buffer_destroy(ctx->cdata);
+
+    ne_free(ctx);
+}
+
+#endif
+
 static void add_timeout_header(ne_request *req, long timeout)
 {
     if (timeout == NE_TIMEOUT_INFINITE) {

+ 9 - 0
libs/neon/src/ne_locks.h

@@ -144,6 +144,15 @@ typedef void (*ne_lock_result)(void *userdata, const struct ne_lock *lock,
 int ne_lock_discover(ne_session *sess, const char *path,
 		     ne_lock_result result, void *userdata);
 
+#ifdef WINSCP
+
+#include "ne_props.h"
+
+void * ne_lock_register_discovery(ne_propfind_handler * handler);
+void ne_lock_discovery_free(void * ctx);
+
+#endif
+
 /* The ne_lock_using_* functions should be used before dispatching a
  * request which modify resources.  If a lock store has been
  * registered with the session associated with the request, and locks

+ 23 - 0
libs/neon/src/ne_openssl.c

@@ -891,6 +891,29 @@ static ne_ssl_client_cert *parse_client_cert(PKCS12 *p12)
     }
 }
 
+#ifdef WINSCP
+ne_ssl_client_cert * ne_ssl_clicert_create(X509 * cert, EVP_PKEY * pkey)
+{
+    /* Copy from parse_client_cert */
+    
+    /* Success - no password needed for decryption. */
+    int len = 0;
+    unsigned char *name;
+    ne_ssl_client_cert *cc;
+
+    name = X509_alias_get0(cert, &len);
+    
+    cc = ne_calloc(sizeof *cc);
+    cc->pkey = pkey;
+    cc->decrypted = 1;
+    if (name && len > 0)
+        cc->friendly_name = ne_strndup((char *)name, len);
+    populate_cert(&cc->cert, cert);
+
+    return cc;
+}
+#endif
+
 ne_ssl_client_cert *ne_ssl_clicert_import(const unsigned char *buffer, 
                                           size_t buflen)
 {

+ 10 - 5
libs/neon/src/ne_socket.c

@@ -333,11 +333,6 @@ int ne_sock_init(void)
     if (err != 0) {
 	return init_state = -1;
     }
-#ifdef HAVE_SSPI
-    if (ne_sspi_init() < 0) {
-        return init_state = -1;
-    }
-#endif
 #endif
 
 #ifdef NE_HAVE_SOCKS
@@ -359,6 +354,16 @@ int ne_sock_init(void)
 #endif
 
     init_state = 1;
+
+#ifdef WIN32    
+#ifdef HAVE_SSPI
+    // This fails on Wine, and we do not want to abort
+    // whole Neon initialization because of that
+    if (ne_sspi_init() < 0) {
+        return -2;
+    }
+#endif
+#endif
     return 0;
 }
 

+ 6 - 0
libs/neon/src/ne_ssl.h

@@ -121,6 +121,12 @@ void ne_ssl_cert_free(ne_ssl_certificate *cert);
  * "decrypted" state.  */
 typedef struct ne_ssl_client_cert_s ne_ssl_client_cert;
 
+#ifdef WINSCP
+typedef struct x509_st X509;
+typedef struct evp_pkey_st EVP_PKEY;
+ne_ssl_client_cert * ne_ssl_clicert_create(X509 * cert, EVP_PKEY * pkey);
+#endif
+
 /* Read a client certificate (and private key) in PKCS#12 format from
  * file 'filename'; returns NULL if the file could not be parsed, or
  * otherwise returning a client certificate object.  The returned

+ 82 - 11
libs/openssl/Makefile

@@ -15,7 +15,7 @@
 
 # Set your compiler options
 CC=bcc32
-CFLAG=-DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl -w-eff -w-sus -w-dup -w-spa -w-csu -w-rvl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_CMS -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_KRB5 -DOPENSSL_NO_ENGINE -DOPENSSL_NO_DYNAMIC_ENGINE -DOPENSSL_DISABLE_OLD_DES_SUPPORT -DNO_CHMOD -DOPENSSL_NO_DGRAM -DDOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_WHIRLPOOL
+CFLAG=-DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl -w-eff -w-sus -w-dup -w-spa -w-csu -w-rvl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_KRB5 -DOPENSSL_NO_ENGINE -DOPENSSL_NO_DYNAMIC_ENGINE -DOPENSSL_DISABLE_OLD_DES_SUPPORT -DNO_CHMOD -DOPENSSL_NO_DGRAM -DDOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_WHIRLPOOL
 LIB_CFLAG=
 
 # The OpenSSL directory
@@ -108,6 +108,7 @@ EXHEADER=$(INCO_D)\e_os2.h \
     $(INCO_D)\kssl.h $(INCO_D)\srtp.h $(INCO_D)\cmac.h \
     $(INCO_D)\srp.h \
     $(INCO_D)\ec.h $(INCO_D)\ecdh.h $(INCO_D)\ecdsa.h \
+    $(INCO_D)\cms.h
 
 E_OBJ=$(OBJ_D)\verify.obj \
     $(OBJ_D)\asn1pars.obj $(OBJ_D)\req.obj $(OBJ_D)\dgst.obj \
@@ -135,10 +136,11 @@ SSLOBJ=$(OBJ_D)\s2_meth.obj \
     $(OBJ_D)\s23_meth.obj $(OBJ_D)\s23_srvr.obj $(OBJ_D)\s23_clnt.obj \
     $(OBJ_D)\s23_lib.obj $(OBJ_D)\s23_pkt.obj $(OBJ_D)\t1_meth.obj \
     $(OBJ_D)\t1_srvr.obj $(OBJ_D)\t1_clnt.obj $(OBJ_D)\t1_lib.obj \
-    $(OBJ_D)\t1_enc.obj $(OBJ_D)\t1_reneg.obj $(OBJ_D)\tls_srp.obj \
+    $(OBJ_D)\t1_enc.obj $(OBJ_D)\t1_reneg.obj $(OBJ_D)\t1_ext.obj \
+    $(OBJ_D)\tls_srp.obj \
     $(OBJ_D)\d1_meth.obj $(OBJ_D)\d1_srvr.obj $(OBJ_D)\d1_srtp.obj \
     $(OBJ_D)\d1_clnt.obj $(OBJ_D)\d1_lib.obj $(OBJ_D)\d1_pkt.obj \
-    $(OBJ_D)\d1_both.obj $(OBJ_D)\d1_enc.obj $(OBJ_D)\ssl_lib.obj \
+    $(OBJ_D)\d1_both.obj $(OBJ_D)\ssl_lib.obj \
     $(OBJ_D)\ssl_err2.obj $(OBJ_D)\ssl_cert.obj $(OBJ_D)\ssl_sess.obj \
     $(OBJ_D)\ssl_ciph.obj $(OBJ_D)\ssl_stat.obj $(OBJ_D)\ssl_rsa.obj \
     $(OBJ_D)\ssl_asn1.obj $(OBJ_D)\ssl_txt.obj $(OBJ_D)\ssl_algs.obj \
@@ -153,7 +155,8 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\md4_one.obj $(OBJ_D)\md5_dgst.obj $(MD5_ASM_OBJ) \
     $(OBJ_D)\md5_one.obj $(OBJ_D)\cbc128.obj $(OBJ_D)\cfb128.obj \
     $(OBJ_D)\ofb128.obj $(OBJ_D)\ccm128.obj \
-    $(OBJ_D)\xts128.obj $(OBJ_D)\gcm128.obj $(OBJ_D)\ctr128.obj \
+    $(OBJ_D)\xts128.obj $(OBJ_D)\wrap128.obj \
+    $(OBJ_D)\gcm128.obj $(OBJ_D)\ctr128.obj \
     $(OBJ_D)\sha_dgst.obj $(OBJ_D)\sha1dgst.obj \
     $(SHA1_ASM_OBJ) $(OBJ_D)\sha_one.obj $(OBJ_D)\sha1_one.obj \
     $(OBJ_D)\sha256.obj $(OBJ_D)\sha512.obj $(OBJ_D)\hmac.obj \
@@ -203,7 +206,8 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\dso_win32.obj $(OBJ_D)\dh_asn1.obj \
     $(OBJ_D)\dh_gen.obj $(OBJ_D)\dh_key.obj $(OBJ_D)\dh_lib.obj \
     $(OBJ_D)\dh_check.obj $(OBJ_D)\dh_err.obj $(OBJ_D)\dh_depr.obj \
-    $(OBJ_D)\dh_pmeth.obj $(OBJ_D)\dh_ameth.obj \
+    $(OBJ_D)\dh_pmeth.obj $(OBJ_D)\dh_ameth.obj $(OBJ_D)\dh_rfc5114.obj \
+    $(OBJ_D)\dh_kdf.obj  \
     $(OBJ_D)\buffer.obj $(OBJ_D)\buf_err.obj $(OBJ_D)\buf_str.obj \
     $(OBJ_D)\bio_lib.obj \
     $(OBJ_D)\bio_cb.obj $(OBJ_D)\bio_err.obj $(OBJ_D)\bss_mem.obj \
@@ -222,7 +226,7 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\evp_enc.obj $(OBJ_D)\evp_key.obj $(OBJ_D)\evp_acnf.obj \
     $(OBJ_D)\e_des.obj $(OBJ_D)\e_bf.obj $(OBJ_D)\e_idea.obj \
     $(OBJ_D)\e_des3.obj $(OBJ_D)\e_rc4.obj $(OBJ_D)\e_aes.obj \
-    $(OBJ_D)\e_aes_cbc_hmac_sha1.obj \
+    $(OBJ_D)\e_aes_cbc_hmac_sha1.obj $(OBJ_D)\e_aes_cbc_hmac_sha256.obj \
     $(OBJ_D)\names.obj $(OBJ_D)\e_xcbc_d.obj $(OBJ_D)\e_rc2.obj \
     $(OBJ_D)\e_cast.obj $(OBJ_D)\m_null.obj \
     $(OBJ_D)\m_md4.obj $(OBJ_D)\m_md5.obj \
@@ -263,6 +267,7 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\x_pkey.obj $(OBJ_D)\a_bool.obj \
     $(OBJ_D)\x_exten.obj $(OBJ_D)\asn_mime.obj $(OBJ_D)\asn1_gen.obj \
     $(OBJ_D)\asn1_par.obj $(OBJ_D)\asn1_lib.obj $(OBJ_D)\asn1_err.obj \
+    $(OBJ_D)\bio_asn1.obj $(OBJ_D)\bio_ndef.obj \
     $(OBJ_D)\a_bytes.obj $(OBJ_D)\a_strnid.obj \
     $(OBJ_D)\evp_asn1.obj $(OBJ_D)\asn_pack.obj $(OBJ_D)\p5_pbe.obj \
     $(OBJ_D)\p5_pbev2.obj $(OBJ_D)\p8_pkey.obj $(OBJ_D)\asn_moid.obj \
@@ -289,7 +294,8 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\v3_ncons.obj $(OBJ_D)\v3_pcia.obj $(OBJ_D)\v3_pci.obj \
     $(OBJ_D)\pcy_cache.obj $(OBJ_D)\pcy_node.obj $(OBJ_D)\pcy_data.obj \
     $(OBJ_D)\pcy_map.obj $(OBJ_D)\pcy_tree.obj $(OBJ_D)\pcy_lib.obj \
-    $(OBJ_D)\v3_asid.obj $(OBJ_D)\v3_addr.obj $(OBJ_D)\conf_err.obj \
+    $(OBJ_D)\v3_asid.obj $(OBJ_D)\v3_addr.obj $(OBJ_D)\v3_scts.obj \
+    $(OBJ_D)\conf_err.obj \
     $(OBJ_D)\conf_lib.obj $(OBJ_D)\conf_api.obj $(OBJ_D)\conf_def.obj \
     $(OBJ_D)\conf_mod.obj $(OBJ_D)\conf_mall.obj $(OBJ_D)\conf_sap.obj \
     $(OBJ_D)\pk7_asn1.obj $(OBJ_D)\pk7_lib.obj \
@@ -318,9 +324,14 @@ CRYPTOOBJ=$(OBJ_D)\cryptlib.obj \
     $(OBJ_D)\ecp_nistp224.obj $(OBJ_D)\ecp_nistp256.obj $(OBJ_D)\ecp_nistp521.obj \
     $(OBJ_D)\ecp_nistputil.obj $(OBJ_D)\ecp_oct.obj $(OBJ_D)\ecp_smpl.obj \
     $(OBJ_D)\ech_err.obj $(OBJ_D)\ech_key.obj $(OBJ_D)\ech_lib.obj \
+    $(OBJ_D)\ech_kdf.obj \
     $(OBJ_D)\ech_ossl.obj $(OBJ_D)\ecs_asn1.obj $(OBJ_D)\ecs_err.obj \
     $(OBJ_D)\ecs_lib.obj $(OBJ_D)\ecs_ossl.obj $(OBJ_D)\ecs_sign.obj \
-    $(OBJ_D)\ecs_vrf.obj $(OBJ_D)\m_ecdsa.obj
+    $(OBJ_D)\ecs_vrf.obj $(OBJ_D)\m_ecdsa.obj \
+    $(OBJ_D)\cms_sd.obj $(OBJ_D)\cms_err.obj $(OBJ_D)\cms_lib.obj \
+    $(OBJ_D)\cms_env.obj $(OBJ_D)\cms_asn1.obj $(OBJ_D)\cms_kari.obj \
+    $(OBJ_D)\cms_dd.obj $(OBJ_D)\cms_enc.obj $(OBJ_D)\cms_io.obj \
+    $(OBJ_D)\cms_pwri.obj $(OBJ_D)\cms_att.obj
 
 ###################################################################
 all: banner $(TMP_D) $(INCO_D) headers lib
@@ -654,6 +665,9 @@ $(INCO_D)\ecdh.h: $(SRC_D)\crypto\ecdh\ecdh.h
 $(INCO_D)\ecdsa.h: $(SRC_D)\crypto\ecdsa\ecdsa.h
     $(CP) "$(SRC_D)\crypto\ecdsa\ecdsa.h" "$(INCO_D)\ecdsa.h"
 
+$(INCO_D)\cms.h: $(SRC_D)\crypto\cms\cms.h
+    $(CP) "$(SRC_D)\crypto\cms\cms.h" "$(INCO_D)\cms.h"
+
 $(OBJ_D)\s2_meth.obj: $(SRC_D)\ssl\s2_meth.c
     $(CC) -o$(OBJ_D)\s2_meth.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\s2_meth.c
 
@@ -729,6 +743,9 @@ $(OBJ_D)\t1_enc.obj: $(SRC_D)\ssl\t1_enc.c
 $(OBJ_D)\t1_reneg.obj: $(SRC_D)\ssl\t1_reneg.c
     $(CC) -o$(OBJ_D)\t1_reneg.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\t1_reneg.c
 
+$(OBJ_D)\t1_ext.obj: $(SRC_D)\ssl\t1_ext.c
+    $(CC) -o$(OBJ_D)\t1_ext.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\t1_ext.c
+
 $(OBJ_D)\tls_srp.obj: $(SRC_D)\ssl\tls_srp.c
     $(CC) -o$(OBJ_D)\tls_srp.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\tls_srp.c
 
@@ -753,9 +770,6 @@ $(OBJ_D)\d1_pkt.obj: $(SRC_D)\ssl\d1_pkt.c
 $(OBJ_D)\d1_both.obj: $(SRC_D)\ssl\d1_both.c
     $(CC) -o$(OBJ_D)\d1_both.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\d1_both.c
 
-$(OBJ_D)\d1_enc.obj: $(SRC_D)\ssl\d1_enc.c
-    $(CC) -o$(OBJ_D)\d1_enc.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\d1_enc.c
-
 $(OBJ_D)\ssl_lib.obj: $(SRC_D)\ssl\ssl_lib.c
     $(CC) -o$(OBJ_D)\ssl_lib.obj  $(LIB_CFLAGS) -c $(SRC_D)\ssl\ssl_lib.c
 
@@ -885,6 +899,9 @@ $(OBJ_D)\gcm128.obj: $(SRC_D)\crypto\modes\gcm128.c
 $(OBJ_D)\xts128.obj: $(SRC_D)\crypto\modes\xts128.c
     $(CC) -o$(OBJ_D)\xts128.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\modes\xts128.c
 
+$(OBJ_D)\wrap128.obj: $(SRC_D)\crypto\modes\wrap128.c
+    $(CC) -o$(OBJ_D)\wrap128.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\modes\wrap128.c
+
 $(OBJ_D)\ctr128.obj: $(SRC_D)\crypto\modes\ctr128.c
     $(CC) -o$(OBJ_D)\ctr128.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\modes\ctr128.c
 
@@ -1305,6 +1322,12 @@ $(OBJ_D)\dh_pmeth.obj: $(SRC_D)\crypto\dh\dh_pmeth.c
 $(OBJ_D)\dh_ameth.obj: $(SRC_D)\crypto\dh\dh_ameth.c
     $(CC) -o$(OBJ_D)\dh_ameth.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\dh\dh_ameth.c
 
+$(OBJ_D)\dh_rfc5114.obj: $(SRC_D)\crypto\dh\dh_rfc5114.c
+    $(CC) -o$(OBJ_D)\dh_rfc5114.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\dh\dh_rfc5114.c
+
+$(OBJ_D)\dh_kdf.obj: $(SRC_D)\crypto\dh\dh_kdf.c
+    $(CC) -o$(OBJ_D)\dh_kdf.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\dh\dh_kdf.c
+
 $(OBJ_D)\buffer.obj: $(SRC_D)\crypto\buffer\buffer.c
     $(CC) -o$(OBJ_D)\buffer.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\buffer\buffer.c
 
@@ -1464,6 +1487,9 @@ $(OBJ_D)\e_aes.obj: $(SRC_D)\crypto\evp\e_aes.c
 $(OBJ_D)\e_aes_cbc_hmac_sha1.obj: $(SRC_D)\crypto\evp\e_aes_cbc_hmac_sha1.c
     $(CC) -o$(OBJ_D)\e_aes_cbc_hmac_sha1.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\evp\e_aes_cbc_hmac_sha1.c
 
+$(OBJ_D)\e_aes_cbc_hmac_sha256.obj: $(SRC_D)\crypto\evp\e_aes_cbc_hmac_sha256.c
+    $(CC) -o$(OBJ_D)\e_aes_cbc_hmac_sha256.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\evp\e_aes_cbc_hmac_sha256.c
+
 $(OBJ_D)\names.obj: $(SRC_D)\crypto\evp\names.c
     $(CC) -o$(OBJ_D)\names.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\evp\names.c
 
@@ -1779,6 +1805,12 @@ $(OBJ_D)\asn1_lib.obj: $(SRC_D)\crypto\asn1\asn1_lib.c
 $(OBJ_D)\asn1_err.obj: $(SRC_D)\crypto\asn1\asn1_err.c
     $(CC) -o$(OBJ_D)\asn1_err.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\asn1\asn1_err.c
 
+$(OBJ_D)\bio_asn1.obj: $(SRC_D)\crypto\asn1\bio_asn1.c
+    $(CC) -o$(OBJ_D)\bio_asn1.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\asn1\bio_asn1.c
+
+$(OBJ_D)\bio_ndef.obj: $(SRC_D)\crypto\asn1\bio_ndef.c
+    $(CC) -o$(OBJ_D)\bio_ndef.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\asn1\bio_ndef.c
+
 $(OBJ_D)\a_bytes.obj: $(SRC_D)\crypto\asn1\a_bytes.c
     $(CC) -o$(OBJ_D)\a_bytes.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\asn1\a_bytes.c
 
@@ -2016,6 +2048,9 @@ $(OBJ_D)\v3_asid.obj: $(SRC_D)\crypto\x509v3\v3_asid.c
 $(OBJ_D)\v3_addr.obj: $(SRC_D)\crypto\x509v3\v3_addr.c
     $(CC) -o$(OBJ_D)\v3_addr.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\x509v3\v3_addr.c
 
+$(OBJ_D)\v3_scts.obj: $(SRC_D)\crypto\x509v3\v3_scts.c
+    $(CC) -o$(OBJ_D)\v3_scts.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\x509v3\v3_scts.c
+
 $(OBJ_D)\conf_err.obj: $(SRC_D)\crypto\conf\conf_err.c
     $(CC) -o$(OBJ_D)\conf_err.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\conf\conf_err.c
 
@@ -2268,6 +2303,9 @@ $(OBJ_D)\ech_lib.obj: $(SRC_D)\crypto\ecdh\ech_lib.c
 $(OBJ_D)\ech_ossl.obj: $(SRC_D)\crypto\ecdh\ech_ossl.c
     $(CC) -o$(OBJ_D)\ech_ossl.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\ecdh\ech_ossl.c
 
+$(OBJ_D)\ech_kdf.obj: $(SRC_D)\crypto\ecdh\ech_kdf.c
+    $(CC) -o$(OBJ_D)\ech_kdf.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\ecdh\ech_kdf.c
+
 $(OBJ_D)\ecs_asn1.obj: $(SRC_D)\crypto\ecdsa\ecs_asn1.c
     $(CC) -o$(OBJ_D)\ecs_asn1.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\ecdsa\ecs_asn1.c
 
@@ -2289,6 +2327,39 @@ $(OBJ_D)\ecs_vrf.obj: $(SRC_D)\crypto\ecdsa\ecs_vrf.c
 $(OBJ_D)\m_ecdsa.obj: $(SRC_D)\crypto\evp\m_ecdsa.c
     $(CC) -o$(OBJ_D)\m_ecdsa.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\evp\m_ecdsa.c
 
+$(OBJ_D)\cms_sd.obj: $(SRC_D)\crypto\cms\cms_sd.c
+    $(CC) -o$(OBJ_D)\cms_sd.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_sd.c
+
+$(OBJ_D)\cms_err.obj: $(SRC_D)\crypto\cms\cms_err.c
+    $(CC) -o$(OBJ_D)\cms_err.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_err.c
+
+$(OBJ_D)\cms_lib.obj: $(SRC_D)\crypto\cms\cms_lib.c
+    $(CC) -o$(OBJ_D)\cms_lib.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_lib.c
+
+$(OBJ_D)\cms_env.obj: $(SRC_D)\crypto\cms\cms_env.c
+    $(CC) -o$(OBJ_D)\cms_env.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_env.c
+
+$(OBJ_D)\cms_asn1.obj: $(SRC_D)\crypto\cms\cms_asn1.c
+    $(CC) -o$(OBJ_D)\cms_asn1.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_asn1.c
+
+$(OBJ_D)\cms_kari.obj: $(SRC_D)\crypto\cms\cms_kari.c
+    $(CC) -o$(OBJ_D)\cms_kari.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_kari.c
+
+$(OBJ_D)\cms_dd.obj: $(SRC_D)\crypto\cms\cms_dd.c
+    $(CC) -o$(OBJ_D)\cms_dd.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_dd.c
+
+$(OBJ_D)\cms_enc.obj: $(SRC_D)\crypto\cms\cms_enc.c
+    $(CC) -o$(OBJ_D)\cms_enc.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_enc.c
+
+$(OBJ_D)\cms_io.obj: $(SRC_D)\crypto\cms\cms_io.c
+    $(CC) -o$(OBJ_D)\cms_io.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_io.c
+
+$(OBJ_D)\cms_pwri.obj: $(SRC_D)\crypto\cms\cms_pwri.c
+    $(CC) -o$(OBJ_D)\cms_pwri.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_pwri.c
+
+$(OBJ_D)\cms_att.obj: $(SRC_D)\crypto\cms\cms_att.c
+    $(CC) -o$(OBJ_D)\cms_att.obj  $(LIB_CFLAGS) -c $(SRC_D)\crypto\cms\cms_att.c
+
 $(O_SSL): $(SSLOBJ)
     -if exist $(O_SSL) $(RM) $(O_SSL)
     $(MKLIB) $(O_SSL) @&&!

+ 4 - 182
libs/openssl/crypto/aes/aes_wrap.c

@@ -54,197 +54,19 @@
 
 #include "cryptlib.h"
 #include <openssl/aes.h>
-#include <openssl/bio.h>
-
-static const unsigned char default_iv[] = {
-    0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
-};
+#include <openssl/modes.h>
 
 int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
                  unsigned char *out,
                  const unsigned char *in, unsigned int inlen)
 {
-    unsigned char *A, B[16], *R;
-    unsigned int i, j, t;
-    if ((inlen & 0x7) || (inlen < 8))
-        return -1;
-    A = B;
-    t = 1;
-    memcpy(out + 8, in, inlen);
-    if (!iv)
-        iv = default_iv;
-
-    memcpy(A, iv, 8);
-
-    for (j = 0; j < 6; j++) {
-        R = out + 8;
-        for (i = 0; i < inlen; i += 8, t++, R += 8) {
-            memcpy(B + 8, R, 8);
-            AES_encrypt(B, B, key);
-            A[7] ^= (unsigned char)(t & 0xff);
-            if (t > 0xff) {
-                A[6] ^= (unsigned char)((t >> 8) & 0xff);
-                A[5] ^= (unsigned char)((t >> 16) & 0xff);
-                A[4] ^= (unsigned char)((t >> 24) & 0xff);
-            }
-            memcpy(R, B + 8, 8);
-        }
-    }
-    memcpy(out, A, 8);
-    return inlen + 8;
+    return CRYPTO_128_wrap(key, iv, out, in, inlen, (block128_f) AES_encrypt);
 }
 
 int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
                    unsigned char *out,
                    const unsigned char *in, unsigned int inlen)
 {
-    unsigned char *A, B[16], *R;
-    unsigned int i, j, t;
-    inlen -= 8;
-    if (inlen & 0x7)
-        return -1;
-    if (inlen < 8)
-        return -1;
-    A = B;
-    t = 6 * (inlen >> 3);
-    memcpy(A, in, 8);
-    memcpy(out, in + 8, inlen);
-    for (j = 0; j < 6; j++) {
-        R = out + inlen - 8;
-        for (i = 0; i < inlen; i += 8, t--, R -= 8) {
-            A[7] ^= (unsigned char)(t & 0xff);
-            if (t > 0xff) {
-                A[6] ^= (unsigned char)((t >> 8) & 0xff);
-                A[5] ^= (unsigned char)((t >> 16) & 0xff);
-                A[4] ^= (unsigned char)((t >> 24) & 0xff);
-            }
-            memcpy(B + 8, R, 8);
-            AES_decrypt(B, B, key);
-            memcpy(R, B + 8, 8);
-        }
-    }
-    if (!iv)
-        iv = default_iv;
-    if (memcmp(A, iv, 8)) {
-        OPENSSL_cleanse(out, inlen);
-        return 0;
-    }
-    return inlen;
-}
-
-#ifdef AES_WRAP_TEST
-
-int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
-                         const unsigned char *iv,
-                         const unsigned char *eout,
-                         const unsigned char *key, int keylen)
-{
-    unsigned char *otmp = NULL, *ptmp = NULL;
-    int r, ret = 0;
-    AES_KEY wctx;
-    otmp = OPENSSL_malloc(keylen + 8);
-    ptmp = OPENSSL_malloc(keylen);
-    if (!otmp || !ptmp)
-        return 0;
-    if (AES_set_encrypt_key(kek, keybits, &wctx))
-        goto err;
-    r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
-    if (r <= 0)
-        goto err;
-
-    if (eout && memcmp(eout, otmp, keylen))
-        goto err;
-
-    if (AES_set_decrypt_key(kek, keybits, &wctx))
-        goto err;
-    r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
-
-    if (memcmp(key, ptmp, keylen))
-        goto err;
-
-    ret = 1;
-
- err:
-    if (otmp)
-        OPENSSL_free(otmp);
-    if (ptmp)
-        OPENSSL_free(ptmp);
-
-    return ret;
-
+    return CRYPTO_128_unwrap(key, iv, out, in, inlen,
+                             (block128_f) AES_decrypt);
 }
-
-int main(int argc, char **argv)
-{
-
-    static const unsigned char kek[] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
-    };
-
-    static const unsigned char key[] = {
-        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
-        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
-    };
-
-    static const unsigned char e1[] = {
-        0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
-        0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
-        0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
-    };
-
-    static const unsigned char e2[] = {
-        0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
-        0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
-        0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
-    };
-
-    static const unsigned char e3[] = {
-        0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
-        0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
-        0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
-    };
-
-    static const unsigned char e4[] = {
-        0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
-        0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
-        0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
-        0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
-    };
-
-    static const unsigned char e5[] = {
-        0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
-        0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
-        0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
-        0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
-    };
-
-    static const unsigned char e6[] = {
-        0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
-        0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
-        0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
-        0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
-        0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
-    };
-
-    AES_KEY wctx, xctx;
-    int ret;
-    ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
-    fprintf(stderr, "Key test result %d\n", ret);
-    ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
-    fprintf(stderr, "Key test result %d\n", ret);
-    ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
-    fprintf(stderr, "Key test result %d\n", ret);
-    ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
-    fprintf(stderr, "Key test result %d\n", ret);
-    ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
-    fprintf(stderr, "Key test result %d\n", ret);
-    ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
-    fprintf(stderr, "Key test result %d\n", ret);
-}
-
-#endif

+ 46 - 0
libs/openssl/crypto/arm64cpuid.S

@@ -0,0 +1,46 @@
+#include "arm_arch.h"
+
+.text
+.arch	armv8-a+crypto
+
+.align	5
+.global	_armv7_neon_probe
+.type	_armv7_neon_probe,%function
+_armv7_neon_probe:
+	orr	v15.16b, v15.16b, v15.16b
+	ret
+.size	_armv7_neon_probe,.-_armv7_neon_probe
+
+.global	_armv7_tick
+.type	_armv7_tick,%function
+_armv7_tick:
+	mrs	x0, CNTVCT_EL0
+	ret
+.size	_armv7_tick,.-_armv7_tick
+
+.global	_armv8_aes_probe
+.type	_armv8_aes_probe,%function
+_armv8_aes_probe:
+	aese	v0.16b, v0.16b
+	ret
+.size	_armv8_aes_probe,.-_armv8_aes_probe
+
+.global	_armv8_sha1_probe
+.type	_armv8_sha1_probe,%function
+_armv8_sha1_probe:
+	sha1h	s0, s0
+	ret
+.size	_armv8_sha1_probe,.-_armv8_sha1_probe
+
+.global	_armv8_sha256_probe
+.type	_armv8_sha256_probe,%function
+_armv8_sha256_probe:
+	sha256su0	v0.4s, v0.4s
+	ret
+.size	_armv8_sha256_probe,.-_armv8_sha256_probe
+.global	_armv8_pmull_probe
+.type	_armv8_pmull_probe,%function
+_armv8_pmull_probe:
+	pmull	v0.1q, v0.1d, v0.1d
+	ret
+.size	_armv8_pmull_probe,.-_armv8_pmull_probe

+ 31 - 4
libs/openssl/crypto/arm_arch.h

@@ -10,13 +10,24 @@
 #    define __ARMEL__
 #   endif
 #  elif defined(__GNUC__)
+#   if   defined(__aarch64__)
+#    define __ARM_ARCH__ 8
+#    if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
+#     define __ARMEB__
+#    else
+#     define __ARMEL__
+#    endif
   /*
    * Why doesn't gcc define __ARM_ARCH__? Instead it defines
    * bunch of below macros. See all_architectires[] table in
    * gcc/config/arm/arm.c. On a side note it defines
    * __ARMEL__/__ARMEB__ for little-/big-endian.
    */
-#   if   defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)     || \
+#   elif defined(__ARM_ARCH)
+#    define __ARM_ARCH__ __ARM_ARCH
+#   elif defined(__ARM_ARCH_8A__)
+#    define __ARM_ARCH__ 8
+#   elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)     || \
         defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__)     || \
         defined(__ARM_ARCH_7EM__)
 #    define __ARM_ARCH__ 7
@@ -41,11 +52,27 @@
 #  include <openssl/fipssyms.h>
 # endif
 
+# if !defined(__ARM_MAX_ARCH__)
+#  define __ARM_MAX_ARCH__ __ARM_ARCH__
+# endif
+
+# if __ARM_MAX_ARCH__<__ARM_ARCH__
+#  error "__ARM_MAX_ARCH__ can't be less than __ARM_ARCH__"
+# elif __ARM_MAX_ARCH__!=__ARM_ARCH__
+#  if __ARM_ARCH__<7 && __ARM_MAX_ARCH__>=7 && defined(__ARMEB__)
+#   error "can't build universal big-endian binary"
+#  endif
+# endif
+
 # if !__ASSEMBLER__
 extern unsigned int OPENSSL_armcap_P;
-
-#  define ARMV7_NEON      (1<<0)
-#  define ARMV7_TICK      (1<<1)
 # endif
 
+# define ARMV7_NEON      (1<<0)
+# define ARMV7_TICK      (1<<1)
+# define ARMV8_AES       (1<<2)
+# define ARMV8_SHA1      (1<<3)
+# define ARMV8_SHA256    (1<<4)
+# define ARMV8_PMULL     (1<<5)
+
 #endif

+ 90 - 7
libs/openssl/crypto/armcap.c

@@ -7,8 +7,18 @@
 
 #include "arm_arch.h"
 
-unsigned int OPENSSL_armcap_P;
+unsigned int OPENSSL_armcap_P = 0;
 
+#if __ARM_MAX_ARCH__<7
+void OPENSSL_cpuid_setup(void)
+{
+}
+
+unsigned long OPENSSL_rdtsc(void)
+{
+    return 0;
+}
+#else
 static sigset_t all_masked;
 
 static sigjmp_buf ill_jmp;
@@ -22,9 +32,13 @@ static void ill_handler(int sig)
  * ARM compilers support inline assembler...
  */
 void _armv7_neon_probe(void);
-unsigned int _armv7_tick(void);
+void _armv8_aes_probe(void);
+void _armv8_sha1_probe(void);
+void _armv8_sha256_probe(void);
+void _armv8_pmull_probe(void);
+unsigned long _armv7_tick(void);
 
-unsigned int OPENSSL_rdtsc(void)
+unsigned long OPENSSL_rdtsc(void)
 {
     if (OPENSSL_armcap_P & ARMV7_TICK)
         return _armv7_tick();
@@ -32,9 +46,44 @@ unsigned int OPENSSL_rdtsc(void)
         return 0;
 }
 
-#if defined(__GNUC__) && __GNUC__>=2
+/*
+ * Use a weak reference to getauxval() so we can use it if it is available but
+ * don't break the build if it is not.
+ */
+# if defined(__GNUC__) && __GNUC__>=2
 void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
-#endif
+extern unsigned long getauxval(unsigned long type) __attribute__ ((weak));
+# else
+static unsigned long (*getauxval) (unsigned long) = NULL;
+# endif
+
+/*
+ * ARM puts the the feature bits for Crypto Extensions in AT_HWCAP2, whereas
+ * AArch64 used AT_HWCAP.
+ */
+# if defined(__arm__) || defined (__arm)
+#  define HWCAP                  16
+                                  /* AT_HWCAP */
+#  define HWCAP_NEON             (1 << 12)
+
+#  define HWCAP_CE               26
+                                  /* AT_HWCAP2 */
+#  define HWCAP_CE_AES           (1 << 0)
+#  define HWCAP_CE_PMULL         (1 << 1)
+#  define HWCAP_CE_SHA1          (1 << 2)
+#  define HWCAP_CE_SHA256        (1 << 3)
+# elif defined(__aarch64__)
+#  define HWCAP                  16
+                                  /* AT_HWCAP */
+#  define HWCAP_NEON             (1 << 1)
+
+#  define HWCAP_CE               HWCAP
+#  define HWCAP_CE_AES           (1 << 3)
+#  define HWCAP_CE_PMULL         (1 << 4)
+#  define HWCAP_CE_SHA1          (1 << 5)
+#  define HWCAP_CE_SHA256        (1 << 6)
+# endif
+
 void OPENSSL_cpuid_setup(void)
 {
     char *e;
@@ -47,7 +96,7 @@ void OPENSSL_cpuid_setup(void)
     trigger = 1;
 
     if ((e = getenv("OPENSSL_armcap"))) {
-        OPENSSL_armcap_P = strtoul(e, NULL, 0);
+        OPENSSL_armcap_P = (unsigned int)strtoul(e, NULL, 0);
         return;
     }
 
@@ -67,9 +116,42 @@ void OPENSSL_cpuid_setup(void)
     sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
     sigaction(SIGILL, &ill_act, &ill_oact);
 
-    if (sigsetjmp(ill_jmp, 1) == 0) {
+    if (getauxval != NULL) {
+        if (getauxval(HWCAP) & HWCAP_NEON) {
+            unsigned long hwcap = getauxval(HWCAP_CE);
+
+            OPENSSL_armcap_P |= ARMV7_NEON;
+
+            if (hwcap & HWCAP_CE_AES)
+                OPENSSL_armcap_P |= ARMV8_AES;
+
+            if (hwcap & HWCAP_CE_PMULL)
+                OPENSSL_armcap_P |= ARMV8_PMULL;
+
+            if (hwcap & HWCAP_CE_SHA1)
+                OPENSSL_armcap_P |= ARMV8_SHA1;
+
+            if (hwcap & HWCAP_CE_SHA256)
+                OPENSSL_armcap_P |= ARMV8_SHA256;
+        }
+    } else if (sigsetjmp(ill_jmp, 1) == 0) {
         _armv7_neon_probe();
         OPENSSL_armcap_P |= ARMV7_NEON;
+        if (sigsetjmp(ill_jmp, 1) == 0) {
+            _armv8_pmull_probe();
+            OPENSSL_armcap_P |= ARMV8_PMULL | ARMV8_AES;
+        } else if (sigsetjmp(ill_jmp, 1) == 0) {
+            _armv8_aes_probe();
+            OPENSSL_armcap_P |= ARMV8_AES;
+        }
+        if (sigsetjmp(ill_jmp, 1) == 0) {
+            _armv8_sha1_probe();
+            OPENSSL_armcap_P |= ARMV8_SHA1;
+        }
+        if (sigsetjmp(ill_jmp, 1) == 0) {
+            _armv8_sha256_probe();
+            OPENSSL_armcap_P |= ARMV8_SHA256;
+        }
     }
     if (sigsetjmp(ill_jmp, 1) == 0) {
         _armv7_tick();
@@ -79,3 +161,4 @@ void OPENSSL_cpuid_setup(void)
     sigaction(SIGILL, &ill_oact, NULL);
     sigprocmask(SIG_SETMASK, &oset, NULL);
 }
+#endif

+ 82 - 27
libs/openssl/crypto/armv4cpuid.S

@@ -4,20 +4,6 @@
 .code	32
 
 .align	5
-.global	_armv7_neon_probe
-.type	_armv7_neon_probe,%function
-_armv7_neon_probe:
-	.word	0xf26ee1fe	@ vorr	q15,q15,q15
-	.word	0xe12fff1e	@ bx	lr
-.size	_armv7_neon_probe,.-_armv7_neon_probe
-
-.global	_armv7_tick
-.type	_armv7_tick,%function
-_armv7_tick:
-	mrc	p15,0,r0,c9,c13,0
-	.word	0xe12fff1e	@ bx	lr
-.size	_armv7_tick,.-_armv7_tick
-
 .global	OPENSSL_atomic_add
 .type	OPENSSL_atomic_add,%function
 OPENSSL_atomic_add:
@@ -28,7 +14,7 @@ OPENSSL_atomic_add:
 	cmp	r2,#0
 	bne	.Ladd
 	mov	r0,r3
-	.word	0xe12fff1e	@ bx	lr
+	bx	lr
 #else
 	stmdb	sp!,{r4-r6,lr}
 	ldr	r2,.Lspinlock
@@ -81,62 +67,131 @@ OPENSSL_cleanse:
 	adds	r1,r1,#4
 	bne	.Little
 .Lcleanse_done:
+#if __ARM_ARCH__>=5
+	bx	lr
+#else
 	tst	lr,#1
 	moveq	pc,lr
 	.word	0xe12fff1e	@ bx	lr
+#endif
 .size	OPENSSL_cleanse,.-OPENSSL_cleanse
 
+#if __ARM_MAX_ARCH__>=7
+.arch	armv7-a
+.fpu	neon
+
+.align	5
+.global	_armv7_neon_probe
+.type	_armv7_neon_probe,%function
+_armv7_neon_probe:
+	vorr	q0,q0,q0
+	bx	lr
+.size	_armv7_neon_probe,.-_armv7_neon_probe
+
+.global	_armv7_tick
+.type	_armv7_tick,%function
+_armv7_tick:
+	mrrc	p15,1,r0,r1,c14		@ CNTVCT
+	bx	lr
+.size	_armv7_tick,.-_armv7_tick
+
+.global	_armv8_aes_probe
+.type	_armv8_aes_probe,%function
+_armv8_aes_probe:
+	.byte	0x00,0x03,0xb0,0xf3	@ aese.8	q0,q0
+	bx	lr
+.size	_armv8_aes_probe,.-_armv8_aes_probe
+
+.global	_armv8_sha1_probe
+.type	_armv8_sha1_probe,%function
+_armv8_sha1_probe:
+	.byte	0x40,0x0c,0x00,0xf2	@ sha1c.32	q0,q0,q0
+	bx	lr
+.size	_armv8_sha1_probe,.-_armv8_sha1_probe
+
+.global	_armv8_sha256_probe
+.type	_armv8_sha256_probe,%function
+_armv8_sha256_probe:
+	.byte	0x40,0x0c,0x00,0xf3	@ sha256h.32	q0,q0,q0
+	bx	lr
+.size	_armv8_sha256_probe,.-_armv8_sha256_probe
+.global	_armv8_pmull_probe
+.type	_armv8_pmull_probe,%function
+_armv8_pmull_probe:
+	.byte	0x00,0x0e,0xa0,0xf2	@ vmull.p64	q0,d0,d0
+	bx	lr
+.size	_armv8_pmull_probe,.-_armv8_pmull_probe
+#endif
+
 .global	OPENSSL_wipe_cpu
 .type	OPENSSL_wipe_cpu,%function
 OPENSSL_wipe_cpu:
+#if __ARM_MAX_ARCH__>=7
 	ldr	r0,.LOPENSSL_armcap
 	adr	r1,.LOPENSSL_armcap
 	ldr	r0,[r1,r0]
+#endif
 	eor	r2,r2,r2
 	eor	r3,r3,r3
 	eor	ip,ip,ip
+#if __ARM_MAX_ARCH__>=7
 	tst	r0,#1
 	beq	.Lwipe_done
-	.word	0xf3000150	@ veor    q0, q0, q0
-	.word	0xf3022152	@ veor    q1, q1, q1
-	.word	0xf3044154	@ veor    q2, q2, q2
-	.word	0xf3066156	@ veor    q3, q3, q3
-	.word	0xf34001f0	@ veor    q8, q8, q8
-	.word	0xf34221f2	@ veor    q9, q9, q9
-	.word	0xf34441f4	@ veor    q10, q10, q10
-	.word	0xf34661f6	@ veor    q11, q11, q11
-	.word	0xf34881f8	@ veor    q12, q12, q12
-	.word	0xf34aa1fa	@ veor    q13, q13, q13
-	.word	0xf34cc1fc	@ veor    q14, q14, q14
-	.word	0xf34ee1fe	@ veor    q15, q15, q15
+	veor	q0, q0, q0
+	veor	q1, q1, q1
+	veor	q2, q2, q2
+	veor	q3, q3, q3
+	veor	q8, q8, q8
+	veor	q9, q9, q9
+	veor	q10, q10, q10
+	veor	q11, q11, q11
+	veor	q12, q12, q12
+	veor	q13, q13, q13
+	veor	q14, q14, q14
+	veor	q15, q15, q15
 .Lwipe_done:
+#endif
 	mov	r0,sp
+#if __ARM_ARCH__>=5
+	bx	lr
+#else
 	tst	lr,#1
 	moveq	pc,lr
 	.word	0xe12fff1e	@ bx	lr
+#endif
 .size	OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
 
 .global	OPENSSL_instrument_bus
 .type	OPENSSL_instrument_bus,%function
 OPENSSL_instrument_bus:
 	eor	r0,r0,r0
+#if __ARM_ARCH__>=5
+	bx	lr
+#else
 	tst	lr,#1
 	moveq	pc,lr
 	.word	0xe12fff1e	@ bx	lr
+#endif
 .size	OPENSSL_instrument_bus,.-OPENSSL_instrument_bus
 
 .global	OPENSSL_instrument_bus2
 .type	OPENSSL_instrument_bus2,%function
 OPENSSL_instrument_bus2:
 	eor	r0,r0,r0
+#if __ARM_ARCH__>=5
+	bx	lr
+#else
 	tst	lr,#1
 	moveq	pc,lr
 	.word	0xe12fff1e	@ bx	lr
+#endif
 .size	OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2
 
 .align	5
+#if __ARM_MAX_ARCH__>=7
 .LOPENSSL_armcap:
 .word	OPENSSL_armcap_P-.LOPENSSL_armcap
+#endif
 #if __ARM_ARCH__>=6
 .align	5
 #else

+ 44 - 2
libs/openssl/crypto/asn1/a_gentm.c

@@ -65,6 +65,7 @@
 #include "cryptlib.h"
 #include "o_time.h"
 #include <openssl/asn1.h>
+#include "asn1_locl.h"
 
 #if 0
 
@@ -117,7 +118,7 @@ ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
 
 #endif
 
-int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
 {
     static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
     static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
@@ -139,6 +140,8 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
     for (i = 0; i < 7; i++) {
         if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
             i++;
+            if (tm)
+                tm->tm_sec = 0;
             break;
         }
         if ((a[o] < '0') || (a[o] > '9'))
@@ -155,6 +158,31 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
 
         if ((n < min[i]) || (n > max[i]))
             goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n * 100 - 1900;
+                break;
+            case 1:
+                tm->tm_year += n;
+                break;
+            case 2:
+                tm->tm_mon = n - 1;
+                break;
+            case 3:
+                tm->tm_mday = n;
+                break;
+            case 4:
+                tm->tm_hour = n;
+                break;
+            case 5:
+                tm->tm_min = n;
+                break;
+            case 6:
+                tm->tm_sec = n;
+                break;
+            }
+        }
     }
     /*
      * Optional fractional seconds: decimal point followed by one or more
@@ -174,6 +202,7 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
     if (a[o] == 'Z')
         o++;
     else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
         o++;
         if (o + 4 > l)
             goto err;
@@ -187,9 +216,17 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
             n = (n * 10) + a[o] - '0';
             if ((n < min[i]) || (n > max[i]))
                 goto err;
+            if (tm) {
+                if (i == 7)
+                    offset = n * 3600;
+                else if (i == 8)
+                    offset += n * 60;
+            }
             o++;
         }
-    } else {
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
+    } else if (a[o]) {
         /* Missing time zone information. */
         goto err;
     }
@@ -198,6 +235,11 @@ int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
     return (0);
 }
 
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d)
+{
+    return asn1_generalizedtime_to_tm(NULL, d);
+}
+
 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
 {
     ASN1_GENERALIZEDTIME t;

+ 30 - 0
libs/openssl/crypto/asn1/a_time.c

@@ -66,6 +66,7 @@
 #include "cryptlib.h"
 #include "o_time.h"
 #include <openssl/asn1t.h>
+#include "asn1_locl.h"
 
 IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME)
 
@@ -196,3 +197,32 @@ int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
 
     return 1;
 }
+
+static int asn1_time_to_tm(struct tm *tm, const ASN1_TIME *t)
+{
+    if (t == NULL) {
+        time_t now_t;
+        time(&now_t);
+        if (OPENSSL_gmtime(&now_t, tm))
+            return 1;
+        return 0;
+    }
+
+    if (t->type == V_ASN1_UTCTIME)
+        return asn1_utctime_to_tm(tm, t);
+    else if (t->type == V_ASN1_GENERALIZEDTIME)
+        return asn1_generalizedtime_to_tm(tm, t);
+
+    return 0;
+}
+
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to)
+{
+    struct tm tm_from, tm_to;
+    if (!asn1_time_to_tm(&tm_from, from))
+        return 0;
+    if (!asn1_time_to_tm(&tm_to, to))
+        return 0;
+    return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
+}

+ 57 - 35
libs/openssl/crypto/asn1/a_utctm.c

@@ -61,6 +61,7 @@
 #include "cryptlib.h"
 #include "o_time.h"
 #include <openssl/asn1.h>
+#include "asn1_locl.h"
 
 #if 0
 int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
@@ -109,7 +110,7 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
 
 #endif
 
-int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
 {
     static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
     static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
@@ -127,6 +128,8 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
     for (i = 0; i < 6; i++) {
         if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
             i++;
+            if (tm)
+                tm->tm_sec = 0;
             break;
         }
         if ((a[o] < '0') || (a[o] > '9'))
@@ -143,10 +146,33 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
 
         if ((n < min[i]) || (n > max[i]))
             goto err;
+        if (tm) {
+            switch (i) {
+            case 0:
+                tm->tm_year = n < 50 ? n + 100 : n;
+                break;
+            case 1:
+                tm->tm_mon = n - 1;
+                break;
+            case 2:
+                tm->tm_mday = n;
+                break;
+            case 3:
+                tm->tm_hour = n;
+                break;
+            case 4:
+                tm->tm_min = n;
+                break;
+            case 5:
+                tm->tm_sec = n;
+                break;
+            }
+        }
     }
     if (a[o] == 'Z')
         o++;
     else if ((a[o] == '+') || (a[o] == '-')) {
+        int offsign = a[o] == '-' ? -1 : 1, offset = 0;
         o++;
         if (o + 4 > l)
             goto err;
@@ -160,12 +186,25 @@ int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
             n = (n * 10) + a[o] - '0';
             if ((n < min[i]) || (n > max[i]))
                 goto err;
+            if (tm) {
+                if (i == 6)
+                    offset = n * 3600;
+                else if (i == 7)
+                    offset += n * 60;
+            }
             o++;
         }
+        if (offset && !OPENSSL_gmtime_adj(tm, 0, offset * offsign))
+            return 0;
     }
-    return (o == l);
+    return o == l;
  err:
-    return (0);
+    return 0;
+}
+
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
+{
+    return asn1_utctime_to_tm(NULL, d);
 }
 
 int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
@@ -249,43 +288,26 @@ ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
 
 int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
 {
-    struct tm *tm;
-    struct tm data;
-    int offset;
-    int year;
-
-#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
-
-    if (s->data[12] == 'Z')
-        offset = 0;
-    else {
-        offset = g2(s->data + 13) * 60 + g2(s->data + 15);
-        if (s->data[12] == '-')
-            offset = -offset;
-    }
+    struct tm stm, ttm;
+    int day, sec;
 
-    t -= offset * 60;           /* FIXME: may overflow in extreme cases */
+    if (!asn1_utctime_to_tm(&stm, s))
+        return -2;
 
-    tm = OPENSSL_gmtime(&t, &data);
-    /*
-     * NB: -1, 0, 1 already valid return values so use -2 to indicate error.
-     */
-    if (tm == NULL)
+    if (!OPENSSL_gmtime(&t, &ttm))
         return -2;
 
-#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
-    year = g2(s->data);
-    if (year < 50)
-        year += 100;
-    return_cmp(year, tm->tm_year);
-    return_cmp(g2(s->data + 2) - 1, tm->tm_mon);
-    return_cmp(g2(s->data + 4), tm->tm_mday);
-    return_cmp(g2(s->data + 6), tm->tm_hour);
-    return_cmp(g2(s->data + 8), tm->tm_min);
-    return_cmp(g2(s->data + 10), tm->tm_sec);
-#undef g2
-#undef return_cmp
+    if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
+        return -2;
 
+    if (day > 0)
+        return 1;
+    if (day < 0)
+        return -1;
+    if (sec > 0)
+        return 1;
+    if (sec < 0)
+        return -1;
     return 0;
 }
 

+ 23 - 1
libs/openssl/crypto/asn1/ameth_lib.c

@@ -68,6 +68,7 @@
 extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
 extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
 extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
 extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
@@ -92,7 +93,10 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
     &eckey_asn1_meth,
 #endif
     &hmac_asn1_meth,
-    &cmac_asn1_meth
+    &cmac_asn1_meth,
+#ifndef OPENSSL_NO_DH
+    &dhx_asn1_meth
+#endif
 };
 
 typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
@@ -460,3 +464,21 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
 {
     ameth->pkey_ctrl = pkey_ctrl;
 }
+
+void EVP_PKEY_asn1_set_item(EVP_PKEY_ASN1_METHOD *ameth,
+                            int (*item_verify) (EVP_MD_CTX *ctx,
+                                                const ASN1_ITEM *it,
+                                                void *asn,
+                                                X509_ALGOR *a,
+                                                ASN1_BIT_STRING *sig,
+                                                EVP_PKEY *pkey),
+                            int (*item_sign) (EVP_MD_CTX *ctx,
+                                              const ASN1_ITEM *it,
+                                              void *asn,
+                                              X509_ALGOR *alg1,
+                                              X509_ALGOR *alg2,
+                                              ASN1_BIT_STRING *sig))
+{
+    ameth->item_sign = item_sign;
+    ameth->item_verify = item_verify;
+}

+ 6 - 4
libs/openssl/crypto/asn1/asn1.h

@@ -207,13 +207,13 @@ typedef struct asn1_const_ctx_st {
 # define ASN1_OBJECT_FLAG_CRITICAL        0x02/* critical x509v3 object id */
 # define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */
 # define ASN1_OBJECT_FLAG_DYNAMIC_DATA    0x08/* internal use */
-typedef struct asn1_object_st {
+struct asn1_object_st {
     const char *sn, *ln;
     int nid;
     int length;
     const unsigned char *data;  /* data remains const after init */
     int flags;                  /* Should we free this one */
-} ASN1_OBJECT;
+};
 
 # define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */
 /*
@@ -843,7 +843,7 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED)
 
-int ASN1_UTCTIME_check(ASN1_UTCTIME *a);
+int ASN1_UTCTIME_check(const ASN1_UTCTIME *a);
 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t);
 ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
                                int offset_day, long offset_sec);
@@ -853,13 +853,15 @@ int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t);
 time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s);
 # endif
 
-int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a);
+int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a);
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
                                                time_t t);
 ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
                                                time_t t, int offset_day,
                                                long offset_sec);
 int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str);
+int ASN1_TIME_diff(int *pday, int *psec,
+                   const ASN1_TIME *from, const ASN1_TIME *to);
 
 DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING)
 ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a);

+ 3 - 0
libs/openssl/crypto/asn1/asn1_locl.h

@@ -59,6 +59,9 @@
 
 /* Internal ASN1 structures and functions: not for application use */
 
+int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
+int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
+
 /* ASN1 print context structure */
 
 struct asn1_pctx_st {

+ 482 - 0
libs/openssl/crypto/asn1/bio_asn1.c

@@ -0,0 +1,482 @@
+/* bio_asn1.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/*
+ * Experimental ASN1 BIO. When written through the data is converted to an
+ * ASN1 string type: default is OCTET STRING. Additional functions can be
+ * provided to add prefix and suffix data.
+ */
+
+#include <string.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+
+/* Must be large enough for biggest tag+length */
+#define DEFAULT_ASN1_BUF_SIZE 20
+
+typedef enum {
+    ASN1_STATE_START,
+    ASN1_STATE_PRE_COPY,
+    ASN1_STATE_HEADER,
+    ASN1_STATE_HEADER_COPY,
+    ASN1_STATE_DATA_COPY,
+    ASN1_STATE_POST_COPY,
+    ASN1_STATE_DONE
+} asn1_bio_state_t;
+
+typedef struct BIO_ASN1_EX_FUNCS_st {
+    asn1_ps_func *ex_func;
+    asn1_ps_func *ex_free_func;
+} BIO_ASN1_EX_FUNCS;
+
+typedef struct BIO_ASN1_BUF_CTX_t {
+    /* Internal state */
+    asn1_bio_state_t state;
+    /* Internal buffer */
+    unsigned char *buf;
+    /* Size of buffer */
+    int bufsize;
+    /* Current position in buffer */
+    int bufpos;
+    /* Current buffer length */
+    int buflen;
+    /* Amount of data to copy */
+    int copylen;
+    /* Class and tag to use */
+    int asn1_class, asn1_tag;
+    asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
+    /* Extra buffer for prefix and suffix data */
+    unsigned char *ex_buf;
+    int ex_len;
+    int ex_pos;
+    void *ex_arg;
+} BIO_ASN1_BUF_CTX;
+
+static int asn1_bio_write(BIO *h, const char *buf, int num);
+static int asn1_bio_read(BIO *h, char *buf, int size);
+static int asn1_bio_puts(BIO *h, const char *str);
+static int asn1_bio_gets(BIO *h, char *str, int size);
+static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int asn1_bio_new(BIO *h);
+static int asn1_bio_free(BIO *data);
+static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next);
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state);
+
+static BIO_METHOD methods_asn1 = {
+    BIO_TYPE_ASN1,
+    "asn1",
+    asn1_bio_write,
+    asn1_bio_read,
+    asn1_bio_puts,
+    asn1_bio_gets,
+    asn1_bio_ctrl,
+    asn1_bio_new,
+    asn1_bio_free,
+    asn1_bio_callback_ctrl,
+};
+
+BIO_METHOD *BIO_f_asn1(void)
+{
+    return (&methods_asn1);
+}
+
+static int asn1_bio_new(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
+    if (!ctx)
+        return 0;
+    if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
+        OPENSSL_free(ctx);
+        return 0;
+    }
+    b->init = 1;
+    b->ptr = (char *)ctx;
+    b->flags = 0;
+    return 1;
+}
+
+static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
+{
+    ctx->buf = OPENSSL_malloc(size);
+    if (!ctx->buf)
+        return 0;
+    ctx->bufsize = size;
+    ctx->bufpos = 0;
+    ctx->buflen = 0;
+    ctx->copylen = 0;
+    ctx->asn1_class = V_ASN1_UNIVERSAL;
+    ctx->asn1_tag = V_ASN1_OCTET_STRING;
+    ctx->ex_buf = 0;
+    ctx->ex_pos = 0;
+    ctx->ex_len = 0;
+    ctx->state = ASN1_STATE_START;
+    return 1;
+}
+
+static int asn1_bio_free(BIO *b)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
+    if (ctx->buf)
+        OPENSSL_free(ctx->buf);
+    OPENSSL_free(ctx);
+    b->init = 0;
+    b->ptr = NULL;
+    b->flags = 0;
+    return 1;
+}
+
+static int asn1_bio_write(BIO *b, const char *in, int inl)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    int wrmax, wrlen, ret;
+    unsigned char *p;
+    if (!in || (inl < 0) || (b->next_bio == NULL))
+        return 0;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
+
+    wrlen = 0;
+    ret = -1;
+
+    for (;;) {
+        switch (ctx->state) {
+
+            /* Setup prefix data, call it */
+        case ASN1_STATE_START:
+            if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
+                                   ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
+                return 0;
+            break;
+
+            /* Copy any pre data first */
+        case ASN1_STATE_PRE_COPY:
+
+            ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
+                                    ASN1_STATE_HEADER);
+
+            if (ret <= 0)
+                goto done;
+
+            break;
+
+        case ASN1_STATE_HEADER:
+            ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
+            OPENSSL_assert(ctx->buflen <= ctx->bufsize);
+            p = ctx->buf;
+            ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
+            ctx->copylen = inl;
+            ctx->state = ASN1_STATE_HEADER_COPY;
+
+            break;
+
+        case ASN1_STATE_HEADER_COPY:
+            ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
+            if (ret <= 0)
+                goto done;
+
+            ctx->buflen -= ret;
+            if (ctx->buflen)
+                ctx->bufpos += ret;
+            else {
+                ctx->bufpos = 0;
+                ctx->state = ASN1_STATE_DATA_COPY;
+            }
+
+            break;
+
+        case ASN1_STATE_DATA_COPY:
+
+            if (inl > ctx->copylen)
+                wrmax = ctx->copylen;
+            else
+                wrmax = inl;
+            ret = BIO_write(b->next_bio, in, wrmax);
+            if (ret <= 0)
+                break;
+            wrlen += ret;
+            ctx->copylen -= ret;
+            in += ret;
+            inl -= ret;
+
+            if (ctx->copylen == 0)
+                ctx->state = ASN1_STATE_HEADER;
+
+            if (inl == 0)
+                goto done;
+
+            break;
+
+        default:
+            BIO_clear_retry_flags(b);
+            return 0;
+
+        }
+
+    }
+
+ done:
+    BIO_clear_retry_flags(b);
+    BIO_copy_next_retry(b);
+
+    return (wrlen > 0) ? wrlen : ret;
+
+}
+
+static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *cleanup, asn1_bio_state_t next)
+{
+    int ret;
+    if (ctx->ex_len <= 0)
+        return 1;
+    for (;;) {
+        ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
+        if (ret <= 0)
+            break;
+        ctx->ex_len -= ret;
+        if (ctx->ex_len > 0)
+            ctx->ex_pos += ret;
+        else {
+            if (cleanup)
+                cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
+            ctx->state = next;
+            ctx->ex_pos = 0;
+            break;
+        }
+    }
+    return ret;
+}
+
+static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
+                             asn1_ps_func *setup,
+                             asn1_bio_state_t ex_state,
+                             asn1_bio_state_t other_state)
+{
+    if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
+        BIO_clear_retry_flags(b);
+        return 0;
+    }
+    if (ctx->ex_len > 0)
+        ctx->state = ex_state;
+    else
+        ctx->state = other_state;
+    return 1;
+}
+
+static int asn1_bio_read(BIO *b, char *in, int inl)
+{
+    if (!b->next_bio)
+        return 0;
+    return BIO_read(b->next_bio, in, inl);
+}
+
+static int asn1_bio_puts(BIO *b, const char *str)
+{
+    return asn1_bio_write(b, str, strlen(str));
+}
+
+static int asn1_bio_gets(BIO *b, char *str, int size)
+{
+    if (!b->next_bio)
+        return 0;
+    return BIO_gets(b->next_bio, str, size);
+}
+
+static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+{
+    if (b->next_bio == NULL)
+        return (0);
+    return BIO_callback_ctrl(b->next_bio, cmd, fp);
+}
+
+static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
+{
+    BIO_ASN1_BUF_CTX *ctx;
+    BIO_ASN1_EX_FUNCS *ex_func;
+    long ret = 1;
+    ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
+    if (ctx == NULL)
+        return 0;
+    switch (cmd) {
+
+    case BIO_C_SET_PREFIX:
+        ex_func = arg2;
+        ctx->prefix = ex_func->ex_func;
+        ctx->prefix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_PREFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->prefix;
+        ex_func->ex_free_func = ctx->prefix_free;
+        break;
+
+    case BIO_C_SET_SUFFIX:
+        ex_func = arg2;
+        ctx->suffix = ex_func->ex_func;
+        ctx->suffix_free = ex_func->ex_free_func;
+        break;
+
+    case BIO_C_GET_SUFFIX:
+        ex_func = arg2;
+        ex_func->ex_func = ctx->suffix;
+        ex_func->ex_free_func = ctx->suffix_free;
+        break;
+
+    case BIO_C_SET_EX_ARG:
+        ctx->ex_arg = arg2;
+        break;
+
+    case BIO_C_GET_EX_ARG:
+        *(void **)arg2 = ctx->ex_arg;
+        break;
+
+    case BIO_CTRL_FLUSH:
+        if (!b->next_bio)
+            return 0;
+
+        /* Call post function if possible */
+        if (ctx->state == ASN1_STATE_HEADER) {
+            if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
+                                   ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
+                return 0;
+        }
+
+        if (ctx->state == ASN1_STATE_POST_COPY) {
+            ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
+                                    ASN1_STATE_DONE);
+            if (ret <= 0)
+                return ret;
+        }
+
+        if (ctx->state == ASN1_STATE_DONE)
+            return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+        else {
+            BIO_clear_retry_flags(b);
+            return 0;
+        }
+        break;
+
+    default:
+        if (!b->next_bio)
+            return 0;
+        return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
+
+    }
+
+    return ret;
+}
+
+static int asn1_bio_set_ex(BIO *b, int cmd,
+                           asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    extmp.ex_func = ex_func;
+    extmp.ex_free_func = ex_free_func;
+    return BIO_ctrl(b, cmd, 0, &extmp);
+}
+
+static int asn1_bio_get_ex(BIO *b, int cmd,
+                           asn1_ps_func **ex_func,
+                           asn1_ps_func **ex_free_func)
+{
+    BIO_ASN1_EX_FUNCS extmp;
+    int ret;
+    ret = BIO_ctrl(b, cmd, 0, &extmp);
+    if (ret > 0) {
+        *ex_func = extmp.ex_func;
+        *ex_free_func = extmp.ex_free_func;
+    }
+    return ret;
+}
+
+int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
+                        asn1_ps_func *prefix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
+}
+
+int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
+                        asn1_ps_func **pprefix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
+}
+
+int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
+                        asn1_ps_func *suffix_free)
+{
+    return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
+}
+
+int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
+                        asn1_ps_func **psuffix_free)
+{
+    return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
+}

+ 248 - 0
libs/openssl/crypto/asn1/bio_ndef.c

@@ -0,0 +1,248 @@
+/* bio_ndef.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 <openssl/asn1.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+#include <stdio.h>
+
+/* Experimental NDEF ASN1 BIO support routines */
+
+/*
+ * The usage is quite simple, initialize an ASN1 structure, get a BIO from it
+ * then any data written through the BIO will end up translated to
+ * approptiate format on the fly. The data is streamed out and does *not*
+ * need to be all held in memory at once. When the BIO is flushed the output
+ * is finalized and any signatures etc written out. The BIO is a 'proper'
+ * BIO and can handle non blocking I/O correctly. The usage is simple. The
+ * implementation is *not*...
+ */
+
+/* BIO support data stored in the ASN1 BIO ex_arg */
+
+typedef struct ndef_aux_st {
+    /* ASN1 structure this BIO refers to */
+    ASN1_VALUE *val;
+    const ASN1_ITEM *it;
+    /* Top of the BIO chain */
+    BIO *ndef_bio;
+    /* Output BIO */
+    BIO *out;
+    /* Boundary where content is inserted */
+    unsigned char **boundary;
+    /* DER buffer start */
+    unsigned char *derbuf;
+} NDEF_SUPPORT;
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg);
+
+BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
+{
+    NDEF_SUPPORT *ndef_aux = NULL;
+    BIO *asn_bio = NULL;
+    const ASN1_AUX *aux = it->funcs;
+    ASN1_STREAM_ARG sarg;
+
+    if (!aux || !aux->asn1_cb) {
+        ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+        return NULL;
+    }
+    ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
+    asn_bio = BIO_new(BIO_f_asn1());
+
+    /* ASN1 bio needs to be next to output BIO */
+
+    out = BIO_push(asn_bio, out);
+
+    if (!ndef_aux || !asn_bio || !out)
+        goto err;
+
+    BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
+    BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
+
+    /*
+     * Now let callback prepend any digest, cipher etc BIOs ASN1 structure
+     * needs.
+     */
+
+    sarg.out = out;
+    sarg.ndef_bio = NULL;
+    sarg.boundary = NULL;
+
+    if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
+        goto err;
+
+    ndef_aux->val = val;
+    ndef_aux->it = it;
+    ndef_aux->ndef_bio = sarg.ndef_bio;
+    ndef_aux->boundary = sarg.boundary;
+    ndef_aux->out = out;
+
+    BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
+
+    return sarg.ndef_bio;
+
+ err:
+    if (asn_bio)
+        BIO_free(asn_bio);
+    if (ndef_aux)
+        OPENSSL_free(ndef_aux);
+    return NULL;
+}
+
+static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (!p)
+        return 0;
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+
+    *plen = *ndef_aux->boundary - *pbuf;
+
+    return 1;
+}
+
+static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    if (ndef_aux->derbuf)
+        OPENSSL_free(ndef_aux->derbuf);
+
+    ndef_aux->derbuf = NULL;
+    *pbuf = NULL;
+    *plen = 0;
+    return 1;
+}
+
+static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
+                            void *parg)
+{
+    NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
+    if (!ndef_prefix_free(b, pbuf, plen, parg))
+        return 0;
+    OPENSSL_free(*pndef_aux);
+    *pndef_aux = NULL;
+    return 1;
+}
+
+static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
+{
+    NDEF_SUPPORT *ndef_aux;
+    unsigned char *p;
+    int derlen;
+    const ASN1_AUX *aux;
+    ASN1_STREAM_ARG sarg;
+
+    if (!parg)
+        return 0;
+
+    ndef_aux = *(NDEF_SUPPORT **)parg;
+
+    aux = ndef_aux->it->funcs;
+
+    /* Finalize structures */
+    sarg.ndef_bio = ndef_aux->ndef_bio;
+    sarg.out = ndef_aux->out;
+    sarg.boundary = ndef_aux->boundary;
+    if (aux->asn1_cb(ASN1_OP_STREAM_POST,
+                     &ndef_aux->val, ndef_aux->it, &sarg) <= 0)
+        return 0;
+
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
+    p = OPENSSL_malloc(derlen);
+    if (!p)
+        return 0;
+
+    ndef_aux->derbuf = p;
+    *pbuf = p;
+    derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
+
+    if (!*ndef_aux->boundary)
+        return 0;
+    *pbuf = *ndef_aux->boundary;
+    *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
+
+    return 1;
+}

+ 15 - 0
libs/openssl/crypto/asn1/t_x509.c

@@ -228,6 +228,21 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
         }
     }
 
+    if (!(cflag & X509_FLAG_NO_IDS)) {
+        if (ci->issuerUID) {
+            if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, ci->issuerUID, 12))
+                goto err;
+        }
+        if (ci->subjectUID) {
+            if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0)
+                goto err;
+            if (!X509_signature_dump(bp, ci->subjectUID, 12))
+                goto err;
+        }
+    }
+
     if (!(cflag & X509_FLAG_NO_EXTENSIONS))
         X509V3_extensions_print(bp, "X509v3 extensions",
                                 ci->extensions, cflag, 8);

+ 3 - 1
libs/openssl/crypto/asn1/x_crl.c

@@ -58,8 +58,8 @@
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "asn1_locl.h"
 #include <openssl/asn1t.h>
+#include "asn1_locl.h"
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
@@ -341,6 +341,8 @@ ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
 
+IMPLEMENT_ASN1_DUP_FUNCTION(X509_REVOKED)
+
 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
 
 IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)

+ 20 - 0
libs/openssl/crypto/asn1/x_x509.c

@@ -208,3 +208,23 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp)
         length += i2d_X509_CERT_AUX(a->aux, pp);
     return length;
 }
+
+int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
+{
+    x->cert_info->enc.modified = 1;
+    return i2d_X509_CINF(x->cert_info, pp);
+}
+
+void X509_get0_signature(ASN1_BIT_STRING **psig, X509_ALGOR **palg,
+                         const X509 *x)
+{
+    if (psig)
+        *psig = x->signature;
+    if (palg)
+        *palg = x->sig_alg;
+}
+
+int X509_get_signature_nid(const X509 *x)
+{
+    return OBJ_obj2nid(x->sig_alg->algorithm);
+}

+ 25 - 0
libs/openssl/crypto/bio/b_dump.c

@@ -182,3 +182,28 @@ int BIO_dump_indent(BIO *bp, const char *s, int len, int indent)
 {
     return BIO_dump_indent_cb(write_bio, bp, s, len, indent);
 }
+
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen)
+{
+    int i, j = 0;
+
+    if (datalen < 1)
+        return 1;
+
+    for (i = 0; i < datalen - 1; i++) {
+        if (i && !j)
+            BIO_printf(out, "%*s", indent, "");
+
+        BIO_printf(out, "%02X:", data[i]);
+
+        j = (j + 1) % width;
+        if (!j)
+            BIO_printf(out, "\n");
+    }
+
+    if (i && !j)
+        BIO_printf(out, "%*s", indent, "");
+    BIO_printf(out, "%02X", data[datalen - 1]);
+    return 1;
+}

+ 6 - 2
libs/openssl/crypto/bio/b_sock.c

@@ -225,13 +225,17 @@ int BIO_get_port(const char *str, unsigned short *port_ptr)
 int BIO_sock_error(int sock)
 {
     int j, i;
-    int size;
+    union {
+        size_t s;
+        int i;
+    } size;
 
 # if defined(OPENSSL_SYS_BEOS_R5)
     return 0;
 # endif
 
-    size = sizeof(int);
+    /* heuristic way to adapt for platforms that expect 64-bit optlen */
+    size.s = 0, size.i = sizeof(j);
     /*
      * Note: under Windows the third parameter is of type (char *) whereas
      * under other systems it is (void *) if you don't have a cast it will

+ 6 - 2
libs/openssl/crypto/bio/bio.h

@@ -174,6 +174,7 @@ extern "C" {
 
 # define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT   45/* Next DTLS handshake timeout
                                               * to adjust socket timeouts */
+# define BIO_CTRL_DGRAM_SET_DONT_FRAG      48
 
 # define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD   49
 
@@ -725,6 +726,9 @@ int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent);
 int BIO_dump_fp(FILE *fp, const char *s, int len);
 int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent);
 # endif
+int BIO_hex_string(BIO *out, int indent, int width, unsigned char *data,
+                   int datalen);
+
 struct hostent *BIO_gethostbyname(const char *name);
 /*-
  * We might want a thread-safe interface too:
@@ -761,8 +765,8 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b);
 int BIO_dgram_sctp_msg_waiting(BIO *b);
 # endif
 BIO *BIO_new_fd(int fd, int close_flag);
-BIO *BIO_new_connect(char *host_port);
-BIO *BIO_new_accept(char *host_port);
+BIO *BIO_new_connect(const char *host_port);
+BIO *BIO_new_accept(const char *host_port);
 
 int BIO_new_bio_pair(BIO **bio1, size_t writebuf1,
                      BIO **bio2, size_t writebuf2);

+ 1 - 1
libs/openssl/crypto/bio/bio_err.c

@@ -1,6 +1,6 @@
 /* crypto/bio/bio_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2015 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

+ 1 - 1
libs/openssl/crypto/bio/bss_acpt.c

@@ -445,7 +445,7 @@ static int acpt_puts(BIO *bp, const char *str)
     return (ret);
 }
 
-BIO *BIO_new_accept(char *str)
+BIO *BIO_new_accept(const char *str)
 {
     BIO *ret;
 

+ 1 - 1
libs/openssl/crypto/bio/bss_conn.c

@@ -585,7 +585,7 @@ static int conn_puts(BIO *bp, const char *str)
     return (ret);
 }
 
-BIO *BIO_new_connect(char *str)
+BIO *BIO_new_connect(const char *str)
 {
     BIO *ret;
 

+ 20 - 2
libs/openssl/crypto/bio/bss_fd.c

@@ -63,9 +63,27 @@
 
 #if defined(OPENSSL_NO_POSIX_IO)
 /*
- * One can argue that one should implement dummy placeholder for
- * BIO_s_fd here...
+ * Dummy placeholder for BIO_s_fd...
  */
+BIO *BIO_new_fd(int fd, int close_flag)
+{
+    return NULL;
+}
+
+int BIO_fd_non_fatal_error(int err)
+{
+    return 0;
+}
+
+int BIO_fd_should_retry(int i)
+{
+    return 0;
+}
+
+BIO_METHOD *BIO_s_fd(void)
+{
+    return NULL;
+}
 #else
 /*
  * As for unconditional usage of "UPLINK" interface in this module.

+ 0 - 18
libs/openssl/crypto/bn/bn.h

@@ -256,24 +256,6 @@ extern "C" {
 #  define BN_HEX_FMT2     "%08X"
 # endif
 
-/*
- * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
- * size_t was used to perform integer-only operations on pointers.  This
- * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
- * is still only 32 bits.  What's needed in these cases is an integer type
- * with the same size as a pointer, which size_t is not certain to be. The
- * only fix here is VMS-specific.
- */
-# if defined(OPENSSL_SYS_VMS)
-#  if __INITIAL_POINTER_SIZE == 64
-#   define PTR_SIZE_INT long long
-#  else                         /* __INITIAL_POINTER_SIZE == 64 */
-#   define PTR_SIZE_INT int
-#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
-# else                          /* defined(OPENSSL_SYS_VMS) */
-#  define PTR_SIZE_INT size_t
-# endif                         /* defined(OPENSSL_SYS_VMS) [else] */
-
 # define BN_DEFAULT_BITS 1280
 
 # define BN_FLG_MALLOCED         0x01

+ 121 - 122
libs/openssl/crypto/bn/bn_asm.c

@@ -489,121 +489,144 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
  * c=(c2,c1,c0)
  */
 
+# ifdef BN_LLONG
 /*
- * Keep in mind that carrying into high part of multiplication result
- * can not overflow, because it cannot be all-ones.
+ * Keep in mind that additions to multiplication result can not
+ * overflow, because its high half cannot be all-ones.
  */
-# ifdef BN_LLONG
-#  define mul_add_c(a,b,c0,c1,c2) \
-        t=(BN_ULLONG)a*b; \
-        t1=(BN_ULONG)Lw(t); \
-        t2=(BN_ULONG)Hw(t); \
-        c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
-
-#  define mul_add_c2(a,b,c0,c1,c2) \
-        t=(BN_ULLONG)a*b; \
-        tt=(t+t)&BN_MASK; \
-        if (tt < t) c2++; \
-        t1=(BN_ULONG)Lw(tt); \
-        t2=(BN_ULONG)Hw(tt); \
-        c0=(c0+t1)&BN_MASK2;  \
-        if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
-
-#  define sqr_add_c(a,i,c0,c1,c2) \
-        t=(BN_ULLONG)a[i]*a[i]; \
-        t1=(BN_ULONG)Lw(t); \
-        t2=(BN_ULONG)Hw(t); \
-        c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)(a)*(b);       \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)(a)*(b);       \
+        BN_ULLONG tt = t+c0;    /* no carry */  \
+        c0 = (BN_ULONG)Lw(tt);                  \
+        hi = (BN_ULONG)Hw(tt);                  \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG hi;                            \
+        BN_ULLONG t = (BN_ULLONG)a[i]*a[i];     \
+        t += c0;                /* no carry */  \
+        c0 = (BN_ULONG)Lw(t);                   \
+        hi = (BN_ULONG)Hw(t);                   \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
 
 #  define sqr_add_c2(a,i,j,c0,c1,c2) \
         mul_add_c2((a)[i],(a)[j],c0,c1,c2)
 
 # elif defined(BN_UMULT_LOHI)
-
-#  define mul_add_c(a,b,c0,c1,c2) {       \
-        BN_ULONG ta=(a),tb=(b);         \
-        BN_UMULT_LOHI(t1,t2,ta,tb);     \
-        c0 += t1; t2 += (c0<t1)?1:0;    \
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        }
-
-#  define mul_add_c2(a,b,c0,c1,c2) {      \
-        BN_ULONG ta=(a),tb=(b),t0;      \
-        BN_UMULT_LOHI(t0,t1,ta,tb);     \
-        c0 += t0; t2 = t1+((c0<t0)?1:0);\
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        c0 += t0; t1 += (c0<t0)?1:0;    \
-        c1 += t1; c2 += (c1<t1)?1:0;    \
-        }
-
-#  define sqr_add_c(a,i,c0,c1,c2) {       \
-        BN_ULONG ta=(a)[i];             \
-        BN_UMULT_LOHI(t1,t2,ta,ta);     \
-        c0 += t1; t2 += (c0<t1)?1:0;    \
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        }
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo, hi;                        \
+        BN_UMULT_LOHI(lo,hi,ta,tb);             \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo, hi, tt;                    \
+        BN_UMULT_LOHI(lo,hi,ta,tb);             \
+        c0 += lo; tt = hi+((c0<lo)?1:0);        \
+        c1 += tt; c2 += (c1<tt)?1:0;            \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a)[i];                   \
+        BN_ULONG lo, hi;                        \
+        BN_UMULT_LOHI(lo,hi,ta,ta);             \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
 
 #  define sqr_add_c2(a,i,j,c0,c1,c2)    \
         mul_add_c2((a)[i],(a)[j],c0,c1,c2)
 
 # elif defined(BN_UMULT_HIGH)
-
-#  define mul_add_c(a,b,c0,c1,c2) {       \
-        BN_ULONG ta=(a),tb=(b);         \
-        t1 = ta * tb;                   \
-        t2 = BN_UMULT_HIGH(ta,tb);      \
-        c0 += t1; t2 += (c0<t1)?1:0;    \
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        }
-
-#  define mul_add_c2(a,b,c0,c1,c2) {      \
-        BN_ULONG ta=(a),tb=(b),t0;      \
-        t1 = BN_UMULT_HIGH(ta,tb);      \
-        t0 = ta * tb;                   \
-        c0 += t0; t2 = t1+((c0<t0)?1:0);\
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        c0 += t0; t1 += (c0<t0)?1:0;    \
-        c1 += t1; c2 += (c1<t1)?1:0;    \
-        }
-
-#  define sqr_add_c(a,i,c0,c1,c2) {       \
-        BN_ULONG ta=(a)[i];             \
-        t1 = ta * ta;                   \
-        t2 = BN_UMULT_HIGH(ta,ta);      \
-        c0 += t1; t2 += (c0<t1)?1:0;    \
-        c1 += t2; c2 += (c1<t2)?1:0;    \
-        }
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a), tb = (b);            \
+        BN_ULONG lo = ta * tb;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,tb);     \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG ta = (a), tb = (b), tt;        \
+        BN_ULONG lo = ta * tb;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,tb);     \
+        c0 += lo; tt = hi + ((c0<lo)?1:0);      \
+        c1 += tt; c2 += (c1<tt)?1:0;            \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG ta = (a)[i];                   \
+        BN_ULONG lo = ta * ta;                  \
+        BN_ULONG hi = BN_UMULT_HIGH(ta,ta);     \
+        c0 += lo; hi += (c0<lo)?1:0;            \
+        c1 += hi; c2 += (c1<hi)?1:0;            \
+        } while(0)
 
 #  define sqr_add_c2(a,i,j,c0,c1,c2)      \
         mul_add_c2((a)[i],(a)[j],c0,c1,c2)
 
 # else                          /* !BN_LLONG */
-#  define mul_add_c(a,b,c0,c1,c2) \
-        t1=LBITS(a); t2=HBITS(a); \
-        bl=LBITS(b); bh=HBITS(b); \
-        mul64(t1,t2,bl,bh); \
-        c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
-
-#  define mul_add_c2(a,b,c0,c1,c2) \
-        t1=LBITS(a); t2=HBITS(a); \
-        bl=LBITS(b); bh=HBITS(b); \
-        mul64(t1,t2,bl,bh); \
-        if (t2 & BN_TBIT) c2++; \
-        t2=(t2+t2)&BN_MASK2; \
-        if (t1 & BN_TBIT) t2++; \
-        t1=(t1+t1)&BN_MASK2; \
-        c0=(c0+t1)&BN_MASK2;  \
-        if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
-
-#  define sqr_add_c(a,i,c0,c1,c2) \
-        sqr64(t1,t2,(a)[i]); \
-        c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \
-        c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++;
+/*
+ * Keep in mind that additions to hi can not overflow, because
+ * the high word of a multiplication result cannot be all-ones.
+ */
+#  define mul_add_c(a,b,c0,c1,c2)       do {    \
+        BN_ULONG lo = LBITS(a), hi = HBITS(a);  \
+        BN_ULONG bl = LBITS(b), bh = HBITS(b);  \
+        mul64(lo,hi,bl,bh);                     \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define mul_add_c2(a,b,c0,c1,c2)      do {    \
+        BN_ULONG tt;                            \
+        BN_ULONG lo = LBITS(a), hi = HBITS(a);  \
+        BN_ULONG bl = LBITS(b), bh = HBITS(b);  \
+        mul64(lo,hi,bl,bh);                     \
+        tt = hi;                                \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) tt++; \
+        c1 = (c1+tt)&BN_MASK2; if (c1<tt) c2++; \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
+
+#  define sqr_add_c(a,i,c0,c1,c2)       do {    \
+        BN_ULONG lo, hi;                        \
+        sqr64(lo,hi,(a)[i]);                    \
+        c0 = (c0+lo)&BN_MASK2; if (c0<lo) hi++; \
+        c1 = (c1+hi)&BN_MASK2; if (c1<hi) c2++; \
+        } while(0)
 
 #  define sqr_add_c2(a,i,j,c0,c1,c2) \
         mul_add_c2((a)[i],(a)[j],c0,c1,c2)
@@ -611,12 +634,6 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
 
 void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 {
-# ifdef BN_LLONG
-    BN_ULLONG t;
-# else
-    BN_ULONG bl, bh;
-# endif
-    BN_ULONG t1, t2;
     BN_ULONG c1, c2, c3;
 
     c1 = 0;
@@ -720,12 +737,6 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 
 void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 {
-# ifdef BN_LLONG
-    BN_ULLONG t;
-# else
-    BN_ULONG bl, bh;
-# endif
-    BN_ULONG t1, t2;
     BN_ULONG c1, c2, c3;
 
     c1 = 0;
@@ -765,12 +776,6 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
 
 void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
 {
-# ifdef BN_LLONG
-    BN_ULLONG t, tt;
-# else
-    BN_ULONG bl, bh;
-# endif
-    BN_ULONG t1, t2;
     BN_ULONG c1, c2, c3;
 
     c1 = 0;
@@ -846,12 +851,6 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
 
 void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a)
 {
-# ifdef BN_LLONG
-    BN_ULLONG t, tt;
-# else
-    BN_ULONG bl, bh;
-# endif
-    BN_ULONG t1, t2;
     BN_ULONG c1, c2, c3;
 
     c1 = 0;

+ 300 - 26
libs/openssl/crypto/bn/bn_exp.c

@@ -122,6 +122,17 @@
 # ifndef alloca
 #  define alloca(s) __builtin_alloca((s))
 # endif
+#elif defined(__sun)
+# include <alloca.h>
+#endif
+
+#include "rsaz_exp.h"
+
+#undef SPARC_T4_MONT
+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
+# include "sparc_arch.h"
+extern unsigned int OPENSSL_sparcv9cap_P[];
+# define SPARC_T4_MONT
 #endif
 
 /* maximum precomputation table size for *variable* sliding windows */
@@ -464,6 +475,23 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     wstart = bits - 1;          /* The top bit of the window */
     wend = 0;                   /* The bottom bit of the window */
 
+#if 1                           /* by Shay Gueron's suggestion */
+    j = m->top;                 /* borrow j */
+    if (m->d[j - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+        if (bn_wexpand(r, j) == NULL)
+            goto err;
+        /* 2^(top*BN_BITS2) - m */
+        r->d[0] = (0 - m->d[0]) & BN_MASK2;
+        for (i = 1; i < j; i++)
+            r->d[i] = (~m->d[i]) & BN_MASK2;
+        r->top = j;
+        /*
+         * Upper words will be zero if the corresponding words of 'm' were
+         * 0xfff[...], so decrement r->top accordingly.
+         */
+        bn_correct_top(r);
+    } else
+#endif
     if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
         goto err;
     for (;;) {
@@ -515,6 +543,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
         if (wstart < 0)
             break;
     }
+#if defined(SPARC_T4_MONT)
+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+        j = mont->N.top;        /* borrow j */
+        val[0]->d[0] = 1;       /* borrow val[0] */
+        for (i = 1; i < j; i++)
+            val[0]->d[i] = 0;
+        val[0]->top = j;
+        if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
+            goto err;
+    } else
+#endif
     if (!BN_from_montgomery(rr, r, mont, ctx))
         goto err;
     ret = 1;
@@ -526,6 +565,27 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     return (ret);
 }
 
+#if defined(SPARC_T4_MONT)
+static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos)
+{
+    BN_ULONG ret = 0;
+    int wordpos;
+
+    wordpos = bitpos / BN_BITS2;
+    bitpos %= BN_BITS2;
+    if (wordpos >= 0 && wordpos < a->top) {
+        ret = a->d[wordpos] & BN_MASK2;
+        if (bitpos) {
+            ret >>= bitpos;
+            if (++wordpos < a->top)
+                ret |= a->d[wordpos] << (BN_BITS2 - bitpos);
+        }
+    }
+
+    return ret & BN_MASK2;
+}
+#endif
+
 /*
  * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific
  * layout so that accessing any of these table values shows the same access
@@ -594,6 +654,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     int powerbufLen = 0;
     unsigned char *powerbuf = NULL;
     BIGNUM tmp, am;
+#if defined(SPARC_T4_MONT)
+    unsigned int t4 = 0;
+#endif
 
     bn_check_top(a);
     bn_check_top(p);
@@ -626,21 +689,62 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
             goto err;
     }
 
+#ifdef RSAZ_ENABLED
+    /*
+     * If the size of the operands allow it, perform the optimized
+     * RSAZ exponentiation. For further information see
+     * crypto/bn/rsaz_exp.c and accompanying assembly modules.
+     */
+    if ((16 == a->top) && (16 == p->top) && (BN_num_bits(m) == 1024)
+        && rsaz_avx2_eligible()) {
+        if (NULL == bn_wexpand(rr, 16))
+            goto err;
+        RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,
+                               mont->n0[0]);
+        rr->top = 16;
+        rr->neg = 0;
+        bn_correct_top(rr);
+        ret = 1;
+        goto err;
+    } else if ((8 == a->top) && (8 == p->top) && (BN_num_bits(m) == 512)) {
+        if (NULL == bn_wexpand(rr, 8))
+            goto err;
+        RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
+        rr->top = 8;
+        rr->neg = 0;
+        bn_correct_top(rr);
+        ret = 1;
+        goto err;
+    }
+#endif
+
     /* Get the window size to use with size of p. */
     window = BN_window_bits_for_ctime_exponent_size(bits);
+#if defined(SPARC_T4_MONT)
+    if (window >= 5 && (top & 15) == 0 && top <= 64 &&
+        (OPENSSL_sparcv9cap_P[1] & (CFR_MONTMUL | CFR_MONTSQR)) ==
+        (CFR_MONTMUL | CFR_MONTSQR) && (t4 = OPENSSL_sparcv9cap_P[0]))
+        window = 5;
+    else
+#endif
 #if defined(OPENSSL_BN_ASM_MONT5)
-    if (window == 6 && bits <= 1024)
-        window = 5;             /* ~5% improvement of 2048-bit RSA sign */
+    if (window >= 5) {
+        window = 5;             /* ~5% improvement for RSA2048 sign, and even
+                                 * for RSA4096 */
+        if ((top & 7) == 0)
+            powerbufLen += 2 * top * sizeof(m->d[0]);
+    }
 #endif
+    (void)0;
 
     /*
      * Allocate a buffer large enough to hold all of the pre-computed powers
      * of am, am itself and tmp.
      */
     numPowers = 1 << window;
-    powerbufLen = sizeof(m->d[0]) * (top * numPowers +
-                                     ((2 * top) >
-                                      numPowers ? (2 * top) : numPowers));
+    powerbufLen += sizeof(m->d[0]) * (top * numPowers +
+                                      ((2 * top) >
+                                       numPowers ? (2 * top) : numPowers));
 #ifdef alloca
     if (powerbufLen < 3072)
         powerbufFree =
@@ -670,15 +774,17 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     tmp.flags = am.flags = BN_FLG_STATIC_DATA;
 
     /* prepare a^0 in Montgomery domain */
-#if 1
+#if 1                           /* by Shay Gueron's suggestion */
+    if (m->d[top - 1] & (((BN_ULONG)1) << (BN_BITS2 - 1))) {
+        /* 2^(top*BN_BITS2) - m */
+        tmp.d[0] = (0 - m->d[0]) & BN_MASK2;
+        for (i = 1; i < top; i++)
+            tmp.d[i] = (~m->d[i]) & BN_MASK2;
+        tmp.top = top;
+    } else
+#endif
     if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx))
         goto err;
-#else
-    tmp.d[0] = (0 - m->d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */
-    for (i = 1; i < top; i++)
-        tmp.d[i] = (~m->d[i]) & BN_MASK2;
-    tmp.top = top;
-#endif
 
     /* prepare a^1 in Montgomery domain */
     if (a->neg || BN_ucmp(a, m) >= 0) {
@@ -689,6 +795,138 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     } else if (!BN_to_montgomery(&am, a, mont, ctx))
         goto err;
 
+#if defined(SPARC_T4_MONT)
+    if (t4) {
+        typedef int (*bn_pwr5_mont_f) (BN_ULONG *tp, const BN_ULONG *np,
+                                       const BN_ULONG *n0, const void *table,
+                                       int power, int bits);
+        int bn_pwr5_mont_t4_8(BN_ULONG *tp, const BN_ULONG *np,
+                              const BN_ULONG *n0, const void *table,
+                              int power, int bits);
+        int bn_pwr5_mont_t4_16(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        int bn_pwr5_mont_t4_24(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        int bn_pwr5_mont_t4_32(BN_ULONG *tp, const BN_ULONG *np,
+                               const BN_ULONG *n0, const void *table,
+                               int power, int bits);
+        static const bn_pwr5_mont_f pwr5_funcs[4] = {
+            bn_pwr5_mont_t4_8, bn_pwr5_mont_t4_16,
+            bn_pwr5_mont_t4_24, bn_pwr5_mont_t4_32
+        };
+        bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top / 16 - 1];
+
+        typedef int (*bn_mul_mont_f) (BN_ULONG *rp, const BN_ULONG *ap,
+                                      const void *bp, const BN_ULONG *np,
+                                      const BN_ULONG *n0);
+        int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const void *bp,
+                             const BN_ULONG *np, const BN_ULONG *n0);
+        int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0);
+        static const bn_mul_mont_f mul_funcs[4] = {
+            bn_mul_mont_t4_8, bn_mul_mont_t4_16,
+            bn_mul_mont_t4_24, bn_mul_mont_t4_32
+        };
+        bn_mul_mont_f mul_worker = mul_funcs[top / 16 - 1];
+
+        void bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap,
+                              const void *bp, const BN_ULONG *np,
+                              const BN_ULONG *n0, int num);
+        void bn_mul_mont_t4(BN_ULONG *rp, const BN_ULONG *ap,
+                            const void *bp, const BN_ULONG *np,
+                            const BN_ULONG *n0, int num);
+        void bn_mul_mont_gather5_t4(BN_ULONG *rp, const BN_ULONG *ap,
+                                    const void *table, const BN_ULONG *np,
+                                    const BN_ULONG *n0, int num, int power);
+        void bn_flip_n_scatter5_t4(const BN_ULONG *inp, size_t num,
+                                   void *table, size_t power);
+        void bn_gather5_t4(BN_ULONG *out, size_t num,
+                           void *table, size_t power);
+        void bn_flip_t4(BN_ULONG *dst, BN_ULONG *src, size_t num);
+
+        BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+        int stride = 5 * (6 - (top / 16 - 1)); /* multiple of 5, but less
+                                                * than 32 */
+
+        /*
+         * BN_to_montgomery can contaminate words above .top [in
+         * BN_DEBUG[_DEBUG] build]...
+         */
+        for (i = am.top; i < top; i++)
+            am.d[i] = 0;
+        for (i = tmp.top; i < top; i++)
+            tmp.d[i] = 0;
+
+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 0);
+        bn_flip_n_scatter5_t4(am.d, top, powerbuf, 1);
+        if (!(*mul_worker) (tmp.d, am.d, am.d, np, n0) &&
+            !(*mul_worker) (tmp.d, am.d, am.d, np, n0))
+            bn_mul_mont_vis3(tmp.d, am.d, am.d, np, n0, top);
+        bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, 2);
+
+        for (i = 3; i < 32; i++) {
+            /* Calculate a^i = a^(i-1) * a */
+            if (!(*mul_worker) (tmp.d, tmp.d, am.d, np, n0) &&
+                !(*mul_worker) (tmp.d, tmp.d, am.d, np, n0))
+                bn_mul_mont_vis3(tmp.d, tmp.d, am.d, np, n0, top);
+            bn_flip_n_scatter5_t4(tmp.d, top, powerbuf, i);
+        }
+
+        /* switch to 64-bit domain */
+        np = alloca(top * sizeof(BN_ULONG));
+        top /= 2;
+        bn_flip_t4(np, mont->N.d, top);
+
+        bits--;
+        for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--)
+            wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+        bn_gather5_t4(tmp.d, top, powerbuf, wvalue);
+
+        /*
+         * Scan the exponent one window at a time starting from the most
+         * significant bits.
+         */
+        while (bits >= 0) {
+            if (bits < stride)
+                stride = bits + 1;
+            bits -= stride;
+            wvalue = bn_get_bits(p, bits + 1);
+
+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+                continue;
+            /* retry once and fall back */
+            if ((*pwr5_worker) (tmp.d, np, n0, powerbuf, wvalue, stride))
+                continue;
+
+            bits += stride - 5;
+            wvalue >>= stride - 5;
+            wvalue &= 31;
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_t4(tmp.d, tmp.d, tmp.d, np, n0, top);
+            bn_mul_mont_gather5_t4(tmp.d, tmp.d, powerbuf, np, n0, top,
+                                   wvalue);
+        }
+
+        bn_flip_t4(tmp.d, tmp.d, top);
+        top *= 2;
+        /* back to 32-bit domain */
+        tmp.top = top;
+        bn_correct_top(&tmp);
+        OPENSSL_cleanse(np, top * sizeof(BN_ULONG));
+    } else
+#endif
 #if defined(OPENSSL_BN_ASM_MONT5)
     if (window == 5 && top > 1) {
         /*
@@ -707,8 +945,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
         void bn_scatter5(const BN_ULONG *inp, size_t num,
                          void *table, size_t power);
         void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power);
+        void bn_power5(BN_ULONG *rp, const BN_ULONG *ap,
+                       const void *table, const BN_ULONG *np,
+                       const BN_ULONG *n0, int num, int power);
+        int bn_get_bits5(const BN_ULONG *ap, int off);
+        int bn_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap,
+                               const BN_ULONG *not_used, const BN_ULONG *np,
+                               const BN_ULONG *n0, int num);
 
-        BN_ULONG *np = mont->N.d, *n0 = mont->n0;
+        BN_ULONG *np = mont->N.d, *n0 = mont->n0, *np2;
 
         /*
          * BN_to_montgomery can contaminate words above .top [in
@@ -719,6 +964,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
         for (i = tmp.top; i < top; i++)
             tmp.d[i] = 0;
 
+        if (top & 7)
+            np2 = np;
+        else
+            for (np2 = am.d + top, i = 0; i < top; i++)
+                np2[2 * i] = np[i];
+
         bn_scatter5(tmp.d, top, powerbuf, 0);
         bn_scatter5(am.d, am.top, powerbuf, 1);
         bn_mul_mont(tmp.d, am.d, am.d, np, n0, top);
@@ -727,7 +978,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
 # if 0
         for (i = 3; i < 32; i++) {
             /* Calculate a^i = a^(i-1) * a */
-            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
             bn_scatter5(tmp.d, top, powerbuf, i);
         }
 # else
@@ -738,7 +989,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
         }
         for (i = 3; i < 8; i += 2) {
             int j;
-            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
             bn_scatter5(tmp.d, top, powerbuf, i);
             for (j = 2 * i; j < 32; j *= 2) {
                 bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
@@ -746,13 +997,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
             }
         }
         for (; i < 16; i += 2) {
-            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
             bn_scatter5(tmp.d, top, powerbuf, i);
             bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
             bn_scatter5(tmp.d, top, powerbuf, 2 * i);
         }
         for (; i < 32; i += 2) {
-            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1);
+            bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np2, n0, top, i - 1);
             bn_scatter5(tmp.d, top, powerbuf, i);
         }
 # endif
@@ -765,20 +1016,34 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
          * Scan the exponent one window at a time starting from the most
          * significant bits.
          */
-        while (bits >= 0) {
-            for (wvalue = 0, i = 0; i < 5; i++, bits--)
-                wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
+        if (top & 7)
+            while (bits >= 0) {
+                for (wvalue = 0, i = 0; i < 5; i++, bits--)
+                    wvalue = (wvalue << 1) + BN_is_bit_set(p, bits);
 
-            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-            bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
-            bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top);
+                bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top,
+                                    wvalue);
+        } else {
+            while (bits >= 0) {
+                wvalue = bn_get_bits5(p->d, bits - 4);
+                bits -= 5;
+                bn_power5(tmp.d, tmp.d, powerbuf, np2, n0, top, wvalue);
+            }
         }
 
+        ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np2, n0, top);
         tmp.top = top;
         bn_correct_top(&tmp);
+        if (ret) {
+            if (!BN_copy(rr, &tmp))
+                ret = 0;
+            goto err;           /* non-zero ret means it's not error */
+        }
     } else
 #endif
     {
@@ -844,6 +1109,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
     }
 
     /* Convert the final result from montgomery to standard format */
+#if defined(SPARC_T4_MONT)
+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3 | SPARCV9_PREFER_FPU)) {
+        am.d[0] = 1;            /* borrow am */
+        for (i = 1; i < top; i++)
+            am.d[i] = 0;
+        if (!BN_mod_mul_montgomery(rr, &tmp, &am, mont, ctx))
+            goto err;
+    } else
+#endif
     if (!BN_from_montgomery(rr, &tmp, mont, ctx))
         goto err;
     ret = 1;

+ 1 - 2
libs/openssl/crypto/bn/bn_gf2m.c

@@ -450,8 +450,7 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
             d0 = p[k] % BN_BITS2;
             d1 = BN_BITS2 - d0;
             z[n] ^= (zz << d0);
-            tmp_ulong = zz >> d1;
-            if (d0 && tmp_ulong)
+            if (d0 && (tmp_ulong = zz >> d1))
                 z[n + 1] ^= tmp_ulong;
         }
 

+ 27 - 0
libs/openssl/crypto/bn/bn_lcl.h

@@ -204,6 +204,24 @@ extern "C" {
 # define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL        (32)/* 32 */
 # define BN_MONT_CTX_SET_SIZE_WORD               (64)/* 32 */
 
+/*
+ * 2011-02-22 SMS. In various places, a size_t variable or a type cast to
+ * size_t was used to perform integer-only operations on pointers.  This
+ * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t
+ * is still only 32 bits.  What's needed in these cases is an integer type
+ * with the same size as a pointer, which size_t is not certain to be. The
+ * only fix here is VMS-specific.
+ */
+# if defined(OPENSSL_SYS_VMS)
+#  if __INITIAL_POINTER_SIZE == 64
+#   define PTR_SIZE_INT long long
+#  else                         /* __INITIAL_POINTER_SIZE == 64 */
+#   define PTR_SIZE_INT int
+#  endif                        /* __INITIAL_POINTER_SIZE == 64 [else] */
+# elif !defined(PTR_SIZE_INT)   /* defined(OPENSSL_SYS_VMS) */
+#  define PTR_SIZE_INT size_t
+# endif                         /* defined(OPENSSL_SYS_VMS) [else] */
+
 # if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
 /*
  * BN_UMULT_HIGH section.
@@ -295,6 +313,15 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
              : "r"(a), "r"(b));
 #    endif
 #   endif
+#  elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
+#   if defined(__GNUC__) && __GNUC__>=2
+#    define BN_UMULT_HIGH(a,b)   ({      \
+        register BN_ULONG ret;          \
+        asm ("umulh     %0,%1,%2"       \
+             : "=r"(ret)                \
+             : "r"(a), "r"(b));         \
+        ret;                    })
+#   endif
 #  endif                        /* cpu */
 # endif                         /* OPENSSL_NO_ASM */
 

+ 346 - 0
libs/openssl/crypto/bn/rsaz_exp.c

@@ -0,0 +1,346 @@
+/*****************************************************************************
+*                                                                            *
+*  Copyright (c) 2012, Intel Corporation                                     *
+*                                                                            *
+*  All rights reserved.                                                      *
+*                                                                            *
+*  Redistribution and use in source and binary forms, with or without        *
+*  modification, are permitted provided that the following conditions are    *
+*  met:                                                                      *
+*                                                                            *
+*  *  Redistributions of source code must retain the above copyright         *
+*     notice, this list of conditions and the following disclaimer.          *
+*                                                                            *
+*  *  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.                                                          *
+*                                                                            *
+*  *  Neither the name of the Intel Corporation nor the names of its         *
+*     contributors may be used to endorse or promote products derived from   *
+*     this software without specific prior written permission.               *
+*                                                                            *
+*                                                                            *
+*  THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""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 INTEL CORPORATION 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.              *
+*                                                                            *
+******************************************************************************
+* Developers and authors:                                                    *
+* Shay Gueron (1, 2), and Vlad Krasnov (1)                                   *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel            *
+* (2) University of Haifa, Israel                                            *
+*****************************************************************************/
+
+#include "rsaz_exp.h"
+
+#ifdef RSAZ_ENABLED
+
+/*
+ * See crypto/bn/asm/rsaz-avx2.pl for further details.
+ */
+void rsaz_1024_norm2red_avx2(void *red, const void *norm);
+void rsaz_1024_mul_avx2(void *ret, const void *a, const void *b,
+                        const void *n, BN_ULONG k);
+void rsaz_1024_sqr_avx2(void *ret, const void *a, const void *n, BN_ULONG k,
+                        int cnt);
+void rsaz_1024_scatter5_avx2(void *tbl, const void *val, int i);
+void rsaz_1024_gather5_avx2(void *val, const void *tbl, int i);
+void rsaz_1024_red2norm_avx2(void *norm, const void *red);
+
+#if defined(__GNUC__)
+# define ALIGN64        __attribute__((aligned(64)))
+#elif defined(_MSC_VER)
+# define ALIGN64        __declspec(align(64))
+#elif defined(__SUNPRO_C)
+# define ALIGN64
+# pragma align 64(one,two80)
+#else
+/* not fatal, might hurt performance a little */
+# define ALIGN64
+#endif
+
+ALIGN64 static const BN_ULONG one[40] = {
+    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+ALIGN64 static const BN_ULONG two80[40] = {
+    0, 0, 1 << 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void RSAZ_1024_mod_exp_avx2(BN_ULONG result_norm[16],
+                            const BN_ULONG base_norm[16],
+                            const BN_ULONG exponent[16],
+                            const BN_ULONG m_norm[16], const BN_ULONG RR[16],
+                            BN_ULONG k0)
+{
+    unsigned char storage[320 * 3 + 32 * 9 * 16 + 64]; /* 5.5KB */
+    unsigned char *p_str = storage + (64 - ((size_t)storage % 64));
+    unsigned char *a_inv, *m, *result;
+    unsigned char *table_s = p_str + 320 * 3;
+    unsigned char *R2 = table_s; /* borrow */
+    int index;
+    int wvalue;
+
+    if ((((size_t)p_str & 4095) + 320) >> 12) {
+        result = p_str;
+        a_inv = p_str + 320;
+        m = p_str + 320 * 2;    /* should not cross page */
+    } else {
+        m = p_str;              /* should not cross page */
+        result = p_str + 320;
+        a_inv = p_str + 320 * 2;
+    }
+
+    rsaz_1024_norm2red_avx2(m, m_norm);
+    rsaz_1024_norm2red_avx2(a_inv, base_norm);
+    rsaz_1024_norm2red_avx2(R2, RR);
+
+    rsaz_1024_mul_avx2(R2, R2, R2, m, k0);
+    rsaz_1024_mul_avx2(R2, R2, two80, m, k0);
+
+    /* table[0] = 1 */
+    rsaz_1024_mul_avx2(result, R2, one, m, k0);
+    /* table[1] = a_inv^1 */
+    rsaz_1024_mul_avx2(a_inv, a_inv, R2, m, k0);
+
+    rsaz_1024_scatter5_avx2(table_s, result, 0);
+    rsaz_1024_scatter5_avx2(table_s, a_inv, 1);
+
+    /* table[2] = a_inv^2 */
+    rsaz_1024_sqr_avx2(result, a_inv, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 2);
+#if 0
+    /* this is almost 2x smaller and less than 1% slower */
+    for (index = 3; index < 32; index++) {
+        rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+        rsaz_1024_scatter5_avx2(table_s, result, index);
+    }
+#else
+    /* table[4] = a_inv^4 */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 4);
+    /* table[8] = a_inv^8 */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 8);
+    /* table[16] = a_inv^16 */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 16);
+    /* table[17] = a_inv^17 */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 17);
+
+    /* table[3] */
+    rsaz_1024_gather5_avx2(result, table_s, 2);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 3);
+    /* table[6] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 6);
+    /* table[12] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 12);
+    /* table[24] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 24);
+    /* table[25] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 25);
+
+    /* table[5] */
+    rsaz_1024_gather5_avx2(result, table_s, 4);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 5);
+    /* table[10] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 10);
+    /* table[20] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 20);
+    /* table[21] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 21);
+
+    /* table[7] */
+    rsaz_1024_gather5_avx2(result, table_s, 6);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 7);
+    /* table[14] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 14);
+    /* table[28] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 28);
+    /* table[29] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 29);
+
+    /* table[9] */
+    rsaz_1024_gather5_avx2(result, table_s, 8);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 9);
+    /* table[18] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 18);
+    /* table[19] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 19);
+
+    /* table[11] */
+    rsaz_1024_gather5_avx2(result, table_s, 10);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 11);
+    /* table[22] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 22);
+    /* table[23] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 23);
+
+    /* table[13] */
+    rsaz_1024_gather5_avx2(result, table_s, 12);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 13);
+    /* table[26] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 26);
+    /* table[27] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 27);
+
+    /* table[15] */
+    rsaz_1024_gather5_avx2(result, table_s, 14);
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 15);
+    /* table[30] */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 1);
+    rsaz_1024_scatter5_avx2(table_s, result, 30);
+    /* table[31] */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    rsaz_1024_scatter5_avx2(table_s, result, 31);
+#endif
+
+    /* load first window */
+    p_str = (unsigned char *)exponent;
+    wvalue = p_str[127] >> 3;
+    rsaz_1024_gather5_avx2(result, table_s, wvalue);
+
+    index = 1014;
+
+    while (index > -1) {        /* loop for the remaining 127 windows */
+
+        rsaz_1024_sqr_avx2(result, result, m, k0, 5);
+
+        wvalue = *((unsigned short *)&p_str[index / 8]);
+        wvalue = (wvalue >> (index % 8)) & 31;
+        index -= 5;
+
+        rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */
+        rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+    }
+
+    /* square four times */
+    rsaz_1024_sqr_avx2(result, result, m, k0, 4);
+
+    wvalue = p_str[0] & 15;
+
+    rsaz_1024_gather5_avx2(a_inv, table_s, wvalue); /* borrow a_inv */
+    rsaz_1024_mul_avx2(result, result, a_inv, m, k0);
+
+    /* from Montgomery */
+    rsaz_1024_mul_avx2(result, result, one, m, k0);
+
+    rsaz_1024_red2norm_avx2(result_norm, result);
+
+    OPENSSL_cleanse(storage, sizeof(storage));
+}
+
+/*
+ * See crypto/bn/rsaz-x86_64.pl for further details.
+ */
+void rsaz_512_mul(void *ret, const void *a, const void *b, const void *n,
+                  BN_ULONG k);
+void rsaz_512_mul_scatter4(void *ret, const void *a, const void *n,
+                           BN_ULONG k, const void *tbl, unsigned int power);
+void rsaz_512_mul_gather4(void *ret, const void *a, const void *tbl,
+                          const void *n, BN_ULONG k, unsigned int power);
+void rsaz_512_mul_by_one(void *ret, const void *a, const void *n, BN_ULONG k);
+void rsaz_512_sqr(void *ret, const void *a, const void *n, BN_ULONG k,
+                  int cnt);
+void rsaz_512_scatter4(void *tbl, const BN_ULONG *val, int power);
+void rsaz_512_gather4(BN_ULONG *val, const void *tbl, int power);
+
+void RSAZ_512_mod_exp(BN_ULONG result[8],
+                      const BN_ULONG base[8], const BN_ULONG exponent[8],
+                      const BN_ULONG m[8], BN_ULONG k0, const BN_ULONG RR[8])
+{
+    unsigned char storage[16 * 8 * 8 + 64 * 2 + 64]; /* 1.2KB */
+    unsigned char *table = storage + (64 - ((size_t)storage % 64));
+    BN_ULONG *a_inv = (BN_ULONG *)(table + 16 * 8 * 8);
+    BN_ULONG *temp = (BN_ULONG *)(table + 16 * 8 * 8 + 8 * 8);
+    unsigned char *p_str = (unsigned char *)exponent;
+    int index;
+    unsigned int wvalue;
+
+    /* table[0] = 1_inv */
+    temp[0] = 0 - m[0];
+    temp[1] = ~m[1];
+    temp[2] = ~m[2];
+    temp[3] = ~m[3];
+    temp[4] = ~m[4];
+    temp[5] = ~m[5];
+    temp[6] = ~m[6];
+    temp[7] = ~m[7];
+    rsaz_512_scatter4(table, temp, 0);
+
+    /* table [1] = a_inv^1 */
+    rsaz_512_mul(a_inv, base, RR, m, k0);
+    rsaz_512_scatter4(table, a_inv, 1);
+
+    /* table [2] = a_inv^2 */
+    rsaz_512_sqr(temp, a_inv, m, k0, 1);
+    rsaz_512_scatter4(table, temp, 2);
+
+    for (index = 3; index < 16; index++)
+        rsaz_512_mul_scatter4(temp, a_inv, m, k0, table, index);
+
+    /* load first window */
+    wvalue = p_str[63];
+
+    rsaz_512_gather4(temp, table, wvalue >> 4);
+    rsaz_512_sqr(temp, temp, m, k0, 4);
+    rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0xf);
+
+    for (index = 62; index >= 0; index--) {
+        wvalue = p_str[index];
+
+        rsaz_512_sqr(temp, temp, m, k0, 4);
+        rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue >> 4);
+
+        rsaz_512_sqr(temp, temp, m, k0, 4);
+        rsaz_512_mul_gather4(temp, temp, table, m, k0, wvalue & 0x0f);
+    }
+
+    /* from Montgomery */
+    rsaz_512_mul_by_one(result, temp, m, k0);
+
+    OPENSSL_cleanse(storage, sizeof(storage));
+}
+
+#else
+
+# if defined(PEDANTIC) || defined(__DECC) || defined(__clang__)
+static void *dummy = &dummy;
+# endif
+
+#endif

+ 56 - 0
libs/openssl/crypto/bn/rsaz_exp.h

@@ -0,0 +1,56 @@
+/******************************************************************************
+* Copyright(c) 2012, Intel Corp.
+* Developers and authors:
+* Shay Gueron (1, 2), and Vlad Krasnov (1)
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel
+* (2) University of Haifa, Israel
+******************************************************************************
+* LICENSE:
+* This submission to OpenSSL is to be made available under the OpenSSL
+* license, and only to the OpenSSL project, in order to allow integration
+* into the publicly distributed code.
+* The use of this code, or portions of this code, or concepts embedded in
+* this code, or modification of this code and/or algorithm(s) in it, or the
+* use of this code for any other purpose than stated above, requires special
+* licensing.
+******************************************************************************
+* DISCLAIMER:
+* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS AND THE COPYRIGHT OWNERS
+* ``AS IS''. 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 CONTRIBUTORS OR THE COPYRIGHT
+* OWNERS 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.
+******************************************************************************/
+
+#ifndef RSAZ_EXP_H
+# define RSAZ_EXP_H
+
+# undef RSAZ_ENABLED
+# if defined(OPENSSL_BN_ASM_MONT) && \
+        (defined(__x86_64) || defined(__x86_64__) || \
+         defined(_M_AMD64) || defined(_M_X64))
+#  define RSAZ_ENABLED
+
+#  include <openssl/bn.h>
+
+void RSAZ_1024_mod_exp_avx2(BN_ULONG result[16],
+                            const BN_ULONG base_norm[16],
+                            const BN_ULONG exponent[16],
+                            const BN_ULONG m_norm[16], const BN_ULONG RR[16],
+                            BN_ULONG k0);
+int rsaz_avx2_eligible();
+
+void RSAZ_512_mod_exp(BN_ULONG result[8],
+                      const BN_ULONG base_norm[8], const BN_ULONG exponent[8],
+                      const BN_ULONG m_norm[8], BN_ULONG k0,
+                      const BN_ULONG RR[8]);
+
+# endif
+
+#endif

+ 11 - 0
libs/openssl/crypto/buffer/buf_str.c

@@ -60,6 +60,15 @@
 #include "cryptlib.h"
 #include <openssl/buffer.h>
 
+size_t BUF_strnlen(const char *str, size_t maxlen)
+{
+    const char *p;
+
+    for (p = str; maxlen-- != 0 && *p != '\0'; ++p) ;
+
+    return p - str;
+}
+
 char *BUF_strdup(const char *str)
 {
     if (str == NULL)
@@ -74,6 +83,8 @@ char *BUF_strndup(const char *str, size_t siz)
     if (str == NULL)
         return (NULL);
 
+    siz = BUF_strnlen(str, siz);
+
     ret = OPENSSL_malloc(siz + 1);
     if (ret == NULL) {
         BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE);

+ 1 - 0
libs/openssl/crypto/buffer/buffer.h

@@ -84,6 +84,7 @@ BUF_MEM *BUF_MEM_new(void);
 void BUF_MEM_free(BUF_MEM *a);
 int BUF_MEM_grow(BUF_MEM *str, size_t len);
 int BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
+size_t BUF_strnlen(const char *str, size_t maxlen);
 char *BUF_strdup(const char *str);
 char *BUF_strndup(const char *str, size_t siz);
 void *BUF_memdup(const void *data, size_t siz);

+ 3 - 3
libs/openssl/crypto/buildinf.h

@@ -9,11 +9,11 @@
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
   #define CFLAGS "compiler: cl  /MD /Ox /O2 /Ob2 -DOPENSSL_THREADS  -DDSO_WIN32  -DOPENSSL_USE_APPLINK -I. -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_STATIC_ENGINE    "
   #define PLATFORM "VC-WIN32"
-  #define DATE "Mon Jul 20 10:57:37 2015"
+  #define DATE "Mon Jul 20 11:12:05 2015"
 #endif
 #ifdef MK1MF_PLATFORM_BC_NT
   /* auto-generated/updated by util/mk1mf.pl for crypto/cversion.c */
-  #define CFLAGS "compiler: bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -D_timeb=timeb -D_ftime=ftime -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_DYNAMIC_ENGINE    "
+  #define CFLAGS "compiler: bcc32 -DWIN32_LEAN_AND_MEAN -q -w-ccc -w-rch -w-pia -w-aus -w-par -w-inl  -c -tWC -tWM -DOPENSSL_SYSNAME_WIN32 -DL_ENDIAN -DDSO_WIN32 -D_stricmp=stricmp -D_strnicmp=strnicmp -O2 -ff -fp -DBN_ASM -DMD5_ASM -DSHA1_ASM -DRMD160_ASM -DOPENSSL_NO_RC5 -DOPENSSL_NO_MD2 -DOPENSSL_NO_KRB5 -DOPENSSL_NO_JPAKE -DOPENSSL_NO_DYNAMIC_ENGINE    "
   #define PLATFORM "BC-NT"
-  #define DATE "Mon Jul 20 10:57:37 2015"
+  #define DATE "Mon Jul 20 11:12:05 2015"
 #endif

+ 2 - 0
libs/openssl/crypto/cast/cast_lcl.h

@@ -152,6 +152,8 @@
 
 #if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)
 # define ROTL(a,n)     (_lrotl(a,n))
+#elif defined(PEDANTIC)
+# define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>((32-(n))&31)))
 #else
 # define ROTL(a,n)     ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n))))
 #endif

+ 555 - 0
libs/openssl/crypto/cms/cms.h

@@ -0,0 +1,555 @@
+/* crypto/cms/cms.h */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMS_H
+# define HEADER_CMS_H
+
+# include <openssl/x509.h>
+
+# ifdef OPENSSL_NO_CMS
+#  error CMS is disabled.
+# endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct CMS_ContentInfo_st CMS_ContentInfo;
+typedef struct CMS_SignerInfo_st CMS_SignerInfo;
+typedef struct CMS_CertificateChoices CMS_CertificateChoices;
+typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice;
+typedef struct CMS_RecipientInfo_st CMS_RecipientInfo;
+typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest;
+typedef struct CMS_Receipt_st CMS_Receipt;
+typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey;
+typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute;
+
+DECLARE_STACK_OF(CMS_SignerInfo)
+DECLARE_STACK_OF(GENERAL_NAMES)
+DECLARE_STACK_OF(CMS_RecipientEncryptedKey)
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest)
+DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_NONE              -1
+# define CMS_RECIPINFO_TRANS             0
+# define CMS_RECIPINFO_AGREE             1
+# define CMS_RECIPINFO_KEK               2
+# define CMS_RECIPINFO_PASS              3
+# define CMS_RECIPINFO_OTHER             4
+
+/* S/MIME related flags */
+
+# define CMS_TEXT                        0x1
+# define CMS_NOCERTS                     0x2
+# define CMS_NO_CONTENT_VERIFY           0x4
+# define CMS_NO_ATTR_VERIFY              0x8
+# define CMS_NOSIGS                      \
+                        (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY)
+# define CMS_NOINTERN                    0x10
+# define CMS_NO_SIGNER_CERT_VERIFY       0x20
+# define CMS_NOVERIFY                    0x20
+# define CMS_DETACHED                    0x40
+# define CMS_BINARY                      0x80
+# define CMS_NOATTR                      0x100
+# define CMS_NOSMIMECAP                  0x200
+# define CMS_NOOLDMIMETYPE               0x400
+# define CMS_CRLFEOL                     0x800
+# define CMS_STREAM                      0x1000
+# define CMS_NOCRL                       0x2000
+# define CMS_PARTIAL                     0x4000
+# define CMS_REUSE_DIGEST                0x8000
+# define CMS_USE_KEYID                   0x10000
+# define CMS_DEBUG_DECRYPT               0x20000
+# define CMS_KEY_PARAM                   0x40000
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms);
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont);
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio);
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms);
+int CMS_is_detached(CMS_ContentInfo *cms);
+int CMS_set_detached(CMS_ContentInfo *cms, int detached);
+
+# ifdef HEADER_PEM_H
+DECLARE_PEM_rw_const(CMS, CMS_ContentInfo)
+# endif
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms);
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms);
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms);
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms);
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags);
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags);
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont);
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags);
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont,
+              unsigned int flags);
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags);
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags);
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags);
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags);
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags);
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags);
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags);
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags);
+
+int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph,
+                               const unsigned char *key, size_t keylen);
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags);
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in,
+                             const EVP_CIPHER *cipher, unsigned int flags);
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags);
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert);
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         unsigned char *id, size_t idlen);
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen);
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms);
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri);
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri);
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher);
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags);
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey);
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert);
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg);
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno);
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType);
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype);
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen);
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen);
+
+int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri,
+                                    unsigned char *pass,
+                                    ossl_ssize_t passlen);
+
+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);
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri);
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags);
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags);
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid);
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms);
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms);
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert);
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert);
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms);
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms);
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl);
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms);
+
+int CMS_SignedData_init(CMS_ContentInfo *cms);
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags);
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si);
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si);
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms);
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer);
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert);
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+                           unsigned int flags);
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig);
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si);
+int CMS_SignerInfo_sign(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify(CMS_SignerInfo *si);
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain);
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs);
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize);
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap);
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si);
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                               int lastpos);
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                               int lastpos);
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type,
+                                const void *bytes, int len);
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len);
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                  int lastpos, int type);
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si);
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos);
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                                 int lastpos);
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc);
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc);
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr);
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len);
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len);
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type);
+
+# ifdef HEADER_X509V3_H
+
+int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
+CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
+                                               int allorfirst,
+                                               STACK_OF(GENERAL_NAMES)
+                                               *receiptList, STACK_OF(GENERAL_NAMES)
+                                               *receiptsTo);
+int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr);
+void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
+                                    ASN1_STRING **pcid,
+                                    int *pallorfirst,
+                                    STACK_OF(GENERAL_NAMES) **plist,
+                                    STACK_OF(GENERAL_NAMES) **prto);
+# endif
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm);
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri);
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert);
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno);
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert);
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk);
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri);
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek);
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen);
+
+/* 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_CMS_strings(void);
+
+/* Error codes for the CMS functions. */
+
+/* Function codes. */
+# define CMS_F_CHECK_CONTENT                              99
+# define CMS_F_CMS_ADD0_CERT                              164
+# define CMS_F_CMS_ADD0_RECIPIENT_KEY                     100
+# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD                165
+# define CMS_F_CMS_ADD1_RECEIPTREQUEST                    158
+# define CMS_F_CMS_ADD1_RECIPIENT_CERT                    101
+# define CMS_F_CMS_ADD1_SIGNER                            102
+# define CMS_F_CMS_ADD1_SIGNINGTIME                       103
+# define CMS_F_CMS_COMPRESS                               104
+# define CMS_F_CMS_COMPRESSEDDATA_CREATE                  105
+# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO                106
+# define CMS_F_CMS_COPY_CONTENT                           107
+# define CMS_F_CMS_COPY_MESSAGEDIGEST                     108
+# define CMS_F_CMS_DATA                                   109
+# define CMS_F_CMS_DATAFINAL                              110
+# define CMS_F_CMS_DATAINIT                               111
+# define CMS_F_CMS_DECRYPT                                112
+# define CMS_F_CMS_DECRYPT_SET1_KEY                       113
+# define CMS_F_CMS_DECRYPT_SET1_PASSWORD                  166
+# define CMS_F_CMS_DECRYPT_SET1_PKEY                      114
+# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX               115
+# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO               116
+# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL                  117
+# define CMS_F_CMS_DIGEST_VERIFY                          118
+# define CMS_F_CMS_ENCODE_RECEIPT                         161
+# define CMS_F_CMS_ENCRYPT                                119
+# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO              120
+# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT                  121
+# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT                  122
+# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY                 123
+# define CMS_F_CMS_ENVELOPEDDATA_CREATE                   124
+# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO                 125
+# define CMS_F_CMS_ENVELOPED_DATA_INIT                    126
+# define CMS_F_CMS_ENV_ASN1_CTRL                          171
+# define CMS_F_CMS_FINAL                                  127
+# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES               128
+# define CMS_F_CMS_GET0_CONTENT                           129
+# define CMS_F_CMS_GET0_ECONTENT_TYPE                     130
+# define CMS_F_CMS_GET0_ENVELOPED                         131
+# define CMS_F_CMS_GET0_REVOCATION_CHOICES                132
+# define CMS_F_CMS_GET0_SIGNED                            133
+# define CMS_F_CMS_MSGSIGDIGEST_ADD1                      162
+# define CMS_F_CMS_RECEIPTREQUEST_CREATE0                 159
+# define CMS_F_CMS_RECEIPT_VERIFY                         160
+# define CMS_F_CMS_RECIPIENTINFO_DECRYPT                  134
+# define CMS_F_CMS_RECIPIENTINFO_ENCRYPT                  169
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT             178
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG            175
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID        173
+# define CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS           172
+# define CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP         174
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT            135
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT            136
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID            137
+# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP             138
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP            139
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT             140
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT             141
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS           142
+# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID      143
+# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT               167
+# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY                 144
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD            168
+# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY                145
+# define CMS_F_CMS_SD_ASN1_CTRL                           170
+# define CMS_F_CMS_SET1_IAS                               176
+# define CMS_F_CMS_SET1_KEYID                             177
+# define CMS_F_CMS_SET1_SIGNERIDENTIFIER                  146
+# define CMS_F_CMS_SET_DETACHED                           147
+# define CMS_F_CMS_SIGN                                   148
+# define CMS_F_CMS_SIGNED_DATA_INIT                       149
+# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN                150
+# define CMS_F_CMS_SIGNERINFO_SIGN                        151
+# define CMS_F_CMS_SIGNERINFO_VERIFY                      152
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT                 153
+# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT              154
+# define CMS_F_CMS_SIGN_RECEIPT                           163
+# define CMS_F_CMS_STREAM                                 155
+# define CMS_F_CMS_UNCOMPRESS                             156
+# define CMS_F_CMS_VERIFY                                 157
+
+/* Reason codes. */
+# define CMS_R_ADD_SIGNER_ERROR                           99
+# define CMS_R_CERTIFICATE_ALREADY_PRESENT                175
+# define CMS_R_CERTIFICATE_HAS_NO_KEYID                   160
+# define CMS_R_CERTIFICATE_VERIFY_ERROR                   100
+# define CMS_R_CIPHER_INITIALISATION_ERROR                101
+# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR      102
+# define CMS_R_CMS_DATAFINAL_ERROR                        103
+# define CMS_R_CMS_LIB                                    104
+# define CMS_R_CONTENTIDENTIFIER_MISMATCH                 170
+# define CMS_R_CONTENT_NOT_FOUND                          105
+# define CMS_R_CONTENT_TYPE_MISMATCH                      171
+# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA           106
+# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA            107
+# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA               108
+# define CMS_R_CONTENT_VERIFY_ERROR                       109
+# define CMS_R_CTRL_ERROR                                 110
+# define CMS_R_CTRL_FAILURE                               111
+# define CMS_R_DECRYPT_ERROR                              112
+# define CMS_R_DIGEST_ERROR                               161
+# define CMS_R_ERROR_GETTING_PUBLIC_KEY                   113
+# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE      114
+# define CMS_R_ERROR_SETTING_KEY                          115
+# define CMS_R_ERROR_SETTING_RECIPIENTINFO                116
+# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH               117
+# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER           176
+# define CMS_R_INVALID_KEY_LENGTH                         118
+# define CMS_R_MD_BIO_INIT_ERROR                          119
+# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH       120
+# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH                 121
+# define CMS_R_MSGSIGDIGEST_ERROR                         172
+# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE          162
+# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH                  163
+# define CMS_R_NEED_ONE_SIGNER                            164
+# define CMS_R_NOT_A_SIGNED_RECEIPT                       165
+# define CMS_R_NOT_ENCRYPTED_DATA                         122
+# define CMS_R_NOT_KEK                                    123
+# define CMS_R_NOT_KEY_AGREEMENT                          181
+# define CMS_R_NOT_KEY_TRANSPORT                          124
+# define CMS_R_NOT_PWRI                                   177
+# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE            125
+# define CMS_R_NO_CIPHER                                  126
+# define CMS_R_NO_CONTENT                                 127
+# define CMS_R_NO_CONTENT_TYPE                            173
+# define CMS_R_NO_DEFAULT_DIGEST                          128
+# define CMS_R_NO_DIGEST_SET                              129
+# define CMS_R_NO_KEY                                     130
+# define CMS_R_NO_KEY_OR_CERT                             174
+# define CMS_R_NO_MATCHING_DIGEST                         131
+# define CMS_R_NO_MATCHING_RECIPIENT                      132
+# define CMS_R_NO_MATCHING_SIGNATURE                      166
+# define CMS_R_NO_MSGSIGDIGEST                            167
+# define CMS_R_NO_PASSWORD                                178
+# define CMS_R_NO_PRIVATE_KEY                             133
+# define CMS_R_NO_PUBLIC_KEY                              134
+# define CMS_R_NO_RECEIPT_REQUEST                         168
+# define CMS_R_NO_SIGNERS                                 135
+# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE     136
+# define CMS_R_RECEIPT_DECODE_ERROR                       169
+# define CMS_R_RECIPIENT_ERROR                            137
+# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND               138
+# define CMS_R_SIGNFINAL_ERROR                            139
+# define CMS_R_SMIME_TEXT_ERROR                           140
+# define CMS_R_STORE_INIT_ERROR                           141
+# define CMS_R_TYPE_NOT_COMPRESSED_DATA                   142
+# define CMS_R_TYPE_NOT_DATA                              143
+# define CMS_R_TYPE_NOT_DIGESTED_DATA                     144
+# define CMS_R_TYPE_NOT_ENCRYPTED_DATA                    145
+# define CMS_R_TYPE_NOT_ENVELOPED_DATA                    146
+# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT                 147
+# define CMS_R_UNKNOWN_CIPHER                             148
+# define CMS_R_UNKNOWN_DIGEST_ALGORIHM                    149
+# define CMS_R_UNKNOWN_ID                                 150
+# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM          151
+# define CMS_R_UNSUPPORTED_CONTENT_TYPE                   152
+# define CMS_R_UNSUPPORTED_KEK_ALGORITHM                  153
+# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM       179
+# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE                 154
+# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE              155
+# define CMS_R_UNSUPPORTED_TYPE                           156
+# define CMS_R_UNWRAP_ERROR                               157
+# define CMS_R_UNWRAP_FAILURE                             180
+# define CMS_R_VERIFICATION_FAILURE                       158
+# define CMS_R_WRAP_ERROR                                 159
+
+#ifdef  __cplusplus
+}
+#endif
+#endif

+ 459 - 0
libs/openssl/crypto/cms/cms_asn1.c

@@ -0,0 +1,459 @@
+/* crypto/cms/cms_asn1.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+
+ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = {
+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME),
+        ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER)
+} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber)
+
+ASN1_SEQUENCE(CMS_OtherCertificateFormat) = {
+        ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat)
+
+ASN1_CHOICE(CMS_CertificateChoices) = {
+        ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509),
+        ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0),
+        ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1),
+        ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2),
+        ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3)
+} ASN1_CHOICE_END(CMS_CertificateChoices)
+
+ASN1_CHOICE(CMS_SignerIdentifier) = {
+        ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+        ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0)
+} ASN1_CHOICE_END(CMS_SignerIdentifier)
+
+ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = {
+        ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT),
+        ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo)
+
+/* Minor tweak to operation: free up signer key, cert */
+static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_POST) {
+        CMS_SignerInfo *si = (CMS_SignerInfo *)*pval;
+        if (si->pkey)
+            EVP_PKEY_free(si->pkey);
+        if (si->signer)
+            X509_free(si->signer);
+        if (si->pctx)
+            EVP_MD_CTX_cleanup(&si->mctx);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = {
+        ASN1_SIMPLE(CMS_SignerInfo, version, LONG),
+        ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier),
+        ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR),
+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0),
+        ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo)
+
+ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = {
+        ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat)
+
+ASN1_CHOICE(CMS_RevocationInfoChoice) = {
+        ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL),
+        ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1)
+} ASN1_CHOICE_END(CMS_RevocationInfoChoice)
+
+ASN1_NDEF_SEQUENCE(CMS_SignedData) = {
+        ASN1_SIMPLE(CMS_SignedData, version, LONG),
+        ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR),
+        ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0),
+        ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1),
+        ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo)
+} ASN1_NDEF_SEQUENCE_END(CMS_SignedData)
+
+ASN1_SEQUENCE(CMS_OriginatorInfo) = {
+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0),
+        ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1)
+} ASN1_SEQUENCE_END(CMS_OriginatorInfo)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = {
+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT),
+        ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR),
+        ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo)
+
+ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = {
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherKeyAttribute) = {
+        ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT),
+        ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute)
+
+ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = {
+        ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING),
+        ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME),
+        ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier)
+
+ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = {
+  ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0)
+} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier)
+
+static int cms_rek_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                      void *exarg)
+{
+    CMS_RecipientEncryptedKey *rek = (CMS_RecipientEncryptedKey *)*pval;
+    if (operation == ASN1_OP_FREE_POST) {
+        if (rek->pkey)
+            EVP_PKEY_free(rek->pkey);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_RecipientEncryptedKey, cms_rek_cb) = {
+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier),
+        ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END_cb(CMS_RecipientEncryptedKey, CMS_RecipientEncryptedKey)
+
+ASN1_SEQUENCE(CMS_OriginatorPublicKey) = {
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR),
+  ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING)
+} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey)
+
+ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = {
+  ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0),
+  ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1)
+} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey)
+
+static int cms_kari_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                       void *exarg)
+{
+    CMS_KeyAgreeRecipientInfo *kari = (CMS_KeyAgreeRecipientInfo *)*pval;
+    if (operation == ASN1_OP_NEW_POST) {
+        EVP_CIPHER_CTX_init(&kari->ctx);
+        EVP_CIPHER_CTX_set_flags(&kari->ctx, EVP_CIPHER_CTX_FLAG_WRAP_ALLOW);
+        kari->pctx = NULL;
+    } else if (operation == ASN1_OP_FREE_POST) {
+        if (kari->pctx)
+            EVP_PKEY_CTX_free(kari->pctx);
+        EVP_CIPHER_CTX_cleanup(&kari->ctx);
+    }
+    return 1;
+}
+
+ASN1_SEQUENCE_cb(CMS_KeyAgreeRecipientInfo, cms_kari_cb) = {
+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG),
+        ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0),
+        ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1),
+        ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey)
+} ASN1_SEQUENCE_END_cb(CMS_KeyAgreeRecipientInfo, CMS_KeyAgreeRecipientInfo)
+
+ASN1_SEQUENCE(CMS_KEKIdentifier) = {
+        ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING),
+        ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME),
+        ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute)
+} ASN1_SEQUENCE_END(CMS_KEKIdentifier)
+
+ASN1_SEQUENCE(CMS_KEKRecipientInfo) = {
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo)
+
+ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = {
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG),
+        ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0),
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo)
+
+ASN1_SEQUENCE(CMS_OtherRecipientInfo) = {
+  ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT),
+  ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY)
+} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo)
+
+/* Free up RecipientInfo additional data */
+static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                     void *exarg)
+{
+    if (operation == ASN1_OP_FREE_PRE) {
+        CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval;
+        if (ri->type == CMS_RECIPINFO_TRANS) {
+            CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+            if (ktri->pkey)
+                EVP_PKEY_free(ktri->pkey);
+            if (ktri->recip)
+                X509_free(ktri->recip);
+            if (ktri->pctx)
+                EVP_PKEY_CTX_free(ktri->pctx);
+        } else if (ri->type == CMS_RECIPINFO_KEK) {
+            CMS_KEKRecipientInfo *kekri = ri->d.kekri;
+            if (kekri->key) {
+                OPENSSL_cleanse(kekri->key, kekri->keylen);
+                OPENSSL_free(kekri->key);
+            }
+        } else if (ri->type == CMS_RECIPINFO_PASS) {
+            CMS_PasswordRecipientInfo *pwri = ri->d.pwri;
+            if (pwri->pass) {
+                OPENSSL_cleanse(pwri->pass, pwri->passlen);
+                OPENSSL_free(pwri->pass);
+            }
+        }
+    }
+    return 1;
+}
+
+ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = {
+        ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo),
+        ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1),
+        ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2),
+        ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3),
+        ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4)
+} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type)
+
+ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = {
+        ASN1_SIMPLE(CMS_EnvelopedData, version, LONG),
+        ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0),
+        ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo),
+        ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData)
+
+ASN1_NDEF_SEQUENCE(CMS_DigestedData) = {
+        ASN1_SIMPLE(CMS_DigestedData, version, LONG),
+        ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING)
+} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData)
+
+ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = {
+        ASN1_SIMPLE(CMS_EncryptedData, version, LONG),
+        ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1)
+} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData)
+
+ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = {
+        ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG),
+        ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0),
+        ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo),
+        ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR),
+        ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1),
+        ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2),
+        ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING),
+        ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3)
+} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData)
+
+ASN1_NDEF_SEQUENCE(CMS_CompressedData) = {
+        ASN1_SIMPLE(CMS_CompressedData, version, LONG),
+        ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR),
+        ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo),
+} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData)
+
+/* This is the ANY DEFINED BY table for the top level ContentInfo structure */
+
+ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0);
+
+ASN1_ADB(CMS_ContentInfo) = {
+        ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)),
+        ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)),
+        ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)),
+        ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)),
+        ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)),
+        ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)),
+        ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)),
+} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL);
+
+/* CMS streaming support */
+static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
+                  void *exarg)
+{
+    ASN1_STREAM_ARG *sarg = exarg;
+    CMS_ContentInfo *cms = NULL;
+    if (pval)
+        cms = (CMS_ContentInfo *)*pval;
+    else
+        return 1;
+    switch (operation) {
+
+    case ASN1_OP_STREAM_PRE:
+        if (CMS_stream(&sarg->boundary, cms) <= 0)
+            return 0;
+    case ASN1_OP_DETACHED_PRE:
+        sarg->ndef_bio = CMS_dataInit(cms, sarg->out);
+        if (!sarg->ndef_bio)
+            return 0;
+        break;
+
+    case ASN1_OP_STREAM_POST:
+    case ASN1_OP_DETACHED_POST:
+        if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0)
+            return 0;
+        break;
+
+    }
+    return 1;
+}
+
+ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = {
+        ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT),
+        ASN1_ADB_OBJECT(CMS_ContentInfo)
+} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo)
+
+/* Specials for signed attributes */
+
+/*
+ * When signing attributes we want to reorder them to match the sorted
+ * encoding.
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign)
+
+/*
+ * When verifying attributes we need to use the received order. So we use
+ * SEQUENCE OF and tag it to SET OF
+ */
+
+ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) =
+        ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
+                                V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE)
+ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify)
+
+
+
+ASN1_CHOICE(CMS_ReceiptsFrom) = {
+  ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0),
+  ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1)
+} ASN1_CHOICE_END(CMS_ReceiptsFrom)
+
+ASN1_SEQUENCE(CMS_ReceiptRequest) = {
+  ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom),
+  ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES)
+} ASN1_SEQUENCE_END(CMS_ReceiptRequest)
+
+ASN1_SEQUENCE(CMS_Receipt) = {
+  ASN1_SIMPLE(CMS_Receipt, version, LONG),
+  ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT),
+  ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING),
+  ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING)
+} ASN1_SEQUENCE_END(CMS_Receipt)
+
+/*
+ * Utilities to encode the CMS_SharedInfo structure used during key
+ * derivation.
+ */
+
+typedef struct {
+    X509_ALGOR *keyInfo;
+    ASN1_OCTET_STRING *entityUInfo;
+    ASN1_OCTET_STRING *suppPubInfo;
+} CMS_SharedInfo;
+
+ASN1_SEQUENCE(CMS_SharedInfo) = {
+  ASN1_SIMPLE(CMS_SharedInfo, keyInfo, X509_ALGOR),
+  ASN1_EXP_OPT(CMS_SharedInfo, entityUInfo, ASN1_OCTET_STRING, 0),
+  ASN1_EXP_OPT(CMS_SharedInfo, suppPubInfo, ASN1_OCTET_STRING, 2),
+} ASN1_SEQUENCE_END(CMS_SharedInfo)
+
+int CMS_SharedInfo_encode(unsigned char **pder, X509_ALGOR *kekalg,
+                          ASN1_OCTET_STRING *ukm, int keylen)
+{
+    union {
+        CMS_SharedInfo *pecsi;
+        ASN1_VALUE *a;
+    } intsi = {
+        NULL
+    };
+
+    ASN1_OCTET_STRING oklen;
+    unsigned char kl[4];
+    CMS_SharedInfo ecsi;
+
+    keylen <<= 3;
+    kl[0] = (keylen >> 24) & 0xff;
+    kl[1] = (keylen >> 16) & 0xff;
+    kl[2] = (keylen >> 8) & 0xff;
+    kl[3] = keylen & 0xff;
+    oklen.length = 4;
+    oklen.data = kl;
+    oklen.type = V_ASN1_OCTET_STRING;
+    oklen.flags = 0;
+    ecsi.keyInfo = kekalg;
+    ecsi.entityUInfo = ukm;
+    ecsi.suppPubInfo = &oklen;
+    intsi.pecsi = &ecsi;
+    return ASN1_item_i2d(intsi.a, pder, ASN1_ITEM_rptr(CMS_SharedInfo));
+}

+ 197 - 0
libs/openssl/crypto/cms/cms_att.c

@@ -0,0 +1,197 @@
+/* crypto/cms/cms_att.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 <openssl/asn1t.h>
+#include <openssl/pem.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+/* CMS SignedData Attribute utilities */
+
+int CMS_signed_get_attr_count(const CMS_SignerInfo *si)
+{
+    return X509at_get_attr_count(si->signedAttrs);
+}
+
+int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos)
+{
+    return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos);
+}
+
+int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                               int lastpos)
+{
+    return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc)
+{
+    return X509at_get_attr(si->signedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc)
+{
+    return X509at_delete_attr(si->signedAttrs, loc);
+}
+
+int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&si->signedAttrs, attr))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                const ASN1_OBJECT *obj, int type,
+                                const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si,
+                                int nid, int type, const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si,
+                                const char *attrname, int type,
+                                const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                  int lastpos, int type)
+{
+    return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type);
+}
+
+int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si)
+{
+    return X509at_get_attr_count(si->unsignedAttrs);
+}
+
+int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid,
+                                 int lastpos)
+{
+    return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos);
+}
+
+int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj,
+                                 int lastpos)
+{
+    return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc)
+{
+    return X509at_get_attr(si->unsignedAttrs, loc);
+}
+
+X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc)
+{
+    return X509at_delete_attr(si->unsignedAttrs, loc);
+}
+
+int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr)
+{
+    if (X509at_add1_attr(&si->unsignedAttrs, attr))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si,
+                                  const ASN1_OBJECT *obj, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si,
+                                  int nid, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len))
+        return 1;
+    return 0;
+}
+
+int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
+                                  const char *attrname, int type,
+                                  const void *bytes, int len)
+{
+    if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname,
+                                type, bytes, len))
+        return 1;
+    return 0;
+}
+
+void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
+                                    int lastpos, int type)
+{
+    return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type);
+}
+
+/* Specific attribute cases */

+ 134 - 0
libs/openssl/crypto/cms/cms_cd.c

@@ -0,0 +1,134 @@
+/* crypto/cms/cms_cd.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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/bio.h>
+#ifndef OPENSSL_NO_COMP
+# include <openssl/comp.h>
+#endif
+#include "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_CompressedData)
+
+#ifdef ZLIB
+
+/* CMS CompressedData Utilities */
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid)
+{
+    CMS_ContentInfo *cms;
+    CMS_CompressedData *cd;
+    /*
+     * Will need something cleverer if there is ever more than one
+     * compression algorithm or parameters have some meaning...
+     */
+    if (comp_nid != NID_zlib_compression) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE,
+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        return NULL;
+    }
+    cms = CMS_ContentInfo_new();
+    if (!cms)
+        return NULL;
+
+    cd = M_ASN1_new_of(CMS_CompressedData);
+
+    if (!cd)
+        goto err;
+
+    cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData);
+    cms->d.compressedData = cd;
+
+    cd->version = 0;
+
+    X509_ALGOR_set0(cd->compressionAlgorithm,
+                    OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL);
+
+    cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+    return cms;
+
+ err:
+
+    if (cms)
+        CMS_ContentInfo_free(cms);
+
+    return NULL;
+}
+
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_CompressedData *cd;
+    ASN1_OBJECT *compoid;
+    if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+               CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA);
+        return NULL;
+    }
+    cd = cms->d.compressedData;
+    X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm);
+    if (OBJ_obj2nid(compoid) != NID_zlib_compression) {
+        CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO,
+               CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+        return NULL;
+    }
+    return BIO_new(BIO_f_zlib());
+}
+
+#endif

+ 145 - 0
libs/openssl/crypto/cms/cms_dd.c

@@ -0,0 +1,145 @@
+/* crypto/cms/cms_dd.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 "cms_lcl.h"
+
+DECLARE_ASN1_ITEM(CMS_DigestedData)
+
+/* CMS DigestedData Utilities */
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md)
+{
+    CMS_ContentInfo *cms;
+    CMS_DigestedData *dd;
+    cms = CMS_ContentInfo_new();
+    if (!cms)
+        return NULL;
+
+    dd = M_ASN1_new_of(CMS_DigestedData);
+
+    if (!dd)
+        goto err;
+
+    cms->contentType = OBJ_nid2obj(NID_pkcs7_digest);
+    cms->d.digestedData = dd;
+
+    dd->version = 0;
+    dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data);
+
+    cms_DigestAlgorithm_set(dd->digestAlgorithm, md);
+
+    return cms;
+
+ err:
+
+    if (cms)
+        CMS_ContentInfo_free(cms);
+
+    return NULL;
+}
+
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_DigestedData *dd;
+    dd = cms->d.digestedData;
+    return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm);
+}
+
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify)
+{
+    EVP_MD_CTX mctx;
+    unsigned char md[EVP_MAX_MD_SIZE];
+    unsigned int mdlen;
+    int r = 0;
+    CMS_DigestedData *dd;
+    EVP_MD_CTX_init(&mctx);
+
+    dd = cms->d.digestedData;
+
+    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm))
+        goto err;
+
+    if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0)
+        goto err;
+
+    if (verify) {
+        if (mdlen != (unsigned int)dd->digest->length) {
+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+                   CMS_R_MESSAGEDIGEST_WRONG_LENGTH);
+            goto err;
+        }
+
+        if (memcmp(md, dd->digest->data, mdlen))
+            CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL,
+                   CMS_R_VERIFICATION_FAILURE);
+        else
+            r = 1;
+    } else {
+        if (!ASN1_STRING_set(dd->digest, md, mdlen))
+            goto err;
+        r = 1;
+    }
+
+ err:
+    EVP_MD_CTX_cleanup(&mctx);
+
+    return r;
+
+}

+ 260 - 0
libs/openssl/crypto/cms/cms_enc.c

@@ -0,0 +1,260 @@
+/* crypto/cms/cms_enc.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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)
+                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) {
+        calg->parameter = ASN1_TYPE_new();
+        if (!calg->parameter) {
+            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;
+        }
+    }
+    ok = 1;
+
+ err:
+    if (ec->key && !keep_key) {
+        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);
+}

+ 974 - 0
libs/openssl/crypto/cms/cms_env.c

@@ -0,0 +1,974 @@
+/* crypto/cms/cms_env.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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"
+
+/* CMS EnvelopedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_EnvelopedData)
+DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute)
+
+DECLARE_STACK_OF(CMS_RecipientInfo)
+
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms)
+{
+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) {
+        CMSerr(CMS_F_CMS_GET0_ENVELOPED,
+               CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA);
+        return NULL;
+    }
+    return cms->d.envelopedData;
+}
+
+static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms)
+{
+    if (cms->d.other == NULL) {
+        cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData);
+        if (!cms->d.envelopedData) {
+            CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        cms->d.envelopedData->version = 0;
+        cms->d.envelopedData->encryptedContentInfo->contentType =
+            OBJ_nid2obj(NID_pkcs7_data);
+        ASN1_OBJECT_free(cms->contentType);
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped);
+        return cms->d.envelopedData;
+    }
+    return cms_get0_enveloped(cms);
+}
+
+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd)
+{
+    EVP_PKEY *pkey;
+    int i;
+    if (ri->type == CMS_RECIPINFO_TRANS)
+        pkey = ri->d.ktri->pkey;
+    else if (ri->type == CMS_RECIPINFO_AGREE) {
+        EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
+        if (!pctx)
+            return 0;
+        pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+        if (!pkey)
+            return 0;
+    } else
+        return 0;
+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+        return 1;
+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_ENVELOPE, cmd, ri);
+    if (i == -2) {
+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+    if (i <= 0) {
+        CMSerr(CMS_F_CMS_ENV_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms)
+{
+    CMS_EnvelopedData *env;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        return NULL;
+    return env->recipientInfos;
+}
+
+int CMS_RecipientInfo_type(CMS_RecipientInfo *ri)
+{
+    return ri->type;
+}
+
+EVP_PKEY_CTX *CMS_RecipientInfo_get0_pkey_ctx(CMS_RecipientInfo *ri)
+{
+    if (ri->type == CMS_RECIPINFO_TRANS)
+        return ri->d.ktri->pctx;
+    else if (ri->type == CMS_RECIPINFO_AGREE)
+        return ri->d.kari->pctx;
+    return NULL;
+}
+
+CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher)
+{
+    CMS_ContentInfo *cms;
+    CMS_EnvelopedData *env;
+    cms = CMS_ContentInfo_new();
+    if (!cms)
+        goto merr;
+    env = cms_enveloped_data_init(cms);
+    if (!env)
+        goto merr;
+    if (!cms_EncryptedContent_init(env->encryptedContentInfo,
+                                   cipher, NULL, 0))
+        goto merr;
+    return cms;
+ merr:
+    if (cms)
+        CMS_ContentInfo_free(cms);
+    CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE);
+    return NULL;
+}
+
+/* Key Transport Recipient Info (KTRI) routines */
+
+/* Initialise a ktri based on passed certificate and key */
+
+static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
+                                       EVP_PKEY *pk, unsigned int flags)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    int idtype;
+
+    ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo);
+    if (!ri->d.ktri)
+        return 0;
+    ri->type = CMS_RECIPINFO_TRANS;
+
+    ktri = ri->d.ktri;
+
+    if (flags & CMS_USE_KEYID) {
+        ktri->version = 2;
+        idtype = CMS_RECIPINFO_KEYIDENTIFIER;
+    } else {
+        ktri->version = 0;
+        idtype = CMS_RECIPINFO_ISSUER_SERIAL;
+    }
+
+    /*
+     * Not a typo: RecipientIdentifier and SignerIdentifier are the same
+     * structure.
+     */
+
+    if (!cms_set1_SignerIdentifier(ktri->rid, recip, idtype))
+        return 0;
+
+    CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509);
+    CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    ktri->pkey = pk;
+    ktri->recip = recip;
+
+    if (flags & CMS_KEY_PARAM) {
+        ktri->pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL);
+        if (!ktri->pctx)
+            return 0;
+        if (EVP_PKEY_encrypt_init(ktri->pctx) <= 0)
+            return 0;
+    } else if (!cms_env_asn1_ctrl(ri, 0))
+        return 0;
+    return 1;
+}
+
+/*
+ * Add a recipient certificate using appropriate type of RecipientInfo
+ */
+
+CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms,
+                                           X509 *recip, unsigned int flags)
+{
+    CMS_RecipientInfo *ri = NULL;
+    CMS_EnvelopedData *env;
+    EVP_PKEY *pk = NULL;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        goto err;
+
+    /* Initialize recipient info */
+    ri = M_ASN1_new_of(CMS_RecipientInfo);
+    if (!ri)
+        goto merr;
+
+    pk = X509_get_pubkey(recip);
+    if (!pk) {
+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY);
+        goto err;
+    }
+
+    switch (cms_pkey_get_ri_type(pk)) {
+
+    case CMS_RECIPINFO_TRANS:
+        if (!cms_RecipientInfo_ktri_init(ri, recip, pk, flags))
+            goto err;
+        break;
+
+    case CMS_RECIPINFO_AGREE:
+        if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
+            goto err;
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        goto err;
+
+    }
+
+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+        goto merr;
+
+    EVP_PKEY_free(pk);
+
+    return ri;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE);
+ err:
+    if (ri)
+        M_ASN1_free_of(ri, CMS_RecipientInfo);
+    if (pk)
+        EVP_PKEY_free(pk);
+    return NULL;
+
+}
+
+int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri,
+                                     EVP_PKEY **pk, X509 **recip,
+                                     X509_ALGOR **palg)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+
+    ktri = ri->d.ktri;
+
+    if (pk)
+        *pk = ktri->pkey;
+    if (recip)
+        *recip = ktri->recip;
+    if (palg)
+        *palg = ktri->keyEncryptionAlgorithm;
+    return 1;
+}
+
+int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri,
+                                          ASN1_OCTET_STRING **keyid,
+                                          X509_NAME **issuer,
+                                          ASN1_INTEGER **sno)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ktri = ri->d.ktri;
+
+    return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno);
+}
+
+int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert)
+{
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP,
+               CMS_R_NOT_KEY_TRANSPORT);
+        return -2;
+    }
+    return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert);
+}
+
+int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey)
+{
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ri->d.ktri->pkey = pkey;
+    return 1;
+}
+
+/* Encrypt content key in key transport recipient info */
+
+static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms,
+                                          CMS_RecipientInfo *ri)
+{
+    CMS_KeyTransRecipientInfo *ktri;
+    CMS_EncryptedContentInfo *ec;
+    EVP_PKEY_CTX *pctx;
+    unsigned char *ek = NULL;
+    size_t eklen;
+
+    int ret = 0;
+
+    if (ri->type != CMS_RECIPINFO_TRANS) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT);
+        return 0;
+    }
+    ktri = ri->d.ktri;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    pctx = ktri->pctx;
+
+    if (pctx) {
+        if (!cms_env_asn1_ctrl(ri, 0))
+            goto err;
+    } else {
+        pctx = EVP_PKEY_CTX_new(ktri->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_CMS_ENCRYPT, 0, ri) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0)
+        goto err;
+
+    ASN1_STRING_set0(ktri->encryptedKey, ek, eklen);
+    ek = NULL;
+
+    ret = 1;
+
+ err:
+    if (pctx) {
+        EVP_PKEY_CTX_free(pctx);
+        ktri->pctx = NULL;
+    }
+    if (ek)
+        OPENSSL_free(ek);
+    return ret;
+
+}
+
+/* Decrypt content key from KTRI */
+
+static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms,
+                                          CMS_RecipientInfo *ri)
+{
+    CMS_KeyTransRecipientInfo *ktri = ri->d.ktri;
+    EVP_PKEY *pkey = ktri->pkey;
+    unsigned char *ek = NULL;
+    size_t eklen;
+    int ret = 0;
+    CMS_EncryptedContentInfo *ec;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    if (ktri->pkey == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY);
+        return 0;
+    }
+
+    ktri->pctx = EVP_PKEY_CTX_new(pkey, NULL);
+    if (!ktri->pctx)
+        return 0;
+
+    if (EVP_PKEY_decrypt_init(ktri->pctx) <= 0)
+        goto err;
+
+    if (!cms_env_asn1_ctrl(ri, 1))
+        goto err;
+
+    if (EVP_PKEY_CTX_ctrl(ktri->pctx, -1, EVP_PKEY_OP_DECRYPT,
+                          EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(ktri->pctx, NULL, &eklen,
+                         ktri->encryptedKey->data,
+                         ktri->encryptedKey->length) <= 0)
+        goto err;
+
+    ek = OPENSSL_malloc(eklen);
+
+    if (ek == NULL) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    if (EVP_PKEY_decrypt(ktri->pctx, ek, &eklen,
+                         ktri->encryptedKey->data,
+                         ktri->encryptedKey->length) <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB);
+        goto err;
+    }
+
+    ret = 1;
+
+    if (ec->key) {
+        OPENSSL_cleanse(ec->key, ec->keylen);
+        OPENSSL_free(ec->key);
+    }
+
+    ec->key = ek;
+    ec->keylen = eklen;
+
+ err:
+    if (ktri->pctx) {
+        EVP_PKEY_CTX_free(ktri->pctx);
+        ktri->pctx = NULL;
+    }
+    if (!ret && ek)
+        OPENSSL_free(ek);
+
+    return ret;
+}
+
+/* Key Encrypted Key (KEK) RecipientInfo routines */
+
+int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri,
+                                   const unsigned char *id, size_t idlen)
+{
+    ASN1_OCTET_STRING tmp_os;
+    CMS_KEKRecipientInfo *kekri;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK);
+        return -2;
+    }
+    kekri = ri->d.kekri;
+    tmp_os.type = V_ASN1_OCTET_STRING;
+    tmp_os.flags = 0;
+    tmp_os.data = (unsigned char *)id;
+    tmp_os.length = (int)idlen;
+    return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier);
+}
+
+/* For now hard code AES key wrap info */
+
+static size_t aes_wrap_keylen(int nid)
+{
+    switch (nid) {
+    case NID_id_aes128_wrap:
+        return 16;
+
+    case NID_id_aes192_wrap:
+        return 24;
+
+    case NID_id_aes256_wrap:
+        return 32;
+
+    default:
+        return 0;
+    }
+}
+
+CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid,
+                                          unsigned char *key, size_t keylen,
+                                          unsigned char *id, size_t idlen,
+                                          ASN1_GENERALIZEDTIME *date,
+                                          ASN1_OBJECT *otherTypeId,
+                                          ASN1_TYPE *otherType)
+{
+    CMS_RecipientInfo *ri = NULL;
+    CMS_EnvelopedData *env;
+    CMS_KEKRecipientInfo *kekri;
+    env = cms_get0_enveloped(cms);
+    if (!env)
+        goto err;
+
+    if (nid == NID_undef) {
+        switch (keylen) {
+        case 16:
+            nid = NID_id_aes128_wrap;
+            break;
+
+        case 24:
+            nid = NID_id_aes192_wrap;
+            break;
+
+        case 32:
+            nid = NID_id_aes256_wrap;
+            break;
+
+        default:
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
+            goto err;
+        }
+
+    } else {
+
+        size_t exp_keylen = aes_wrap_keylen(nid);
+
+        if (!exp_keylen) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY,
+                   CMS_R_UNSUPPORTED_KEK_ALGORITHM);
+            goto err;
+        }
+
+        if (keylen != exp_keylen) {
+            CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH);
+            goto err;
+        }
+
+    }
+
+    /* Initialize recipient info */
+    ri = M_ASN1_new_of(CMS_RecipientInfo);
+    if (!ri)
+        goto merr;
+
+    ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo);
+    if (!ri->d.kekri)
+        goto merr;
+    ri->type = CMS_RECIPINFO_KEK;
+
+    kekri = ri->d.kekri;
+
+    if (otherTypeId) {
+        kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute);
+        if (kekri->kekid->other == NULL)
+            goto merr;
+    }
+
+    if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri))
+        goto merr;
+
+    /* After this point no calls can fail */
+
+    kekri->version = 4;
+
+    kekri->key = key;
+    kekri->keylen = keylen;
+
+    ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen);
+
+    kekri->kekid->date = date;
+
+    if (kekri->kekid->other) {
+        kekri->kekid->other->keyAttrId = otherTypeId;
+        kekri->kekid->other->keyAttr = otherType;
+    }
+
+    X509_ALGOR_set0(kekri->keyEncryptionAlgorithm,
+                    OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL);
+
+    return ri;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE);
+ err:
+    if (ri)
+        M_ASN1_free_of(ri, CMS_RecipientInfo);
+    return NULL;
+
+}
+
+int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pid,
+                                    ASN1_GENERALIZEDTIME **pdate,
+                                    ASN1_OBJECT **potherid,
+                                    ASN1_TYPE **pothertype)
+{
+    CMS_KEKIdentifier *rkid;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK);
+        return 0;
+    }
+    rkid = ri->d.kekri->kekid;
+    if (palg)
+        *palg = ri->d.kekri->keyEncryptionAlgorithm;
+    if (pid)
+        *pid = rkid->keyIdentifier;
+    if (pdate)
+        *pdate = rkid->date;
+    if (potherid) {
+        if (rkid->other)
+            *potherid = rkid->other->keyAttrId;
+        else
+            *potherid = NULL;
+    }
+    if (pothertype) {
+        if (rkid->other)
+            *pothertype = rkid->other->keyAttr;
+        else
+            *pothertype = NULL;
+    }
+    return 1;
+}
+
+int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri,
+                               unsigned char *key, size_t keylen)
+{
+    CMS_KEKRecipientInfo *kekri;
+    if (ri->type != CMS_RECIPINFO_KEK) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK);
+        return 0;
+    }
+
+    kekri = ri->d.kekri;
+    kekri->key = key;
+    kekri->keylen = keylen;
+    return 1;
+}
+
+/* Encrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms,
+                                           CMS_RecipientInfo *ri)
+{
+    CMS_EncryptedContentInfo *ec;
+    CMS_KEKRecipientInfo *kekri;
+    AES_KEY actx;
+    unsigned char *wkey = NULL;
+    int wkeylen;
+    int r = 0;
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    kekri = ri->d.kekri;
+
+    if (!kekri->key) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY);
+        return 0;
+    }
+
+    if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT,
+               CMS_R_ERROR_SETTING_KEY);
+        goto err;
+    }
+
+    wkey = OPENSSL_malloc(ec->keylen + 8);
+
+    if (!wkey) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen);
+
+    if (wkeylen <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR);
+        goto err;
+    }
+
+    ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen);
+
+    r = 1;
+
+ err:
+
+    if (!r && wkey)
+        OPENSSL_free(wkey);
+    OPENSSL_cleanse(&actx, sizeof(actx));
+
+    return r;
+
+}
+
+/* Decrypt content key in KEK recipient info */
+
+static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms,
+                                           CMS_RecipientInfo *ri)
+{
+    CMS_EncryptedContentInfo *ec;
+    CMS_KEKRecipientInfo *kekri;
+    AES_KEY actx;
+    unsigned char *ukey = NULL;
+    int ukeylen;
+    int r = 0, wrap_nid;
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+
+    kekri = ri->d.kekri;
+
+    if (!kekri->key) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY);
+        return 0;
+    }
+
+    wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm);
+    if (aes_wrap_keylen(wrap_nid) != kekri->keylen) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_INVALID_KEY_LENGTH);
+        return 0;
+    }
+
+    /* If encrypted key length is invalid don't bother */
+
+    if (kekri->encryptedKey->length < 16) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_INVALID_ENCRYPTED_KEY_LENGTH);
+        goto err;
+    }
+
+    if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT,
+               CMS_R_ERROR_SETTING_KEY);
+        goto err;
+    }
+
+    ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8);
+
+    if (!ukey) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    ukeylen = AES_unwrap_key(&actx, NULL, ukey,
+                             kekri->encryptedKey->data,
+                             kekri->encryptedKey->length);
+
+    if (ukeylen <= 0) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR);
+        goto err;
+    }
+
+    ec->key = ukey;
+    ec->keylen = ukeylen;
+
+    r = 1;
+
+ err:
+
+    if (!r && ukey)
+        OPENSSL_free(ukey);
+    OPENSSL_cleanse(&actx, sizeof(actx));
+
+    return r;
+
+}
+
+int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+{
+    switch (ri->type) {
+    case CMS_RECIPINFO_TRANS:
+        return cms_RecipientInfo_ktri_decrypt(cms, ri);
+
+    case CMS_RECIPINFO_KEK:
+        return cms_RecipientInfo_kekri_decrypt(cms, ri);
+
+    case CMS_RECIPINFO_PASS:
+        return cms_RecipientInfo_pwri_crypt(cms, ri, 0);
+
+    default:
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT,
+               CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE);
+        return 0;
+    }
+}
+
+int CMS_RecipientInfo_encrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri)
+{
+    switch (ri->type) {
+    case CMS_RECIPINFO_TRANS:
+        return cms_RecipientInfo_ktri_encrypt(cms, ri);
+
+    case CMS_RECIPINFO_AGREE:
+        return cms_RecipientInfo_kari_encrypt(cms, ri);
+
+    case CMS_RECIPINFO_KEK:
+        return cms_RecipientInfo_kekri_encrypt(cms, ri);
+        break;
+
+    case CMS_RECIPINFO_PASS:
+        return cms_RecipientInfo_pwri_crypt(cms, ri, 1);
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_ENCRYPT,
+               CMS_R_UNSUPPORTED_RECIPIENT_TYPE);
+        return 0;
+    }
+}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_env_set_originfo_version(CMS_EnvelopedData *env)
+{
+    CMS_OriginatorInfo *org = env->originatorInfo;
+    int i;
+    if (org == NULL)
+        return;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(org->certificates); i++) {
+        CMS_CertificateChoices *cch;
+        cch = sk_CMS_CertificateChoices_value(org->certificates, i);
+        if (cch->type == CMS_CERTCHOICE_OTHER) {
+            env->version = 4;
+            return;
+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
+            if (env->version < 3)
+                env->version = 3;
+        }
+    }
+
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(org->crls); i++) {
+        CMS_RevocationInfoChoice *rch;
+        rch = sk_CMS_RevocationInfoChoice_value(org->crls, i);
+        if (rch->type == CMS_REVCHOICE_OTHER) {
+            env->version = 4;
+            return;
+        }
+    }
+}
+
+static void cms_env_set_version(CMS_EnvelopedData *env)
+{
+    int i;
+    CMS_RecipientInfo *ri;
+
+    /*
+     * Can't set version higher than 4 so if 4 or more already nothing to do.
+     */
+    if (env->version >= 4)
+        return;
+
+    cms_env_set_originfo_version(env);
+
+    if (env->version >= 3)
+        return;
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(env->recipientInfos); i++) {
+        ri = sk_CMS_RecipientInfo_value(env->recipientInfos, i);
+        if (ri->type == CMS_RECIPINFO_PASS || ri->type == CMS_RECIPINFO_OTHER) {
+            env->version = 3;
+            return;
+        } else if (ri->type != CMS_RECIPINFO_TRANS
+                   || ri->d.ktri->version != 0) {
+            env->version = 2;
+        }
+    }
+    if (env->version == 2)
+        return;
+    if (env->originatorInfo || env->unprotectedAttrs)
+        env->version = 2;
+    env->version = 0;
+}
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms)
+{
+    CMS_EncryptedContentInfo *ec;
+    STACK_OF(CMS_RecipientInfo) *rinfos;
+    CMS_RecipientInfo *ri;
+    int i, ok = 0;
+    BIO *ret;
+
+    /* Get BIO first to set up key */
+
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    ret = cms_EncryptedContent_init_bio(ec);
+
+    /* If error or no cipher end of processing */
+
+    if (!ret || !ec->cipher)
+        return ret;
+
+    /* Now encrypt content key according to each RecipientInfo type */
+
+    rinfos = cms->d.envelopedData->recipientInfos;
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) {
+        ri = sk_CMS_RecipientInfo_value(rinfos, i);
+        if (CMS_RecipientInfo_encrypt(cms, ri) <= 0) {
+            CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO,
+                   CMS_R_ERROR_SETTING_RECIPIENTINFO);
+            goto err;
+        }
+    }
+    cms_env_set_version(cms->d.envelopedData);
+
+    ok = 1;
+
+ err:
+    ec->cipher = NULL;
+    if (ec->key) {
+        OPENSSL_cleanse(ec->key, ec->keylen);
+        OPENSSL_free(ec->key);
+        ec->key = NULL;
+        ec->keylen = 0;
+    }
+    if (ok)
+        return ret;
+    BIO_free(ret);
+    return NULL;
+
+}
+
+/*
+ * Get RecipientInfo type (if any) supported by a key (public or private). To
+ * retain compatibility with previous behaviour if the ctrl value isn't
+ * supported we assume key transport.
+ */
+int cms_pkey_get_ri_type(EVP_PKEY *pk)
+{
+    if (pk->ameth && pk->ameth->pkey_ctrl) {
+        int i, r;
+        i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_RI_TYPE, 0, &r);
+        if (i > 0)
+            return r;
+    }
+    return CMS_RECIPINFO_TRANS;
+}

+ 309 - 0
libs/openssl/crypto/cms/cms_err.c

@@ -0,0 +1,309 @@
+/* crypto/cms/cms_err.c */
+/* ====================================================================
+ * Copyright (c) 1999-2013 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
+ *    [email protected].
+ *
+ * 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
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+/*
+ * 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/cms.h>
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+
+# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0)
+# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason)
+
+static ERR_STRING_DATA CMS_str_functs[] = {
+    {ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"},
+    {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD),
+     "CMS_add0_recipient_password"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"},
+    {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"},
+    {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO),
+     "cms_CompressedData_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"},
+    {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"},
+    {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"},
+    {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"},
+    {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"},
+    {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX),
+     "cms_DigestAlgorithm_find_ctx"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO),
+     "cms_DigestAlgorithm_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"},
+    {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"},
+    {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO),
+     "cms_EncryptedContent_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY),
+     "CMS_EncryptedData_set1_key"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO),
+     "cms_EnvelopedData_init_bio"},
+    {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"},
+    {ERR_FUNC(CMS_F_CMS_ENV_ASN1_CTRL), "cms_env_asn1_ctrl"},
+    {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"},
+    {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES),
+     "CMS_GET0_CERTIFICATE_CHOICES"},
+    {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"},
+    {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"},
+    {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"},
+    {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES),
+     "CMS_GET0_REVOCATION_CHOICES"},
+    {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"},
+    {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"},
+    {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0),
+     "CMS_ReceiptRequest_create0"},
+    {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_ENCRYPT), "CMS_RecipientInfo_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT),
+     "cms_RecipientInfo_kari_encrypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG),
+     "CMS_RecipientInfo_kari_get0_alg"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID),
+     "CMS_RecipientInfo_kari_get0_orig_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS),
+     "CMS_RecipientInfo_kari_get0_reks"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP),
+     "CMS_RecipientInfo_kari_orig_id_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT),
+     "CMS_RECIPIENTINFO_KEKRI_DECRYPT"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT),
+     "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID),
+     "CMS_RecipientInfo_kekri_get0_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP),
+     "CMS_RecipientInfo_kekri_id_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP),
+     "CMS_RecipientInfo_ktri_cert_cmp"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT),
+     "CMS_RECIPIENTINFO_KTRI_DECRYPT"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT),
+     "CMS_RECIPIENTINFO_KTRI_ENCRYPT"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS),
+     "CMS_RecipientInfo_ktri_get0_algs"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID),
+     "CMS_RecipientInfo_ktri_get0_signer_id"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT),
+     "cms_RecipientInfo_pwri_crypt"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY),
+     "CMS_RecipientInfo_set0_key"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD),
+     "CMS_RecipientInfo_set0_password"},
+    {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY),
+     "CMS_RecipientInfo_set0_pkey"},
+    {ERR_FUNC(CMS_F_CMS_SD_ASN1_CTRL), "CMS_SD_ASN1_CTRL"},
+    {ERR_FUNC(CMS_F_CMS_SET1_IAS), "cms_set1_ias"},
+    {ERR_FUNC(CMS_F_CMS_SET1_KEYID), "cms_set1_keyid"},
+    {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"},
+    {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"},
+    {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"},
+    {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN),
+     "CMS_SIGNERINFO_CONTENT_SIGN"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT),
+     "CMS_SIGNERINFO_VERIFY_CERT"},
+    {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT),
+     "CMS_SignerInfo_verify_content"},
+    {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"},
+    {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"},
+    {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"},
+    {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"},
+    {0, NULL}
+};
+
+static ERR_STRING_DATA CMS_str_reasons[] = {
+    {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"},
+    {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT),
+     "certificate already present"},
+    {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"},
+    {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"},
+    {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR),
+     "cipher initialisation error"},
+    {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR),
+     "cipher parameter initialisation error"},
+    {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"},
+    {ERR_REASON(CMS_R_CMS_LIB), "cms lib"},
+    {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH),
+     "contentidentifier mismatch"},
+    {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA),
+     "content type not compressed data"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA),
+     "content type not enveloped data"},
+    {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA),
+     "content type not signed data"},
+    {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"},
+    {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"},
+    {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"},
+    {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"},
+    {ERR_REASON(CMS_R_DIGEST_ERROR), "digest error"},
+    {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"},
+    {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE),
+     "error reading messagedigest attribute"},
+    {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"},
+    {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO),
+     "error setting recipientinfo"},
+    {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH),
+     "invalid encrypted key length"},
+    {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER),
+     "invalid key encryption parameter"},
+    {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"},
+    {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"},
+    {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH),
+     "messagedigest attribute wrong length"},
+    {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH),
+     "messagedigest wrong length"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE),
+     "msgsigdigest verification failure"},
+    {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH),
+     "msgsigdigest wrong length"},
+    {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"},
+    {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"},
+    {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"},
+    {ERR_REASON(CMS_R_NOT_KEK), "not kek"},
+    {ERR_REASON(CMS_R_NOT_KEY_AGREEMENT), "not key agreement"},
+    {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"},
+    {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"},
+    {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),
+     "not supported for this key type"},
+    {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"},
+    {ERR_REASON(CMS_R_NO_CONTENT), "no content"},
+    {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"},
+    {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"},
+    {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"},
+    {ERR_REASON(CMS_R_NO_KEY), "no key"},
+    {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"},
+    {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"},
+    {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"},
+    {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"},
+    {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"},
+    {ERR_REASON(CMS_R_NO_PASSWORD), "no password"},
+    {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"},
+    {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"},
+    {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"},
+    {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"},
+    {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),
+     "private key does not match certificate"},
+    {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"},
+    {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"},
+    {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND),
+     "signer certificate not found"},
+    {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"},
+    {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"},
+    {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"},
+    {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"},
+    {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"},
+    {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT),
+     "unable to finalize context"},
+    {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"},
+    {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"},
+    {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM),
+     "unsupported compression algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM),
+     "unsupported kek algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM),
+     "unsupported key encryption algorithm"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE),
+     "unsupported recipient type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE),
+     "unsupported recpientinfo type"},
+    {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"},
+    {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"},
+    {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"},
+    {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"},
+    {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"},
+    {0, NULL}
+};
+
+#endif
+
+void ERR_load_CMS_strings(void)
+{
+#ifndef OPENSSL_NO_ERR
+
+    if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) {
+        ERR_load_strings(0, CMS_str_functs);
+        ERR_load_strings(0, CMS_str_reasons);
+    }
+#endif
+}

+ 395 - 0
libs/openssl/crypto/cms/cms_ess.c

@@ -0,0 +1,395 @@
+/* crypto/cms/cms_ess.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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)
+            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;
+
+}

+ 133 - 0
libs/openssl/crypto/cms/cms_io.c

@@ -0,0 +1,133 @@
+/* crypto/cms/cms_io.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 <openssl/asn1t.h>
+#include <openssl/x509.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (!pos)
+        return 0;
+    if (!*pos)
+        *pos = ASN1_OCTET_STRING_new();
+    if (*pos) {
+        (*pos)->flags |= ASN1_STRING_FLAG_NDEF;
+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+        *boundary = &(*pos)->data;
+        return 1;
+    }
+    CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms)
+{
+    return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+}
+
+int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms)
+{
+    return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms);
+}
+
+IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo)
+
+BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms)
+{
+    return BIO_new_NDEF(out, (ASN1_VALUE *)cms,
+                        ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+/* CMS wrappers round generalised stream and MIME routines */
+
+int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags)
+{
+    return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags,
+                               ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in,
+                             int flags)
+{
+    return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags,
+                                     "CMS", ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags)
+{
+    STACK_OF(X509_ALGOR) *mdalgs;
+    int ctype_nid = OBJ_obj2nid(cms->contentType);
+    int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms));
+    if (ctype_nid == NID_pkcs7_signed)
+        mdalgs = cms->d.signedData->digestAlgorithms;
+    else
+        mdalgs = NULL;
+
+    return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags,
+                            ctype_nid, econt_nid, mdalgs,
+                            ASN1_ITEM_rptr(CMS_ContentInfo));
+}
+
+CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont)
+{
+    return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont,
+                                              ASN1_ITEM_rptr
+                                              (CMS_ContentInfo));
+}

+ 465 - 0
libs/openssl/crypto/cms/cms_kari.c

@@ -0,0 +1,465 @@
+/* crypto/cms/cms_kari.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) for the OpenSSL
+ * project.
+ */
+/* ====================================================================
+ * Copyright (c) 2013 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
+ *    [email protected].
+ *
+ * 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"
+
+DECLARE_ASN1_ITEM(CMS_KeyAgreeRecipientInfo)
+DECLARE_ASN1_ITEM(CMS_RecipientEncryptedKey)
+DECLARE_ASN1_ITEM(CMS_OriginatorPublicKey)
+DECLARE_ASN1_ITEM(CMS_RecipientKeyIdentifier)
+
+/* Key Agreement Recipient Info (KARI) routines */
+
+int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
+                                    X509_ALGOR **palg,
+                                    ASN1_OCTET_STRING **pukm)
+{
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ALG,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    if (palg)
+        *palg = ri->d.kari->keyEncryptionAlgorithm;
+    if (pukm)
+        *pukm = ri->d.kari->ukm;
+    return 1;
+}
+
+/* Retrieve recipient encrypted keys from a kari */
+
+STACK_OF(CMS_RecipientEncryptedKey)
+*CMS_RecipientInfo_kari_get0_reks(CMS_RecipientInfo *ri)
+{
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_REKS,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return NULL;
+    }
+    return ri->d.kari->recipientEncryptedKeys;
+}
+
+int CMS_RecipientInfo_kari_get0_orig_id(CMS_RecipientInfo *ri,
+                                        X509_ALGOR **pubalg,
+                                        ASN1_BIT_STRING **pubkey,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno)
+{
+    CMS_OriginatorIdentifierOrKey *oik;
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_GET0_ORIG_ID,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    oik = ri->d.kari->originator;
+    if (issuer)
+        *issuer = NULL;
+    if (sno)
+        *sno = NULL;
+    if (keyid)
+        *keyid = NULL;
+    if (pubalg)
+        *pubalg = NULL;
+    if (pubkey)
+        *pubkey = NULL;
+    if (oik->type == CMS_OIK_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = oik->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = oik->d.issuerAndSerialNumber->serialNumber;
+    } else if (oik->type == CMS_OIK_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = oik->d.subjectKeyIdentifier;
+    } else if (oik->type == CMS_OIK_PUBKEY) {
+        if (pubalg)
+            *pubalg = oik->d.originatorKey->algorithm;
+        if (pubkey)
+            *pubkey = oik->d.originatorKey->publicKey;
+    } else
+        return 0;
+    return 1;
+}
+
+int CMS_RecipientInfo_kari_orig_id_cmp(CMS_RecipientInfo *ri, X509 *cert)
+{
+    CMS_OriginatorIdentifierOrKey *oik;
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ORIG_ID_CMP,
+               CMS_R_NOT_KEY_AGREEMENT);
+        return -2;
+    }
+    oik = ri->d.kari->originator;
+    if (oik->type == CMS_OIK_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(oik->d.issuerAndSerialNumber, cert);
+    else if (oik->type == CMS_OIK_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(oik->d.subjectKeyIdentifier, cert);
+    return -1;
+}
+
+int CMS_RecipientEncryptedKey_get0_id(CMS_RecipientEncryptedKey *rek,
+                                      ASN1_OCTET_STRING **keyid,
+                                      ASN1_GENERALIZEDTIME **tm,
+                                      CMS_OtherKeyAttribute **other,
+                                      X509_NAME **issuer, ASN1_INTEGER **sno)
+{
+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+    if (rid->type == CMS_REK_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = rid->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = rid->d.issuerAndSerialNumber->serialNumber;
+        if (keyid)
+            *keyid = NULL;
+        if (tm)
+            *tm = NULL;
+        if (other)
+            *other = NULL;
+    } else if (rid->type == CMS_REK_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = rid->d.rKeyId->subjectKeyIdentifier;
+        if (tm)
+            *tm = rid->d.rKeyId->date;
+        if (other)
+            *other = rid->d.rKeyId->other;
+        if (issuer)
+            *issuer = NULL;
+        if (sno)
+            *sno = NULL;
+    } else
+        return 0;
+    return 1;
+}
+
+int CMS_RecipientEncryptedKey_cert_cmp(CMS_RecipientEncryptedKey *rek,
+                                       X509 *cert)
+{
+    CMS_KeyAgreeRecipientIdentifier *rid = rek->rid;
+    if (rid->type == CMS_REK_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(rid->d.issuerAndSerialNumber, cert);
+    else if (rid->type == CMS_REK_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(rid->d.rKeyId->subjectKeyIdentifier, cert);
+    else
+        return -1;
+}
+
+int CMS_RecipientInfo_kari_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pk)
+{
+    EVP_PKEY_CTX *pctx;
+    CMS_KeyAgreeRecipientInfo *kari = ri->d.kari;
+    if (kari->pctx) {
+        EVP_PKEY_CTX_free(kari->pctx);
+        kari->pctx = NULL;
+    }
+    if (!pk)
+        return 1;
+    pctx = EVP_PKEY_CTX_new(pk, NULL);
+    if (!pctx || !EVP_PKEY_derive_init(pctx))
+        goto err;
+    kari->pctx = pctx;
+    return 1;
+ err:
+    if (pctx)
+        EVP_PKEY_CTX_free(pctx);
+    return 0;
+}
+
+EVP_CIPHER_CTX *CMS_RecipientInfo_kari_get0_ctx(CMS_RecipientInfo *ri)
+{
+    if (ri->type == CMS_RECIPINFO_AGREE)
+        return &ri->d.kari->ctx;
+    return NULL;
+}
+
+/*
+ * Derive KEK and decrypt/encrypt with it to produce either the original CEK
+ * or the encrypted CEK.
+ */
+
+static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
+                          const unsigned char *in, size_t inlen,
+                          CMS_KeyAgreeRecipientInfo *kari, int enc)
+{
+    /* Key encryption key */
+    unsigned char kek[EVP_MAX_KEY_LENGTH];
+    size_t keklen;
+    int rv = 0;
+    unsigned char *out = NULL;
+    int outlen;
+    keklen = EVP_CIPHER_CTX_key_length(&kari->ctx);
+    if (keklen > EVP_MAX_KEY_LENGTH)
+        return 0;
+    /* Derive KEK */
+    if (EVP_PKEY_derive(kari->pctx, kek, &keklen) <= 0)
+        goto err;
+    /* Set KEK in context */
+    if (!EVP_CipherInit_ex(&kari->ctx, NULL, NULL, kek, NULL, enc))
+        goto err;
+    /* obtain output length of ciphered key */
+    if (!EVP_CipherUpdate(&kari->ctx, NULL, &outlen, in, inlen))
+        goto err;
+    out = OPENSSL_malloc(outlen);
+    if (!out)
+        goto err;
+    if (!EVP_CipherUpdate(&kari->ctx, out, &outlen, in, inlen))
+        goto err;
+    *pout = out;
+    *poutlen = (size_t)outlen;
+    rv = 1;
+
+ err:
+    OPENSSL_cleanse(kek, keklen);
+    if (!rv && out)
+        OPENSSL_free(out);
+    EVP_CIPHER_CTX_cleanup(&kari->ctx);
+    EVP_PKEY_CTX_free(kari->pctx);
+    kari->pctx = NULL;
+    return rv;
+}
+
+int CMS_RecipientInfo_kari_decrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri,
+                                   CMS_RecipientEncryptedKey *rek)
+{
+    int rv = 0;
+    unsigned char *enckey = NULL, *cek = NULL;
+    size_t enckeylen;
+    size_t ceklen;
+    CMS_EncryptedContentInfo *ec;
+    enckeylen = rek->encryptedKey->length;
+    enckey = rek->encryptedKey->data;
+    /* Setup all parameters to derive KEK */
+    if (!cms_env_asn1_ctrl(ri, 1))
+        goto err;
+    /* Attempt to decrypt CEK */
+    if (!cms_kek_cipher(&cek, &ceklen, enckey, enckeylen, ri->d.kari, 0))
+        goto err;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    if (ec->key) {
+        OPENSSL_cleanse(ec->key, ec->keylen);
+        OPENSSL_free(ec->key);
+    }
+    ec->key = cek;
+    ec->keylen = ceklen;
+    cek = NULL;
+    rv = 1;
+ err:
+    if (cek)
+        OPENSSL_free(cek);
+    return rv;
+}
+
+/* Create ephemeral key and initialise context based on it */
+static int cms_kari_create_ephemeral_key(CMS_KeyAgreeRecipientInfo *kari,
+                                         EVP_PKEY *pk)
+{
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_PKEY *ekey = NULL;
+    int rv = 0;
+    pctx = EVP_PKEY_CTX_new(pk, NULL);
+    if (!pctx)
+        goto err;
+    if (EVP_PKEY_keygen_init(pctx) <= 0)
+        goto err;
+    if (EVP_PKEY_keygen(pctx, &ekey) <= 0)
+        goto err;
+    EVP_PKEY_CTX_free(pctx);
+    pctx = EVP_PKEY_CTX_new(ekey, NULL);
+    if (!pctx)
+        goto err;
+    if (EVP_PKEY_derive_init(pctx) <= 0)
+        goto err;
+    kari->pctx = pctx;
+    rv = 1;
+ err:
+    if (!rv && pctx)
+        EVP_PKEY_CTX_free(pctx);
+    if (ekey)
+        EVP_PKEY_free(ekey);
+    return rv;
+}
+
+/* Initialise a ktri based on passed certificate and key */
+
+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
+                                EVP_PKEY *pk, unsigned int flags)
+{
+    CMS_KeyAgreeRecipientInfo *kari;
+    CMS_RecipientEncryptedKey *rek = NULL;
+
+    ri->d.kari = M_ASN1_new_of(CMS_KeyAgreeRecipientInfo);
+    if (!ri->d.kari)
+        return 0;
+    ri->type = CMS_RECIPINFO_AGREE;
+
+    kari = ri->d.kari;
+    kari->version = 3;
+
+    rek = M_ASN1_new_of(CMS_RecipientEncryptedKey);
+    if (!sk_CMS_RecipientEncryptedKey_push(kari->recipientEncryptedKeys, rek)) {
+        M_ASN1_free_of(rek, CMS_RecipientEncryptedKey);
+        return 0;
+    }
+
+    if (flags & CMS_USE_KEYID) {
+        rek->rid->type = CMS_REK_KEYIDENTIFIER;
+        rek->rid->d.rKeyId = M_ASN1_new_of(CMS_RecipientKeyIdentifier);
+        if (rek->rid->d.rKeyId == NULL)
+            return 0;
+        if (!cms_set1_keyid(&rek->rid->d.rKeyId->subjectKeyIdentifier, recip))
+            return 0;
+    } else {
+        rek->rid->type = CMS_REK_ISSUER_SERIAL;
+        if (!cms_set1_ias(&rek->rid->d.issuerAndSerialNumber, recip))
+            return 0;
+    }
+
+    /* Create ephemeral key */
+    if (!cms_kari_create_ephemeral_key(kari, pk))
+        return 0;
+
+    CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    rek->pkey = pk;
+    return 1;
+}
+
+static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
+                         const EVP_CIPHER *cipher)
+{
+    EVP_CIPHER_CTX *ctx = &kari->ctx;
+    const EVP_CIPHER *kekcipher;
+    int keylen = EVP_CIPHER_key_length(cipher);
+    /* If a suitable wrap algorithm is already set nothing to do */
+    kekcipher = EVP_CIPHER_CTX_cipher(ctx);
+
+    if (kekcipher) {
+        if (EVP_CIPHER_CTX_mode(ctx) != EVP_CIPH_WRAP_MODE)
+            return 0;
+        return 1;
+    }
+    /*
+     * Pick a cipher based on content encryption cipher. If it is DES3 use
+     * DES3 wrap otherwise use AES wrap similar to key size.
+     */
+    if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
+        kekcipher = EVP_des_ede3_wrap();
+    else if (keylen <= 16)
+        kekcipher = EVP_aes_128_wrap();
+    else if (keylen <= 24)
+        kekcipher = EVP_aes_192_wrap();
+    else
+        kekcipher = EVP_aes_256_wrap();
+    return EVP_EncryptInit_ex(ctx, kekcipher, NULL, NULL, NULL);
+}
+
+/* Encrypt content key in key agreement recipient info */
+
+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri)
+{
+    CMS_KeyAgreeRecipientInfo *kari;
+    CMS_EncryptedContentInfo *ec;
+    CMS_RecipientEncryptedKey *rek;
+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
+    int i;
+
+    if (ri->type != CMS_RECIPINFO_AGREE) {
+        CMSerr(CMS_F_CMS_RECIPIENTINFO_KARI_ENCRYPT, CMS_R_NOT_KEY_AGREEMENT);
+        return 0;
+    }
+    kari = ri->d.kari;
+    reks = kari->recipientEncryptedKeys;
+    ec = cms->d.envelopedData->encryptedContentInfo;
+    /* Initialise wrap algorithm parameters */
+    if (!cms_wrap_init(kari, ec->cipher))
+        return 0;
+    /*
+     * If no orignator key set up initialise for ephemeral key the public key
+     * ASN1 structure will set the actual public key value.
+     */
+    if (kari->originator->type == -1) {
+        CMS_OriginatorIdentifierOrKey *oik = kari->originator;
+        oik->type = CMS_OIK_PUBKEY;
+        oik->d.originatorKey = M_ASN1_new_of(CMS_OriginatorPublicKey);
+        if (!oik->d.originatorKey)
+            return 0;
+    }
+    /* Initialise KDF algorithm */
+    if (!cms_env_asn1_ctrl(ri, 0))
+        return 0;
+    /* For each rek, derive KEK, encrypt CEK */
+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
+        unsigned char *enckey;
+        size_t enckeylen;
+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
+        if (EVP_PKEY_derive_set_peer(kari->pctx, rek->pkey) <= 0)
+            return 0;
+        if (!cms_kek_cipher(&enckey, &enckeylen, ec->key, ec->keylen,
+                            kari, 1))
+            return 0;
+        ASN1_STRING_set0(rek->encryptedKey, enckey, enckeylen);
+    }
+
+    return 1;
+
+}

+ 471 - 0
libs/openssl/crypto/cms/cms_lcl.h

@@ -0,0 +1,471 @@
+/* crypto/cms/cms_lcl.h */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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.
+ * ====================================================================
+ */
+
+#ifndef HEADER_CMS_LCL_H
+# define HEADER_CMS_LCL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+# include <openssl/x509.h>
+
+/*
+ * Cryptographic message syntax (CMS) structures: taken from RFC3852
+ */
+
+/* Forward references */
+
+typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber;
+typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo;
+typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier;
+typedef struct CMS_SignedData_st CMS_SignedData;
+typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat;
+typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo;
+typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo;
+typedef struct CMS_EnvelopedData_st CMS_EnvelopedData;
+typedef struct CMS_DigestedData_st CMS_DigestedData;
+typedef struct CMS_EncryptedData_st CMS_EncryptedData;
+typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData;
+typedef struct CMS_CompressedData_st CMS_CompressedData;
+typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat;
+typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo;
+typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey;
+typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey;
+typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo;
+typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier;
+typedef struct CMS_KeyAgreeRecipientIdentifier_st
+    CMS_KeyAgreeRecipientIdentifier;
+typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier;
+typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo;
+typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo;
+typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo;
+typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom;
+
+struct CMS_ContentInfo_st {
+    ASN1_OBJECT *contentType;
+    union {
+        ASN1_OCTET_STRING *data;
+        CMS_SignedData *signedData;
+        CMS_EnvelopedData *envelopedData;
+        CMS_DigestedData *digestedData;
+        CMS_EncryptedData *encryptedData;
+        CMS_AuthenticatedData *authenticatedData;
+        CMS_CompressedData *compressedData;
+        ASN1_TYPE *other;
+        /* Other types ... */
+        void *otherData;
+    } d;
+};
+
+struct CMS_SignedData_st {
+    long version;
+    STACK_OF(X509_ALGOR) *digestAlgorithms;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    STACK_OF(CMS_CertificateChoices) *certificates;
+    STACK_OF(CMS_RevocationInfoChoice) *crls;
+    STACK_OF(CMS_SignerInfo) *signerInfos;
+};
+
+struct CMS_EncapsulatedContentInfo_st {
+    ASN1_OBJECT *eContentType;
+    ASN1_OCTET_STRING *eContent;
+    /* Set to 1 if incomplete structure only part set up */
+    int partial;
+};
+
+struct CMS_SignerInfo_st {
+    long version;
+    CMS_SignerIdentifier *sid;
+    X509_ALGOR *digestAlgorithm;
+    STACK_OF(X509_ATTRIBUTE) *signedAttrs;
+    X509_ALGOR *signatureAlgorithm;
+    ASN1_OCTET_STRING *signature;
+    STACK_OF(X509_ATTRIBUTE) *unsignedAttrs;
+    /* Signing certificate and key */
+    X509 *signer;
+    EVP_PKEY *pkey;
+    /* Digest and public key context for alternative parameters */
+    EVP_MD_CTX mctx;
+    EVP_PKEY_CTX *pctx;
+};
+
+struct CMS_SignerIdentifier_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        ASN1_OCTET_STRING *subjectKeyIdentifier;
+    } d;
+};
+
+struct CMS_EnvelopedData_st {
+    long version;
+    CMS_OriginatorInfo *originatorInfo;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    CMS_EncryptedContentInfo *encryptedContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+};
+
+struct CMS_OriginatorInfo_st {
+    STACK_OF(CMS_CertificateChoices) *certificates;
+    STACK_OF(CMS_RevocationInfoChoice) *crls;
+};
+
+struct CMS_EncryptedContentInfo_st {
+    ASN1_OBJECT *contentType;
+    X509_ALGOR *contentEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedContent;
+    /* Content encryption algorithm and key */
+    const EVP_CIPHER *cipher;
+    unsigned char *key;
+    size_t keylen;
+    /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */
+    int debug;
+};
+
+struct CMS_RecipientInfo_st {
+    int type;
+    union {
+        CMS_KeyTransRecipientInfo *ktri;
+        CMS_KeyAgreeRecipientInfo *kari;
+        CMS_KEKRecipientInfo *kekri;
+        CMS_PasswordRecipientInfo *pwri;
+        CMS_OtherRecipientInfo *ori;
+    } d;
+};
+
+typedef CMS_SignerIdentifier CMS_RecipientIdentifier;
+
+struct CMS_KeyTransRecipientInfo_st {
+    long version;
+    CMS_RecipientIdentifier *rid;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Recipient Key and cert */
+    X509 *recip;
+    EVP_PKEY *pkey;
+    /* Public key context for this operation */
+    EVP_PKEY_CTX *pctx;
+};
+
+struct CMS_KeyAgreeRecipientInfo_st {
+    long version;
+    CMS_OriginatorIdentifierOrKey *originator;
+    ASN1_OCTET_STRING *ukm;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys;
+    /* Public key context associated with current operation */
+    EVP_PKEY_CTX *pctx;
+    /* Cipher context for CEK wrapping */
+    EVP_CIPHER_CTX ctx;
+};
+
+struct CMS_OriginatorIdentifierOrKey_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        ASN1_OCTET_STRING *subjectKeyIdentifier;
+        CMS_OriginatorPublicKey *originatorKey;
+    } d;
+};
+
+struct CMS_OriginatorPublicKey_st {
+    X509_ALGOR *algorithm;
+    ASN1_BIT_STRING *publicKey;
+};
+
+struct CMS_RecipientEncryptedKey_st {
+    CMS_KeyAgreeRecipientIdentifier *rid;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Public key associated with this recipient */
+    EVP_PKEY *pkey;
+};
+
+struct CMS_KeyAgreeRecipientIdentifier_st {
+    int type;
+    union {
+        CMS_IssuerAndSerialNumber *issuerAndSerialNumber;
+        CMS_RecipientKeyIdentifier *rKeyId;
+    } d;
+};
+
+struct CMS_RecipientKeyIdentifier_st {
+    ASN1_OCTET_STRING *subjectKeyIdentifier;
+    ASN1_GENERALIZEDTIME *date;
+    CMS_OtherKeyAttribute *other;
+};
+
+struct CMS_KEKRecipientInfo_st {
+    long version;
+    CMS_KEKIdentifier *kekid;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Extra info: symmetric key to use */
+    unsigned char *key;
+    size_t keylen;
+};
+
+struct CMS_KEKIdentifier_st {
+    ASN1_OCTET_STRING *keyIdentifier;
+    ASN1_GENERALIZEDTIME *date;
+    CMS_OtherKeyAttribute *other;
+};
+
+struct CMS_PasswordRecipientInfo_st {
+    long version;
+    X509_ALGOR *keyDerivationAlgorithm;
+    X509_ALGOR *keyEncryptionAlgorithm;
+    ASN1_OCTET_STRING *encryptedKey;
+    /* Extra info: password to use */
+    unsigned char *pass;
+    size_t passlen;
+};
+
+struct CMS_OtherRecipientInfo_st {
+    ASN1_OBJECT *oriType;
+    ASN1_TYPE *oriValue;
+};
+
+struct CMS_DigestedData_st {
+    long version;
+    X509_ALGOR *digestAlgorithm;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    ASN1_OCTET_STRING *digest;
+};
+
+struct CMS_EncryptedData_st {
+    long version;
+    CMS_EncryptedContentInfo *encryptedContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs;
+};
+
+struct CMS_AuthenticatedData_st {
+    long version;
+    CMS_OriginatorInfo *originatorInfo;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    X509_ALGOR *macAlgorithm;
+    X509_ALGOR *digestAlgorithm;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+    STACK_OF(X509_ATTRIBUTE) *authAttrs;
+    ASN1_OCTET_STRING *mac;
+    STACK_OF(X509_ATTRIBUTE) *unauthAttrs;
+};
+
+struct CMS_CompressedData_st {
+    long version;
+    X509_ALGOR *compressionAlgorithm;
+    STACK_OF(CMS_RecipientInfo) *recipientInfos;
+    CMS_EncapsulatedContentInfo *encapContentInfo;
+};
+
+struct CMS_RevocationInfoChoice_st {
+    int type;
+    union {
+        X509_CRL *crl;
+        CMS_OtherRevocationInfoFormat *other;
+    } d;
+};
+
+# define CMS_REVCHOICE_CRL               0
+# define CMS_REVCHOICE_OTHER             1
+
+struct CMS_OtherRevocationInfoFormat_st {
+    ASN1_OBJECT *otherRevInfoFormat;
+    ASN1_TYPE *otherRevInfo;
+};
+
+struct CMS_CertificateChoices {
+    int type;
+    union {
+        X509 *certificate;
+        ASN1_STRING *extendedCertificate; /* Obsolete */
+        ASN1_STRING *v1AttrCert; /* Left encoded for now */
+        ASN1_STRING *v2AttrCert; /* Left encoded for now */
+        CMS_OtherCertificateFormat *other;
+    } d;
+};
+
+# define CMS_CERTCHOICE_CERT             0
+# define CMS_CERTCHOICE_EXCERT           1
+# define CMS_CERTCHOICE_V1ACERT          2
+# define CMS_CERTCHOICE_V2ACERT          3
+# define CMS_CERTCHOICE_OTHER            4
+
+struct CMS_OtherCertificateFormat_st {
+    ASN1_OBJECT *otherCertFormat;
+    ASN1_TYPE *otherCert;
+};
+
+/*
+ * This is also defined in pkcs7.h but we duplicate it to allow the CMS code
+ * to be independent of PKCS#7
+ */
+
+struct CMS_IssuerAndSerialNumber_st {
+    X509_NAME *issuer;
+    ASN1_INTEGER *serialNumber;
+};
+
+struct CMS_OtherKeyAttribute_st {
+    ASN1_OBJECT *keyAttrId;
+    ASN1_TYPE *keyAttr;
+};
+
+/* ESS structures */
+
+# ifdef HEADER_X509V3_H
+
+struct CMS_ReceiptRequest_st {
+    ASN1_OCTET_STRING *signedContentIdentifier;
+    CMS_ReceiptsFrom *receiptsFrom;
+    STACK_OF(GENERAL_NAMES) *receiptsTo;
+};
+
+struct CMS_ReceiptsFrom_st {
+    int type;
+    union {
+        long allOrFirstTier;
+        STACK_OF(GENERAL_NAMES) *receiptList;
+    } d;
+};
+# endif
+
+struct CMS_Receipt_st {
+    long version;
+    ASN1_OBJECT *contentType;
+    ASN1_OCTET_STRING *signedContentIdentifier;
+    ASN1_OCTET_STRING *originatorSignatureValue;
+};
+
+DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo)
+DECLARE_ASN1_ITEM(CMS_SignerInfo)
+DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber)
+DECLARE_ASN1_ITEM(CMS_Attributes_Sign)
+DECLARE_ASN1_ITEM(CMS_Attributes_Verify)
+DECLARE_ASN1_ITEM(CMS_RecipientInfo)
+DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo)
+DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber)
+
+# define CMS_SIGNERINFO_ISSUER_SERIAL    0
+# define CMS_SIGNERINFO_KEYIDENTIFIER    1
+
+# define CMS_RECIPINFO_ISSUER_SERIAL     0
+# define CMS_RECIPINFO_KEYIDENTIFIER     1
+
+# define CMS_REK_ISSUER_SERIAL           0
+# define CMS_REK_KEYIDENTIFIER           1
+
+# define CMS_OIK_ISSUER_SERIAL           0
+# define CMS_OIK_KEYIDENTIFIER           1
+# define CMS_OIK_PUBKEY                  2
+
+BIO *cms_content_bio(CMS_ContentInfo *cms);
+
+CMS_ContentInfo *cms_Data_create(void);
+
+CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md);
+BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms);
+int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify);
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms);
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain);
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
+                              int type);
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno);
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert);
+
+CMS_ContentInfo *cms_CompressedData_create(int comp_nid);
+BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms);
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md);
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm);
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+                                 X509_ALGOR *mdalg);
+
+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert);
+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert);
+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert);
+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert);
+
+BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec);
+BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms);
+int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec,
+                              const EVP_CIPHER *cipher,
+                              const unsigned char *key, size_t keylen);
+
+int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms);
+int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src);
+ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si);
+
+BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms);
+CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms);
+int cms_env_asn1_ctrl(CMS_RecipientInfo *ri, int cmd);
+int cms_pkey_get_ri_type(EVP_PKEY *pk);
+/* KARI routines */
+int cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri, X509 *recip,
+                                EVP_PKEY *pk, unsigned int flags);
+int cms_RecipientInfo_kari_encrypt(CMS_ContentInfo *cms,
+                                   CMS_RecipientInfo *ri);
+
+/* PWRI routines */
+int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                                 int en_de);
+
+#ifdef  __cplusplus
+}
+#endif
+#endif

+ 652 - 0
libs/openssl/crypto/cms/cms_lib.c

@@ -0,0 +1,652 @@
+/* crypto/cms/cms_lib.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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 <openssl/asn1t.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/bio.h>
+#include <openssl/asn1.h>
+#include "cms.h"
+#include "cms_lcl.h"
+
+IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo)
+IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo)
+
+DECLARE_ASN1_ITEM(CMS_CertificateChoices)
+DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice)
+DECLARE_STACK_OF(CMS_CertificateChoices)
+DECLARE_STACK_OF(CMS_RevocationInfoChoice)
+
+const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms)
+{
+    return cms->contentType;
+}
+
+CMS_ContentInfo *cms_Data_create(void)
+{
+    CMS_ContentInfo *cms;
+    cms = CMS_ContentInfo_new();
+    if (cms) {
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_data);
+        /* Never detached */
+        CMS_set_detached(cms, 0);
+    }
+    return cms;
+}
+
+BIO *cms_content_bio(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos)
+        return NULL;
+    /* If content detached data goes nowhere: create NULL BIO */
+    if (!*pos)
+        return BIO_new(BIO_s_null());
+    /*
+     * If content not detached and created return memory BIO
+     */
+    if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT))
+        return BIO_new(BIO_s_mem());
+    /* Else content was read in: return read only BIO for it */
+    return BIO_new_mem_buf((*pos)->data, (*pos)->length);
+}
+
+BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont)
+{
+    BIO *cmsbio, *cont;
+    if (icont)
+        cont = icont;
+    else
+        cont = cms_content_bio(cms);
+    if (!cont) {
+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT);
+        return NULL;
+    }
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+        return cont;
+
+    case NID_pkcs7_signed:
+        cmsbio = cms_SignedData_init_bio(cms);
+        break;
+
+    case NID_pkcs7_digest:
+        cmsbio = cms_DigestedData_init_bio(cms);
+        break;
+#ifdef ZLIB
+    case NID_id_smime_ct_compressedData:
+        cmsbio = cms_CompressedData_init_bio(cms);
+        break;
+#endif
+
+    case NID_pkcs7_encrypted:
+        cmsbio = cms_EncryptedData_init_bio(cms);
+        break;
+
+    case NID_pkcs7_enveloped:
+        cmsbio = cms_EnvelopedData_init_bio(cms);
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE);
+        return NULL;
+    }
+
+    if (cmsbio)
+        return BIO_push(cmsbio, cont);
+
+    if (!icont)
+        BIO_free(cont);
+    return NULL;
+
+}
+
+int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos)
+        return 0;
+    /* If ebmedded content find memory BIO and set content */
+    if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) {
+        BIO *mbio;
+        unsigned char *cont;
+        long contlen;
+        mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM);
+        if (!mbio) {
+            CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND);
+            return 0;
+        }
+        contlen = BIO_get_mem_data(mbio, &cont);
+        /* Set bio as read only so its content can't be clobbered */
+        BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY);
+        BIO_set_mem_eof_return(mbio, 0);
+        ASN1_STRING_set0(*pos, cont, contlen);
+        (*pos)->flags &= ~ASN1_STRING_FLAG_CONT;
+    }
+
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+    case NID_pkcs7_enveloped:
+    case NID_pkcs7_encrypted:
+    case NID_id_smime_ct_compressedData:
+        /* Nothing to do */
+        return 1;
+
+    case NID_pkcs7_signed:
+        return cms_SignedData_final(cms, cmsbio);
+
+    case NID_pkcs7_digest:
+        return cms_DigestedData_do_final(cms, cmsbio, 0);
+
+    default:
+        CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE);
+        return 0;
+    }
+}
+
+/*
+ * Return an OCTET STRING pointer to content. This allows it to be accessed
+ * or set later.
+ */
+
+ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_data:
+        return &cms->d.data;
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->encapContentInfo->eContent;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->encryptedContentInfo->encryptedContent;
+
+    case NID_pkcs7_digest:
+        return &cms->d.digestedData->encapContentInfo->eContent;
+
+    case NID_pkcs7_encrypted:
+        return &cms->d.encryptedData->encryptedContentInfo->encryptedContent;
+
+    case NID_id_smime_ct_authData:
+        return &cms->d.authenticatedData->encapContentInfo->eContent;
+
+    case NID_id_smime_ct_compressedData:
+        return &cms->d.compressedData->encapContentInfo->eContent;
+
+    default:
+        if (cms->d.other->type == V_ASN1_OCTET_STRING)
+            return &cms->d.other->value.octet_string;
+        CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+/*
+ * Return an ASN1_OBJECT pointer to content type. This allows it to be
+ * accessed or set later.
+ */
+
+static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->encapContentInfo->eContentType;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->encryptedContentInfo->contentType;
+
+    case NID_pkcs7_digest:
+        return &cms->d.digestedData->encapContentInfo->eContentType;
+
+    case NID_pkcs7_encrypted:
+        return &cms->d.encryptedData->encryptedContentInfo->contentType;
+
+    case NID_id_smime_ct_authData:
+        return &cms->d.authenticatedData->encapContentInfo->eContentType;
+
+    case NID_id_smime_ct_compressedData:
+        return &cms->d.compressedData->encapContentInfo->eContentType;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms)
+{
+    ASN1_OBJECT **petype;
+    petype = cms_get0_econtent_type(cms);
+    if (petype)
+        return *petype;
+    return NULL;
+}
+
+int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid)
+{
+    ASN1_OBJECT **petype, *etype;
+    petype = cms_get0_econtent_type(cms);
+    if (!petype)
+        return 0;
+    if (!oid)
+        return 1;
+    etype = OBJ_dup(oid);
+    if (!etype)
+        return 0;
+    ASN1_OBJECT_free(*petype);
+    *petype = etype;
+    return 1;
+}
+
+int CMS_is_detached(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (!pos)
+        return -1;
+    if (*pos)
+        return 0;
+    return 1;
+}
+
+int CMS_set_detached(CMS_ContentInfo *cms, int detached)
+{
+    ASN1_OCTET_STRING **pos;
+    pos = CMS_get0_content(cms);
+    if (!pos)
+        return 0;
+    if (detached) {
+        if (*pos) {
+            ASN1_OCTET_STRING_free(*pos);
+            *pos = NULL;
+        }
+        return 1;
+    }
+    if (!*pos)
+        *pos = ASN1_OCTET_STRING_new();
+    if (*pos) {
+        /*
+         * NB: special flag to show content is created and not read in.
+         */
+        (*pos)->flags |= ASN1_STRING_FLAG_CONT;
+        return 1;
+    }
+    CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
+
+void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md)
+{
+    int param_type;
+
+    if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
+        param_type = V_ASN1_UNDEF;
+    else
+        param_type = V_ASN1_NULL;
+
+    X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
+
+}
+
+/* Create a digest BIO from an X509_ALGOR structure */
+
+BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm)
+{
+    BIO *mdbio = NULL;
+    ASN1_OBJECT *digestoid;
+    const EVP_MD *digest;
+    X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm);
+    digest = EVP_get_digestbyobj(digestoid);
+    if (!digest) {
+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO,
+               CMS_R_UNKNOWN_DIGEST_ALGORIHM);
+        goto err;
+    }
+    mdbio = BIO_new(BIO_f_md());
+    if (!mdbio || !BIO_set_md(mdbio, digest)) {
+        CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR);
+        goto err;
+    }
+    return mdbio;
+ err:
+    if (mdbio)
+        BIO_free(mdbio);
+    return NULL;
+}
+
+/* Locate a message digest content from a BIO chain based on SignerInfo */
+
+int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain,
+                                 X509_ALGOR *mdalg)
+{
+    int nid;
+    ASN1_OBJECT *mdoid;
+    X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg);
+    nid = OBJ_obj2nid(mdoid);
+    /* Look for digest type to match signature */
+    for (;;) {
+        EVP_MD_CTX *mtmp;
+        chain = BIO_find_type(chain, BIO_TYPE_MD);
+        if (chain == NULL) {
+            CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX,
+                   CMS_R_NO_MATCHING_DIGEST);
+            return 0;
+        }
+        BIO_get_md_ctx(chain, &mtmp);
+        if (EVP_MD_CTX_type(mtmp) == nid
+            /*
+             * Workaround for broken implementations that use signature
+             * algorithm OID instead of digest.
+             */
+            || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid)
+            return EVP_MD_CTX_copy_ex(mctx, mtmp);
+        chain = BIO_next(chain);
+    }
+}
+
+static STACK_OF(CMS_CertificateChoices)
+**cms_get0_certificate_choices(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->certificates;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->originatorInfo->certificates;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES,
+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms)
+{
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    CMS_CertificateChoices *cch;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return NULL;
+    if (!*pcerts)
+        *pcerts = sk_CMS_CertificateChoices_new_null();
+    if (!*pcerts)
+        return NULL;
+    cch = M_ASN1_new_of(CMS_CertificateChoices);
+    if (!cch)
+        return NULL;
+    if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) {
+        M_ASN1_free_of(cch, CMS_CertificateChoices);
+        return NULL;
+    }
+    return cch;
+}
+
+int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert)
+{
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    int i;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return 0;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+        if (cch->type == CMS_CERTCHOICE_CERT) {
+            if (!X509_cmp(cch->d.certificate, cert)) {
+                CMSerr(CMS_F_CMS_ADD0_CERT,
+                       CMS_R_CERTIFICATE_ALREADY_PRESENT);
+                return 0;
+            }
+        }
+    }
+    cch = CMS_add0_CertificateChoices(cms);
+    if (!cch)
+        return 0;
+    cch->type = CMS_CERTCHOICE_CERT;
+    cch->d.certificate = cert;
+    return 1;
+}
+
+int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert)
+{
+    int r;
+    r = CMS_add0_cert(cms, cert);
+    if (r > 0)
+        CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509);
+    return r;
+}
+
+static STACK_OF(CMS_RevocationInfoChoice)
+**cms_get0_revocation_choices(CMS_ContentInfo *cms)
+{
+    switch (OBJ_obj2nid(cms->contentType)) {
+
+    case NID_pkcs7_signed:
+        return &cms->d.signedData->crls;
+
+    case NID_pkcs7_enveloped:
+        return &cms->d.envelopedData->originatorInfo->crls;
+
+    default:
+        CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES,
+               CMS_R_UNSUPPORTED_CONTENT_TYPE);
+        return NULL;
+
+    }
+}
+
+CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms)
+{
+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+    CMS_RevocationInfoChoice *rch;
+    pcrls = cms_get0_revocation_choices(cms);
+    if (!pcrls)
+        return NULL;
+    if (!*pcrls)
+        *pcrls = sk_CMS_RevocationInfoChoice_new_null();
+    if (!*pcrls)
+        return NULL;
+    rch = M_ASN1_new_of(CMS_RevocationInfoChoice);
+    if (!rch)
+        return NULL;
+    if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) {
+        M_ASN1_free_of(rch, CMS_RevocationInfoChoice);
+        return NULL;
+    }
+    return rch;
+}
+
+int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+{
+    CMS_RevocationInfoChoice *rch;
+    rch = CMS_add0_RevocationInfoChoice(cms);
+    if (!rch)
+        return 0;
+    rch->type = CMS_REVCHOICE_CRL;
+    rch->d.crl = crl;
+    return 1;
+}
+
+int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl)
+{
+    int r;
+    r = CMS_add0_crl(cms, crl);
+    if (r > 0)
+        CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL);
+    return r;
+}
+
+STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509) *certs = NULL;
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) **pcerts;
+    int i;
+    pcerts = cms_get0_certificate_choices(cms);
+    if (!pcerts)
+        return NULL;
+    for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) {
+        cch = sk_CMS_CertificateChoices_value(*pcerts, i);
+        if (cch->type == 0) {
+            if (!certs) {
+                certs = sk_X509_new_null();
+                if (!certs)
+                    return NULL;
+            }
+            if (!sk_X509_push(certs, cch->d.certificate)) {
+                sk_X509_pop_free(certs, X509_free);
+                return NULL;
+            }
+            CRYPTO_add(&cch->d.certificate->references, 1, CRYPTO_LOCK_X509);
+        }
+    }
+    return certs;
+
+}
+
+STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509_CRL) *crls = NULL;
+    STACK_OF(CMS_RevocationInfoChoice) **pcrls;
+    CMS_RevocationInfoChoice *rch;
+    int i;
+    pcrls = cms_get0_revocation_choices(cms);
+    if (!pcrls)
+        return NULL;
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) {
+        rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i);
+        if (rch->type == 0) {
+            if (!crls) {
+                crls = sk_X509_CRL_new_null();
+                if (!crls)
+                    return NULL;
+            }
+            if (!sk_X509_CRL_push(crls, rch->d.crl)) {
+                sk_X509_CRL_pop_free(crls, X509_CRL_free);
+                return NULL;
+            }
+            CRYPTO_add(&rch->d.crl->references, 1, CRYPTO_LOCK_X509_CRL);
+        }
+    }
+    return crls;
+}
+
+int cms_ias_cert_cmp(CMS_IssuerAndSerialNumber *ias, X509 *cert)
+{
+    int ret;
+    ret = X509_NAME_cmp(ias->issuer, X509_get_issuer_name(cert));
+    if (ret)
+        return ret;
+    return ASN1_INTEGER_cmp(ias->serialNumber, X509_get_serialNumber(cert));
+}
+
+int cms_keyid_cert_cmp(ASN1_OCTET_STRING *keyid, X509 *cert)
+{
+    X509_check_purpose(cert, -1, -1);
+    if (!cert->skid)
+        return -1;
+    return ASN1_OCTET_STRING_cmp(keyid, cert->skid);
+}
+
+int cms_set1_ias(CMS_IssuerAndSerialNumber **pias, X509 *cert)
+{
+    CMS_IssuerAndSerialNumber *ias;
+    ias = M_ASN1_new_of(CMS_IssuerAndSerialNumber);
+    if (!ias)
+        goto err;
+    if (!X509_NAME_set(&ias->issuer, X509_get_issuer_name(cert)))
+        goto err;
+    if (!ASN1_STRING_copy(ias->serialNumber, X509_get_serialNumber(cert)))
+        goto err;
+    if (*pias)
+        M_ASN1_free_of(*pias, CMS_IssuerAndSerialNumber);
+    *pias = ias;
+    return 1;
+ err:
+    if (ias)
+        M_ASN1_free_of(ias, CMS_IssuerAndSerialNumber);
+    CMSerr(CMS_F_CMS_SET1_IAS, ERR_R_MALLOC_FAILURE);
+    return 0;
+}
+
+int cms_set1_keyid(ASN1_OCTET_STRING **pkeyid, X509 *cert)
+{
+    ASN1_OCTET_STRING *keyid = NULL;
+    X509_check_purpose(cert, -1, -1);
+    if (!cert->skid) {
+        CMSerr(CMS_F_CMS_SET1_KEYID, CMS_R_CERTIFICATE_HAS_NO_KEYID);
+        return 0;
+    }
+    keyid = ASN1_STRING_dup(cert->skid);
+    if (!keyid) {
+        CMSerr(CMS_F_CMS_SET1_KEYID, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+    if (*pkeyid)
+        ASN1_OCTET_STRING_free(*pkeyid);
+    *pkeyid = keyid;
+    return 1;
+}

+ 432 - 0
libs/openssl/crypto/cms/cms_pwri.c

@@ -0,0 +1,432 @@
+/* crypto/cms/cms_pwri.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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();
+    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)
+            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)
+            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;
+
+}

+ 955 - 0
libs/openssl/crypto/cms/cms_sd.c

@@ -0,0 +1,955 @@
+/* crypto/cms/cms_sd.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+/* CMS SignedData Utilities */
+
+DECLARE_ASN1_ITEM(CMS_SignedData)
+
+static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
+{
+    if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
+        CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
+        return NULL;
+    }
+    return cms->d.signedData;
+}
+
+static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
+{
+    if (cms->d.other == NULL) {
+        cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
+        if (!cms->d.signedData) {
+            CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
+            return NULL;
+        }
+        cms->d.signedData->version = 1;
+        cms->d.signedData->encapContentInfo->eContentType =
+            OBJ_nid2obj(NID_pkcs7_data);
+        cms->d.signedData->encapContentInfo->partial = 1;
+        ASN1_OBJECT_free(cms->contentType);
+        cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
+        return cms->d.signedData;
+    }
+    return cms_get0_signed(cms);
+}
+
+/* Just initialize SignedData e.g. for certs only structure */
+
+int CMS_SignedData_init(CMS_ContentInfo *cms)
+{
+    if (cms_signed_data_init(cms))
+        return 1;
+    else
+        return 0;
+}
+
+/* Check structures and fixup version numbers (if necessary) */
+
+static void cms_sd_set_version(CMS_SignedData *sd)
+{
+    int i;
+    CMS_CertificateChoices *cch;
+    CMS_RevocationInfoChoice *rch;
+    CMS_SignerInfo *si;
+
+    for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
+        cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
+        if (cch->type == CMS_CERTCHOICE_OTHER) {
+            if (sd->version < 5)
+                sd->version = 5;
+        } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
+            if (sd->version < 4)
+                sd->version = 4;
+        } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
+            if (sd->version < 3)
+                sd->version = 3;
+        }
+    }
+
+    for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
+        rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
+        if (rch->type == CMS_REVCHOICE_OTHER) {
+            if (sd->version < 5)
+                sd->version = 5;
+        }
+    }
+
+    if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
+        && (sd->version < 3))
+        sd->version = 3;
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+        if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
+            if (si->version < 3)
+                si->version = 3;
+            if (sd->version < 3)
+                sd->version = 3;
+        } else if (si->version < 1)
+            si->version = 1;
+    }
+
+    if (sd->version < 1)
+        sd->version = 1;
+
+}
+
+/* Copy an existing messageDigest value */
+
+static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
+{
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *sitmp;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        ASN1_OCTET_STRING *messageDigest;
+        sitmp = sk_CMS_SignerInfo_value(sinfos, i);
+        if (sitmp == si)
+            continue;
+        if (CMS_signed_get_attr_count(sitmp) < 0)
+            continue;
+        if (OBJ_cmp(si->digestAlgorithm->algorithm,
+                    sitmp->digestAlgorithm->algorithm))
+            continue;
+        messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
+                                                    OBJ_nid2obj
+                                                    (NID_pkcs9_messageDigest),
+                                                    -3, V_ASN1_OCTET_STRING);
+        if (!messageDigest) {
+            CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+            return 0;
+        }
+
+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+                                        V_ASN1_OCTET_STRING,
+                                        messageDigest, -1))
+            return 1;
+        else
+            return 0;
+    }
+    CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
+    return 0;
+}
+
+int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
+{
+    switch (type) {
+    case CMS_SIGNERINFO_ISSUER_SERIAL:
+        if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
+            return 0;
+        break;
+
+    case CMS_SIGNERINFO_KEYIDENTIFIER:
+        if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
+            return 0;
+        break;
+
+    default:
+        CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
+        return 0;
+    }
+
+    sid->type = type;
+
+    return 1;
+}
+
+int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
+                                        ASN1_OCTET_STRING **keyid,
+                                        X509_NAME **issuer,
+                                        ASN1_INTEGER **sno)
+{
+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
+        if (issuer)
+            *issuer = sid->d.issuerAndSerialNumber->issuer;
+        if (sno)
+            *sno = sid->d.issuerAndSerialNumber->serialNumber;
+    } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
+        if (keyid)
+            *keyid = sid->d.subjectKeyIdentifier;
+    } else
+        return 0;
+    return 1;
+}
+
+int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
+{
+    if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
+        return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
+    else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
+        return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
+    else
+        return -1;
+}
+
+static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
+{
+    EVP_PKEY *pkey = si->pkey;
+    int i;
+    if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+        return 1;
+    i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
+    if (i == -2) {
+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+    if (i <= 0) {
+        CMSerr(CMS_F_CMS_SD_ASN1_CTRL, CMS_R_CTRL_FAILURE);
+        return 0;
+    }
+    return 1;
+}
+
+CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
+                                X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
+                                unsigned int flags)
+{
+    CMS_SignedData *sd;
+    CMS_SignerInfo *si = NULL;
+    X509_ALGOR *alg;
+    int i, type;
+    if (!X509_check_private_key(signer, pk)) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER,
+               CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
+        return NULL;
+    }
+    sd = cms_signed_data_init(cms);
+    if (!sd)
+        goto err;
+    si = M_ASN1_new_of(CMS_SignerInfo);
+    if (!si)
+        goto merr;
+    X509_check_purpose(signer, -1, -1);
+
+    CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
+    CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+
+    si->pkey = pk;
+    si->signer = signer;
+    EVP_MD_CTX_init(&si->mctx);
+    si->pctx = NULL;
+
+    if (flags & CMS_USE_KEYID) {
+        si->version = 3;
+        if (sd->version < 3)
+            sd->version = 3;
+        type = CMS_SIGNERINFO_KEYIDENTIFIER;
+    } else {
+        type = CMS_SIGNERINFO_ISSUER_SERIAL;
+        si->version = 1;
+    }
+
+    if (!cms_set1_SignerIdentifier(si->sid, signer, type))
+        goto err;
+
+    if (md == NULL) {
+        int def_nid;
+        if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
+            goto err;
+        md = EVP_get_digestbynid(def_nid);
+        if (md == NULL) {
+            CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
+            goto err;
+        }
+    }
+
+    if (!md) {
+        CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
+        goto err;
+    }
+
+    cms_DigestAlgorithm_set(si->digestAlgorithm, md);
+
+    /* See if digest is present in digestAlgorithms */
+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
+        ASN1_OBJECT *aoid;
+        alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+        X509_ALGOR_get0(&aoid, NULL, NULL, alg);
+        if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
+            break;
+    }
+
+    if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
+        alg = X509_ALGOR_new();
+        if (!alg)
+            goto merr;
+        cms_DigestAlgorithm_set(alg, md);
+        if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
+            X509_ALGOR_free(alg);
+            goto merr;
+        }
+    }
+
+    if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
+        goto err;
+    if (!(flags & CMS_NOATTR)) {
+        /*
+         * Initialialize signed attributes strutucture so other attributes
+         * such as signing time etc are added later even if we add none here.
+         */
+        if (!si->signedAttrs) {
+            si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
+            if (!si->signedAttrs)
+                goto merr;
+        }
+
+        if (!(flags & CMS_NOSMIMECAP)) {
+            STACK_OF(X509_ALGOR) *smcap = NULL;
+            i = CMS_add_standard_smimecap(&smcap);
+            if (i)
+                i = CMS_add_smimecap(si, smcap);
+            sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+            if (!i)
+                goto merr;
+        }
+        if (flags & CMS_REUSE_DIGEST) {
+            if (!cms_copy_messageDigest(cms, si))
+                goto err;
+            if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
+                !CMS_SignerInfo_sign(si))
+                goto err;
+        }
+    }
+
+    if (!(flags & CMS_NOCERTS)) {
+        /* NB ignore -1 return for duplicate cert */
+        if (!CMS_add1_cert(cms, signer))
+            goto merr;
+    }
+
+    if (flags & CMS_KEY_PARAM) {
+        if (flags & CMS_NOATTR) {
+            si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+            if (!si->pctx)
+                goto err;
+            if (EVP_PKEY_sign_init(si->pctx) <= 0)
+                goto err;
+            if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
+                goto err;
+        } else if (EVP_DigestSignInit(&si->mctx, &si->pctx, md, NULL, pk) <=
+                   0)
+            goto err;
+    }
+
+    if (!sd->signerInfos)
+        sd->signerInfos = sk_CMS_SignerInfo_new_null();
+    if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
+        goto merr;
+
+    return si;
+
+ merr:
+    CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
+ err:
+    if (si)
+        M_ASN1_free_of(si, CMS_SignerInfo);
+    return NULL;
+
+}
+
+static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
+{
+    ASN1_TIME *tt;
+    int r = 0;
+    if (t)
+        tt = t;
+    else
+        tt = X509_gmtime_adj(NULL, 0);
+
+    if (!tt)
+        goto merr;
+
+    if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
+                                    tt->type, tt, -1) <= 0)
+        goto merr;
+
+    r = 1;
+
+ merr:
+
+    if (!t)
+        ASN1_TIME_free(tt);
+
+    if (!r)
+        CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
+
+    return r;
+
+}
+
+EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
+{
+    return si->pctx;
+}
+
+EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
+{
+    return &si->mctx;
+}
+
+STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
+{
+    CMS_SignedData *sd;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return NULL;
+    return sd->signerInfos;
+}
+
+STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
+{
+    STACK_OF(X509) *signers = NULL;
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *si;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        if (si->signer) {
+            if (!signers) {
+                signers = sk_X509_new_null();
+                if (!signers)
+                    return NULL;
+            }
+            if (!sk_X509_push(signers, si->signer)) {
+                sk_X509_free(signers);
+                return NULL;
+            }
+        }
+    }
+    return signers;
+}
+
+void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
+{
+    if (signer) {
+        CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
+        if (si->pkey)
+            EVP_PKEY_free(si->pkey);
+        si->pkey = X509_get_pubkey(signer);
+    }
+    if (si->signer)
+        X509_free(si->signer);
+    si->signer = signer;
+}
+
+int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
+                                  ASN1_OCTET_STRING **keyid,
+                                  X509_NAME **issuer, ASN1_INTEGER **sno)
+{
+    return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
+}
+
+int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
+{
+    return cms_SignerIdentifier_cert_cmp(si->sid, cert);
+}
+
+int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
+                           unsigned int flags)
+{
+    CMS_SignedData *sd;
+    CMS_SignerInfo *si;
+    CMS_CertificateChoices *cch;
+    STACK_OF(CMS_CertificateChoices) *certs;
+    X509 *x;
+    int i, j;
+    int ret = 0;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return -1;
+    certs = sd->certificates;
+    for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
+        si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
+        if (si->signer)
+            continue;
+
+        for (j = 0; j < sk_X509_num(scerts); j++) {
+            x = sk_X509_value(scerts, j);
+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
+                CMS_SignerInfo_set1_signer_cert(si, x);
+                ret++;
+                break;
+            }
+        }
+
+        if (si->signer || (flags & CMS_NOINTERN))
+            continue;
+
+        for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
+            cch = sk_CMS_CertificateChoices_value(certs, j);
+            if (cch->type != 0)
+                continue;
+            x = cch->d.certificate;
+            if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
+                CMS_SignerInfo_set1_signer_cert(si, x);
+                ret++;
+                break;
+            }
+        }
+    }
+    return ret;
+}
+
+void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
+                              X509 **signer, X509_ALGOR **pdig,
+                              X509_ALGOR **psig)
+{
+    if (pk)
+        *pk = si->pkey;
+    if (signer)
+        *signer = si->signer;
+    if (pdig)
+        *pdig = si->digestAlgorithm;
+    if (psig)
+        *psig = si->signatureAlgorithm;
+}
+
+ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
+{
+    return si->signature;
+}
+
+static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
+                                       CMS_SignerInfo *si, BIO *chain)
+{
+    EVP_MD_CTX mctx;
+    int r = 0;
+    EVP_PKEY_CTX *pctx = NULL;
+    EVP_MD_CTX_init(&mctx);
+
+    if (!si->pkey) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
+        return 0;
+    }
+
+    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+        goto err;
+    /* Set SignerInfo algortihm details if we used custom parametsr */
+    if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
+        goto err;
+
+    /*
+     * If any signed attributes calculate and add messageDigest attribute
+     */
+
+    if (CMS_signed_get_attr_count(si) >= 0) {
+        ASN1_OBJECT *ctype =
+            cms->d.signedData->encapContentInfo->eContentType;
+        unsigned char md[EVP_MAX_MD_SIZE];
+        unsigned int mdlen;
+        if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+            goto err;
+        if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
+                                         V_ASN1_OCTET_STRING, md, mdlen))
+            goto err;
+        /* Copy content type across */
+        if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
+                                        V_ASN1_OBJECT, ctype, -1) <= 0)
+            goto err;
+        if (!CMS_SignerInfo_sign(si))
+            goto err;
+    } else if (si->pctx) {
+        unsigned char *sig;
+        size_t siglen;
+        unsigned char md[EVP_MAX_MD_SIZE];
+        unsigned int mdlen;
+        pctx = si->pctx;
+        if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
+            goto err;
+        siglen = EVP_PKEY_size(si->pkey);
+        sig = OPENSSL_malloc(siglen);
+        if (!sig) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0)
+            goto err;
+        ASN1_STRING_set0(si->signature, sig, siglen);
+    } else {
+        unsigned char *sig;
+        unsigned int siglen;
+        sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
+        if (!sig) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
+            goto err;
+        }
+        if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
+            OPENSSL_free(sig);
+            goto err;
+        }
+        ASN1_STRING_set0(si->signature, sig, siglen);
+    }
+
+    r = 1;
+
+ err:
+    EVP_MD_CTX_cleanup(&mctx);
+    if (pctx)
+        EVP_PKEY_CTX_free(pctx);
+    return r;
+
+}
+
+int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
+{
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    CMS_SignerInfo *si;
+    int i;
+    sinfos = CMS_get0_SignerInfos(cms);
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        if (!cms_SignerInfo_content_sign(cms, si, chain))
+            return 0;
+    }
+    cms->d.signedData->encapContentInfo->partial = 0;
+    return 1;
+}
+
+int CMS_SignerInfo_sign(CMS_SignerInfo *si)
+{
+    EVP_MD_CTX *mctx = &si->mctx;
+    EVP_PKEY_CTX *pctx;
+    unsigned char *abuf = NULL;
+    int alen;
+    size_t siglen;
+    const EVP_MD *md = NULL;
+
+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    if (md == NULL)
+        return 0;
+
+    if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
+        if (!cms_add1_signingTime(si, NULL))
+            goto err;
+    }
+
+    if (si->pctx)
+        pctx = si->pctx;
+    else {
+        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_CMS_SIGN, 0, si) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
+                         ASN1_ITEM_rptr(CMS_Attributes_Sign));
+    if (!abuf)
+        goto err;
+    if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
+        goto err;
+    if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
+        goto err;
+    OPENSSL_free(abuf);
+    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_CMS_SIGN, 1, si) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
+        goto err;
+    }
+
+    EVP_MD_CTX_cleanup(mctx);
+
+    ASN1_STRING_set0(si->signature, abuf, siglen);
+
+    return 1;
+
+ err:
+    if (abuf)
+        OPENSSL_free(abuf);
+    EVP_MD_CTX_cleanup(mctx);
+    return 0;
+
+}
+
+int CMS_SignerInfo_verify(CMS_SignerInfo *si)
+{
+    EVP_MD_CTX *mctx = &si->mctx;
+    unsigned char *abuf = NULL;
+    int alen, r = -1;
+    const EVP_MD *md = NULL;
+
+    if (!si->pkey) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
+        return -1;
+    }
+
+    md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
+    if (md == NULL)
+        return -1;
+    EVP_MD_CTX_init(mctx);
+    if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
+        goto err;
+
+    if (!cms_sd_asn1_ctrl(si, 1))
+        goto err;
+
+    alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
+                         ASN1_ITEM_rptr(CMS_Attributes_Verify));
+    if (!abuf)
+        goto err;
+    r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
+    OPENSSL_free(abuf);
+    if (r <= 0) {
+        r = -1;
+        goto err;
+    }
+    r = EVP_DigestVerifyFinal(mctx,
+                              si->signature->data, si->signature->length);
+    if (r <= 0)
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
+ err:
+    EVP_MD_CTX_cleanup(mctx);
+    return r;
+}
+
+/* Create a chain of digest BIOs from a CMS ContentInfo */
+
+BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
+{
+    int i;
+    CMS_SignedData *sd;
+    BIO *chain = NULL;
+    sd = cms_get0_signed(cms);
+    if (!sd)
+        return NULL;
+    if (cms->d.signedData->encapContentInfo->partial)
+        cms_sd_set_version(sd);
+    for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
+        X509_ALGOR *digestAlgorithm;
+        BIO *mdbio;
+        digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
+        mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
+        if (!mdbio)
+            goto err;
+        if (chain)
+            BIO_push(chain, mdbio);
+        else
+            chain = mdbio;
+    }
+    return chain;
+ err:
+    if (chain)
+        BIO_free_all(chain);
+    return NULL;
+}
+
+int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
+{
+    ASN1_OCTET_STRING *os = NULL;
+    EVP_MD_CTX mctx;
+    EVP_PKEY_CTX *pkctx = NULL;
+    int r = -1;
+    unsigned char mval[EVP_MAX_MD_SIZE];
+    unsigned int mlen;
+    EVP_MD_CTX_init(&mctx);
+    /* If we have any signed attributes look for messageDigest value */
+    if (CMS_signed_get_attr_count(si) >= 0) {
+        os = CMS_signed_get0_data_by_OBJ(si,
+                                         OBJ_nid2obj(NID_pkcs9_messageDigest),
+                                         -3, V_ASN1_OCTET_STRING);
+        if (!os) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
+            goto err;
+        }
+    }
+
+    if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
+        goto err;
+
+    if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+               CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
+        goto err;
+    }
+
+    /* If messageDigest found compare it */
+
+    if (os) {
+        if (mlen != (unsigned int)os->length) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
+            goto err;
+        }
+
+        if (memcmp(mval, os->data, mlen)) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_VERIFICATION_FAILURE);
+            r = 0;
+        } else
+            r = 1;
+    } else {
+        const EVP_MD *md = EVP_MD_CTX_md(&mctx);
+        pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
+        if (EVP_PKEY_verify_init(pkctx) <= 0)
+            goto err;
+        if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
+            goto err;
+        si->pctx = pkctx;
+        if (!cms_sd_asn1_ctrl(si, 1))
+            goto err;
+        r = EVP_PKEY_verify(pkctx, si->signature->data,
+                            si->signature->length, mval, mlen);
+        if (r <= 0) {
+            CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
+                   CMS_R_VERIFICATION_FAILURE);
+            r = 0;
+        }
+    }
+
+ err:
+    if (pkctx)
+        EVP_PKEY_CTX_free(pkctx);
+    EVP_MD_CTX_cleanup(&mctx);
+    return r;
+
+}
+
+int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
+{
+    unsigned char *smder = NULL;
+    int smderlen, r;
+    smderlen = i2d_X509_ALGORS(algs, &smder);
+    if (smderlen <= 0)
+        return 0;
+    r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
+                                    V_ASN1_SEQUENCE, smder, smderlen);
+    OPENSSL_free(smder);
+    return r;
+}
+
+int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
+                            int algnid, int keysize)
+{
+    X509_ALGOR *alg;
+    ASN1_INTEGER *key = NULL;
+    if (keysize > 0) {
+        key = ASN1_INTEGER_new();
+        if (!key || !ASN1_INTEGER_set(key, keysize))
+            return 0;
+    }
+    alg = X509_ALGOR_new();
+    if (!alg) {
+        if (key)
+            ASN1_INTEGER_free(key);
+        return 0;
+    }
+
+    X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
+                    key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
+    if (!*algs)
+        *algs = sk_X509_ALGOR_new_null();
+    if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) {
+        X509_ALGOR_free(alg);
+        return 0;
+    }
+    return 1;
+}
+
+/* Check to see if a cipher exists and if so add S/MIME capabilities */
+
+static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+{
+    if (EVP_get_cipherbynid(nid))
+        return CMS_add_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
+{
+    if (EVP_get_digestbynid(nid))
+        return CMS_add_simple_smimecap(sk, nid, arg);
+    return 1;
+}
+
+int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
+{
+    if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
+        || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
+        || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
+        || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
+        || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
+        || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
+        return 0;
+    return 1;
+}

+ 836 - 0
libs/openssl/crypto/cms/cms_smime.c

@@ -0,0 +1,836 @@
+/* crypto/cms/cms_smime.c */
+/*
+ * Written by Dr Stephen N Henson ([email protected]) 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
+ *    [email protected].
+ *
+ * 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/x509.h>
+#include <openssl/x509v3.h>
+#include <openssl/err.h>
+#include <openssl/cms.h>
+#include "cms_lcl.h"
+#include "asn1_locl.h"
+
+static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
+{
+    unsigned char buf[4096];
+    int r = 0, i;
+    BIO *tmpout = NULL;
+
+    if (out == NULL)
+        tmpout = BIO_new(BIO_s_null());
+    else if (flags & CMS_TEXT) {
+        tmpout = BIO_new(BIO_s_mem());
+        BIO_set_mem_eof_return(tmpout, 0);
+    } else
+        tmpout = out;
+
+    if (!tmpout) {
+        CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE);
+        goto err;
+    }
+
+    /* Read all content through chain to process digest, decrypt etc */
+    for (;;) {
+        i = BIO_read(in, buf, sizeof(buf));
+        if (i <= 0) {
+            if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
+                if (!BIO_get_cipher_status(in))
+                    goto err;
+            }
+            if (i < 0)
+                goto err;
+            break;
+        }
+
+        if (tmpout && (BIO_write(tmpout, buf, i) != i))
+            goto err;
+    }
+
+    if (flags & CMS_TEXT) {
+        if (!SMIME_text(tmpout, out)) {
+            CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR);
+            goto err;
+        }
+    }
+
+    r = 1;
+
+ err:
+    if (tmpout && (tmpout != out))
+        BIO_free(tmpout);
+    return r;
+
+}
+
+static int check_content(CMS_ContentInfo *cms)
+{
+    ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
+    if (!pos || !*pos) {
+        CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
+        return 0;
+    }
+    return 1;
+}
+
+static void do_free_upto(BIO *f, BIO *upto)
+{
+    if (upto) {
+        BIO *tbio;
+        do {
+            tbio = BIO_pop(f);
+            BIO_free(f);
+            f = tbio;
+        }
+        while (f && f != upto);
+    } else
+        BIO_free_all(f);
+}
+
+int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
+        CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
+        return 0;
+    }
+    cont = CMS_dataInit(cms, NULL);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    BIO_free_all(cont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    cms = cms_Data_create();
+    if (!cms)
+        return NULL;
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+
+    return NULL;
+}
+
+int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                      unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
+        CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    if (r)
+        r = cms_DigestedData_do_final(cms, cont, 1);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
+                                   unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (!md)
+        md = EVP_sha1();
+    cms = cms_DigestedData_create(md);
+    if (!cms)
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
+                              const unsigned char *key, size_t keylen,
+                              BIO *dcont, BIO *out, unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
+               CMS_R_TYPE_NOT_ENCRYPTED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
+        return 0;
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
+                                           const unsigned char *key,
+                                           size_t keylen, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (!cipher) {
+        CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
+        return NULL;
+    }
+    cms = CMS_ContentInfo_new();
+    if (!cms)
+        return NULL;
+    if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
+                                      X509_STORE *store,
+                                      STACK_OF(X509) *certs,
+                                      STACK_OF(X509_CRL) *crls,
+                                      unsigned int flags)
+{
+    X509_STORE_CTX ctx;
+    X509 *signer;
+    int i, j, r = 0;
+    CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+    if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) {
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR);
+        goto err;
+    }
+    X509_STORE_CTX_set_default(&ctx, "smime_sign");
+    if (crls)
+        X509_STORE_CTX_set0_crls(&ctx, crls);
+
+    i = X509_verify_cert(&ctx);
+    if (i <= 0) {
+        j = X509_STORE_CTX_get_error(&ctx);
+        CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
+               CMS_R_CERTIFICATE_VERIFY_ERROR);
+        ERR_add_error_data(2, "Verify error:",
+                           X509_verify_cert_error_string(j));
+        goto err;
+    }
+    r = 1;
+ err:
+    X509_STORE_CTX_cleanup(&ctx);
+    return r;
+
+}
+
+int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
+               X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
+{
+    CMS_SignerInfo *si;
+    STACK_OF(CMS_SignerInfo) *sinfos;
+    STACK_OF(X509) *cms_certs = NULL;
+    STACK_OF(X509_CRL) *crls = NULL;
+    X509 *signer;
+    int i, scount = 0, ret = 0;
+    BIO *cmsbio = NULL, *tmpin = NULL;
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    /* Attempt to find all signer certificates */
+
+    sinfos = CMS_get0_SignerInfos(cms);
+
+    if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
+        goto err;
+    }
+
+    for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+        si = sk_CMS_SignerInfo_value(sinfos, i);
+        CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
+        if (signer)
+            scount++;
+    }
+
+    if (scount != sk_CMS_SignerInfo_num(sinfos))
+        scount += CMS_set1_signers_certs(cms, certs, flags);
+
+    if (scount != sk_CMS_SignerInfo_num(sinfos)) {
+        CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
+        goto err;
+    }
+
+    /* Attempt to verify all signers certs */
+
+    if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
+        cms_certs = CMS_get1_certs(cms);
+        if (!(flags & CMS_NOCRL))
+            crls = CMS_get1_crls(cms);
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (!cms_signerinfo_verify_cert(si, store,
+                                            cms_certs, crls, flags))
+                goto err;
+        }
+    }
+
+    /* Attempt to verify all SignerInfo signed attribute signatures */
+
+    if (!(flags & CMS_NO_ATTR_VERIFY)) {
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (CMS_signed_get_attr_count(si) < 0)
+                continue;
+            if (CMS_SignerInfo_verify(si) <= 0)
+                goto err;
+        }
+    }
+
+    /*
+     * Performance optimization: if the content is a memory BIO then store
+     * its contents in a temporary read only memory BIO. This avoids
+     * potentially large numbers of slow copies of data which will occur when
+     * reading from a read write memory BIO when signatures are calculated.
+     */
+
+    if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
+        char *ptr;
+        long len;
+        len = BIO_get_mem_data(dcont, &ptr);
+        tmpin = BIO_new_mem_buf(ptr, len);
+        if (tmpin == NULL) {
+            CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
+            goto err2;
+        }
+    } else
+        tmpin = dcont;
+
+    cmsbio = CMS_dataInit(cms, tmpin);
+    if (!cmsbio)
+        goto err;
+
+    if (!cms_copy_content(out, cmsbio, flags))
+        goto err;
+
+    if (!(flags & CMS_NO_CONTENT_VERIFY)) {
+        for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
+            si = sk_CMS_SignerInfo_value(sinfos, i);
+            if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
+                CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR);
+                goto err;
+            }
+        }
+    }
+
+    ret = 1;
+
+ err:
+
+    if (dcont && (tmpin == dcont))
+        do_free_upto(cmsbio, dcont);
+    else
+        BIO_free_all(cmsbio);
+
+ err2:
+    if (cms_certs)
+        sk_X509_pop_free(cms_certs, X509_free);
+    if (crls)
+        sk_X509_CRL_pop_free(crls, X509_CRL_free);
+
+    return ret;
+}
+
+int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
+                       STACK_OF(X509) *certs,
+                       X509_STORE *store, unsigned int flags)
+{
+    int r;
+    flags &= ~(CMS_DETACHED | CMS_TEXT);
+    r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
+    if (r <= 0)
+        return r;
+    return cms_Receipt_verify(rcms, ocms);
+}
+
+CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
+                          STACK_OF(X509) *certs, BIO *data,
+                          unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    int i;
+
+    cms = CMS_ContentInfo_new();
+    if (!cms || !CMS_SignedData_init(cms))
+        goto merr;
+
+    if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
+        CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
+        goto err;
+    }
+
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        X509 *x = sk_X509_value(certs, i);
+        if (!CMS_add1_cert(cms, x))
+            goto merr;
+    }
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, data, NULL, flags))
+        return cms;
+    else
+        goto err;
+
+ merr:
+    CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
+
+ err:
+    if (cms)
+        CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
+                                  X509 *signcert, EVP_PKEY *pkey,
+                                  STACK_OF(X509) *certs, unsigned int flags)
+{
+    CMS_SignerInfo *rct_si;
+    CMS_ContentInfo *cms = NULL;
+    ASN1_OCTET_STRING **pos, *os;
+    BIO *rct_cont = NULL;
+    int r = 0;
+
+    flags &= ~(CMS_STREAM | CMS_TEXT);
+    /* Not really detached but avoids content being allocated */
+    flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
+    if (!pkey || !signcert) {
+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
+        return NULL;
+    }
+
+    /* Initialize signed data */
+
+    cms = CMS_sign(NULL, NULL, certs, NULL, flags);
+    if (!cms)
+        goto err;
+
+    /* Set inner content type to signed receipt */
+    if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
+        goto err;
+
+    rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
+    if (!rct_si) {
+        CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
+        goto err;
+    }
+
+    os = cms_encode_Receipt(si);
+
+    if (!os)
+        goto err;
+
+    /* Set content to digest */
+    rct_cont = BIO_new_mem_buf(os->data, os->length);
+    if (!rct_cont)
+        goto err;
+
+    /* Add msgSigDigest attribute */
+
+    if (!cms_msgSigDigest_add1(rct_si, si))
+        goto err;
+
+    /* Finalize structure */
+    if (!CMS_final(cms, rct_cont, NULL, flags))
+        goto err;
+
+    /* Set embedded content */
+    pos = CMS_get0_content(cms);
+    *pos = os;
+
+    r = 1;
+
+ err:
+    if (rct_cont)
+        BIO_free(rct_cont);
+    if (r)
+        return cms;
+    CMS_ContentInfo_free(cms);
+    return NULL;
+
+}
+
+CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
+                             const EVP_CIPHER *cipher, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    int i;
+    X509 *recip;
+    cms = CMS_EnvelopedData_create(cipher);
+    if (!cms)
+        goto merr;
+    for (i = 0; i < sk_X509_num(certs); i++) {
+        recip = sk_X509_value(certs, i);
+        if (!CMS_add1_recipient_cert(cms, recip, flags)) {
+            CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
+            goto err;
+        }
+    }
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & (CMS_STREAM | CMS_PARTIAL))
+        || CMS_final(cms, data, NULL, flags))
+        return cms;
+    else
+        goto err;
+
+ merr:
+    CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
+ err:
+    if (cms)
+        CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
+                              EVP_PKEY *pk, X509 *cert)
+{
+    int i;
+    STACK_OF(CMS_RecipientEncryptedKey) *reks;
+    CMS_RecipientEncryptedKey *rek;
+    reks = CMS_RecipientInfo_kari_get0_reks(ri);
+    if (!cert)
+        return 0;
+    for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
+        int rv;
+        rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
+        if (CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
+            continue;
+        CMS_RecipientInfo_kari_set0_pkey(ri, pk);
+        rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
+        CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
+        if (rv > 0)
+            return 1;
+        return -1;
+    }
+    return 0;
+}
+
+int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r, ri_type;
+    int debug = 0, match_ri = 0;
+    ris = CMS_get0_RecipientInfos(cms);
+    if (ris)
+        debug = cms->d.envelopedData->encryptedContentInfo->debug;
+    ri_type = cms_pkey_get_ri_type(pk);
+    if (ri_type == CMS_RECIPINFO_NONE) {
+        CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
+               CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
+        return 0;
+    }
+
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != ri_type)
+            continue;
+        match_ri = 1;
+        if (ri_type == CMS_RECIPINFO_AGREE) {
+            r = cms_kari_set1_pkey(cms, ri, pk, cert);
+            if (r > 0)
+                return 1;
+            if (r < 0)
+                return 0;
+        }
+        /*
+         * If we have a cert try matching RecipientInfo otherwise try them
+         * all.
+         */
+        else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
+            CMS_RecipientInfo_set0_pkey(ri, pk);
+            r = CMS_RecipientInfo_decrypt(cms, ri);
+            CMS_RecipientInfo_set0_pkey(ri, NULL);
+            if (cert) {
+                /*
+                 * If not debugging clear any error and return success to
+                 * avoid leaking of information useful to MMA
+                 */
+                if (!debug) {
+                    ERR_clear_error();
+                    return 1;
+                }
+                if (r > 0)
+                    return 1;
+                CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR);
+                return 0;
+            }
+            /*
+             * If no cert and not debugging don't leave loop after first
+             * successful decrypt. Always attempt to decrypt all recipients
+             * to avoid leaking timing of a successful decrypt.
+             */
+            else if (r > 0 && debug)
+                return 1;
+        }
+    }
+    /* If no cert and not debugging always return success */
+    if (match_ri && !cert && !debug) {
+        ERR_clear_error();
+        return 1;
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
+                         unsigned char *key, size_t keylen,
+                         unsigned char *id, size_t idlen)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r;
+    ris = CMS_get0_RecipientInfos(cms);
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
+            continue;
+
+        /*
+         * If we have an id try matching RecipientInfo otherwise try them
+         * all.
+         */
+        if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
+            CMS_RecipientInfo_set0_key(ri, key, keylen);
+            r = CMS_RecipientInfo_decrypt(cms, ri);
+            CMS_RecipientInfo_set0_key(ri, NULL, 0);
+            if (r > 0)
+                return 1;
+            if (id) {
+                CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
+                return 0;
+            }
+            ERR_clear_error();
+        }
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
+                              unsigned char *pass, ossl_ssize_t passlen)
+{
+    STACK_OF(CMS_RecipientInfo) *ris;
+    CMS_RecipientInfo *ri;
+    int i, r;
+    ris = CMS_get0_RecipientInfos(cms);
+    for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
+        ri = sk_CMS_RecipientInfo_value(ris, i);
+        if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
+            continue;
+        CMS_RecipientInfo_set0_password(ri, pass, passlen);
+        r = CMS_RecipientInfo_decrypt(cms, ri);
+        CMS_RecipientInfo_set0_password(ri, NULL, 0);
+        if (r > 0)
+            return 1;
+    }
+
+    CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
+    return 0;
+
+}
+
+int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
+                BIO *dcont, BIO *out, unsigned int flags)
+{
+    int r;
+    BIO *cont;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) {
+        CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
+        return 0;
+    }
+    if (!dcont && !check_content(cms))
+        return 0;
+    if (flags & CMS_DEBUG_DECRYPT)
+        cms->d.envelopedData->encryptedContentInfo->debug = 1;
+    else
+        cms->d.envelopedData->encryptedContentInfo->debug = 0;
+    if (!pk && !cert && !dcont && !out)
+        return 1;
+    if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
+        return 0;
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
+{
+    BIO *cmsbio;
+    int ret = 0;
+    if (!(cmsbio = CMS_dataInit(cms, dcont))) {
+        CMSerr(CMS_F_CMS_FINAL, ERR_R_MALLOC_FAILURE);
+        return 0;
+    }
+
+    SMIME_crlf_copy(data, cmsbio, flags);
+
+    (void)BIO_flush(cmsbio);
+
+    if (!CMS_dataFinal(cms, cmsbio)) {
+        CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
+        goto err;
+    }
+
+    ret = 1;
+
+ err:
+    do_free_upto(cmsbio, dcont);
+
+    return ret;
+
+}
+
+#ifdef ZLIB
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags)
+{
+    BIO *cont;
+    int r;
+    if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
+        CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
+        return 0;
+    }
+
+    if (!dcont && !check_content(cms))
+        return 0;
+
+    cont = CMS_dataInit(cms, dcont);
+    if (!cont)
+        return 0;
+    r = cms_copy_content(out, cont, flags);
+    do_free_upto(cont, dcont);
+    return r;
+}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+{
+    CMS_ContentInfo *cms;
+    if (comp_nid <= 0)
+        comp_nid = NID_zlib_compression;
+    cms = cms_CompressedData_create(comp_nid);
+    if (!cms)
+        return NULL;
+
+    if (!(flags & CMS_DETACHED))
+        CMS_set_detached(cms, 0);
+
+    if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
+        return cms;
+
+    CMS_ContentInfo_free(cms);
+    return NULL;
+}
+
+#else
+
+int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
+                   unsigned int flags)
+{
+    CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+    return 0;
+}
+
+CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
+{
+    CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+    return NULL;
+}
+
+#endif

+ 30 - 5
libs/openssl/crypto/cryptlib.c

@@ -653,7 +653,7 @@ const char *CRYPTO_get_lock_name(int type)
         defined(__x86_64) || defined(__x86_64__) || \
         defined(_M_AMD64) || defined(_M_X64)
 
-unsigned int OPENSSL_ia32cap_P[2];
+extern unsigned int OPENSSL_ia32cap_P[4];
 unsigned long *OPENSSL_ia32cap_loc(void)
 {
     if (sizeof(long) == 4)
@@ -663,6 +663,9 @@ unsigned long *OPENSSL_ia32cap_loc(void)
          * is 32-bit.
          */
         OPENSSL_ia32cap_P[1] = 0;
+
+    OPENSSL_ia32cap_P[2] = 0;
+
     return (unsigned long *)OPENSSL_ia32cap_P;
 }
 
@@ -676,7 +679,7 @@ typedef unsigned long long IA32CAP;
 void OPENSSL_cpuid_setup(void)
 {
     static int trigger = 0;
-    IA32CAP OPENSSL_ia32_cpuid(void);
+    IA32CAP OPENSSL_ia32_cpuid(unsigned int *);
     IA32CAP vec;
     char *env;
 
@@ -694,9 +697,23 @@ void OPENSSL_cpuid_setup(void)
             vec = strtoul(env + off, NULL, 0);
 #  endif
         if (off)
-            vec = OPENSSL_ia32_cpuid() & ~vec;
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P) & ~vec;
+        else if (env[0] == ':')
+            vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
+
+        OPENSSL_ia32cap_P[2] = 0;
+        if ((env = strchr(env, ':'))) {
+            unsigned int vecx;
+            env++;
+            off = (env[0] == '~') ? 1 : 0;
+            vecx = strtoul(env + off, NULL, 0);
+            if (off)
+                OPENSSL_ia32cap_P[2] &= ~vecx;
+            else
+                OPENSSL_ia32cap_P[2] = vecx;
+        }
     } else
-        vec = OPENSSL_ia32_cpuid();
+        vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
 
     /*
      * |(1<<10) sets a reserved bit to signal that variable
@@ -706,6 +723,8 @@ void OPENSSL_cpuid_setup(void)
     OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10);
     OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32);
 }
+# else
+unsigned int OPENSSL_ia32cap_P[4];
 # endif
 
 #else
@@ -857,8 +876,12 @@ void OPENSSL_showfatal(const char *fmta, ...)
     if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL &&
         GetFileType(h) != FILE_TYPE_UNKNOWN) {
         /* must be console application */
+        int len;
+        DWORD out;
+
         va_start(ap, fmta);
-        vfprintf(stderr, fmta, ap);
+        len = _vsnprintf((char *)buf, sizeof(buf), fmta, ap);
+        WriteFile(h, buf, len < 0 ? sizeof(buf) : (DWORD) len, &out, NULL);
         va_end(ap);
         return;
     }
@@ -965,7 +988,9 @@ void OpenSSLDie(const char *file, int line, const char *assertion)
     /*
      * Win32 abort() customarily shows a dialog, but we just did that...
      */
+# if !defined(_WIN32_WCE)
     raise(SIGABRT);
+# endif
     _exit(3);
 #endif
 }

+ 4 - 0
libs/openssl/crypto/cversion.c

@@ -68,7 +68,11 @@ const char *SSLeay_version(int t)
         return OPENSSL_VERSION_TEXT;
     if (t == SSLEAY_BUILT_ON) {
 #ifdef DATE
+# ifdef OPENSSL_USE_BUILD_DATE
         return (DATE);
+# else
+        return ("built on: reproducible build, date unspecified");
+# endif
 #else
         return ("built on: date not available");
 #endif

+ 3 - 2
libs/openssl/crypto/des/asm/d_win32.asm

@@ -1001,7 +1001,7 @@ L$_DES_encrypt1_begin:
 	call	L$000pic_point
 L$000pic_point:
 	pop	ebp
-	lea	ebp,[(_DES_SPtrans-L$000pic_point)+ebp]
+	lea	ebp,[(L$des_sptrans-L$000pic_point)+ebp]
 	mov	ecx,DWORD [24+esp]
 	cmp	ebx,0
 	je	NEAR L$001decrypt
@@ -1076,7 +1076,7 @@ L$_DES_encrypt2_begin:
 	call	L$003pic_point
 L$003pic_point:
 	pop	ebp
-	lea	ebp,[(_DES_SPtrans-L$003pic_point)+ebp]
+	lea	ebp,[(L$des_sptrans-L$003pic_point)+ebp]
 	mov	ecx,DWORD [24+esp]
 	cmp	ebx,0
 	je	NEAR L$004decrypt
@@ -1697,6 +1697,7 @@ dd	L$036ej7-L$034PIC_point
 align	64
 align	64
 _DES_SPtrans:
+L$des_sptrans:
 dd	34080768,524288,33554434,34080770
 dd	33554432,526338,524290,33554434
 dd	526338,34080768,34078720,2050

+ 3 - 1
libs/openssl/crypto/des/des_locl.h

@@ -162,8 +162,10 @@
                                 } \
                         }
 
-# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC)
+# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER))
 #  define ROTATE(a,n)     (_lrotr(a,n))
+# elif defined(__ICC)
+#  define ROTATE(a,n)     (_rotr(a,n))
 # elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC)
 #  if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
 #   define ROTATE(a,n)   ({ register unsigned int ret;   \

+ 105 - 0
libs/openssl/crypto/dh/dh.h

@@ -167,6 +167,9 @@ struct dh_st {
 # define DH_CHECK_P_NOT_SAFE_PRIME       0x02
 # define DH_UNABLE_TO_CHECK_GENERATOR    0x04
 # define DH_NOT_SUITABLE_GENERATOR       0x08
+# define DH_CHECK_Q_NOT_PRIME            0x10
+# define DH_CHECK_INVALID_Q_VALUE        0x20
+# define DH_CHECK_INVALID_J_VALUE        0x40
 
 /* DH_check_pub_key error codes */
 # define DH_CHECK_PUBKEY_TOO_SMALL       0x01
@@ -217,8 +220,11 @@ int DH_check(const DH *dh, int *codes);
 int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes);
 int DH_generate_key(DH *dh);
 int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh);
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh);
 DH *d2i_DHparams(DH **a, const unsigned char **pp, long length);
 int i2d_DHparams(const DH *a, unsigned char **pp);
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length);
+int i2d_DHxparams(const DH *a, unsigned char **pp);
 # ifndef OPENSSL_NO_FP_API
 int DHparams_print_fp(FILE *fp, const DH *x);
 # endif
@@ -228,16 +234,109 @@ int DHparams_print(BIO *bp, const DH *x);
 int DHparams_print(char *bp, const DH *x);
 # endif
 
+/* RFC 5114 parameters */
+DH *DH_get_1024_160(void);
+DH *DH_get_2048_224(void);
+DH *DH_get_2048_256(void);
+
+/* RFC2631 KDF */
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md);
+
 # define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \
         EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                         EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL)
 
+# define EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN, len, NULL)
+
+# define EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_PARAMGEN_TYPE, typ, NULL)
+
 # define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \
         EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \
                         EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL)
 
+# define EVP_PKEY_CTX_set_dh_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dhx_rfc5114(ctx, gen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, EVP_PKEY_OP_PARAMGEN, \
+                        EVP_PKEY_CTRL_DH_RFC5114, gen, NULL)
+
+# define EVP_PKEY_CTX_set_dh_kdf_type(ctx, kdf) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, kdf, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_type(ctx) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_TYPE, -2, NULL)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_oid(ctx, oid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OID, 0, (void *)oid)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_oid(ctx, poid) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_OID, 0, (void *)poid)
+
+# define EVP_PKEY_CTX_set_dh_kdf_md(ctx, md) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_MD, 0, (void *)md)
+
+# define EVP_PKEY_CTX_get_dh_kdf_md(ctx, pmd) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_MD, 0, (void *)pmd)
+
+# define EVP_PKEY_CTX_set_dh_kdf_outlen(ctx, len) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_OUTLEN, len, NULL)
+
+# define EVP_PKEY_CTX_get_dh_kdf_outlen(ctx, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                        EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN, 0, (void *)plen)
+
+# define EVP_PKEY_CTX_set0_dh_kdf_ukm(ctx, p, plen) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_DH_KDF_UKM, plen, (void *)p)
+
+# define EVP_PKEY_CTX_get0_dh_kdf_ukm(ctx, p) \
+        EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DHX, \
+                                EVP_PKEY_OP_DERIVE, \
+                                EVP_PKEY_CTRL_GET_DH_KDF_UKM, 0, (void *)p)
+
 # define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN     (EVP_PKEY_ALG_CTRL + 1)
 # define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR     (EVP_PKEY_ALG_CTRL + 2)
+# define EVP_PKEY_CTRL_DH_RFC5114                (EVP_PKEY_ALG_CTRL + 3)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN  (EVP_PKEY_ALG_CTRL + 4)
+# define EVP_PKEY_CTRL_DH_PARAMGEN_TYPE          (EVP_PKEY_ALG_CTRL + 5)
+# define EVP_PKEY_CTRL_DH_KDF_TYPE               (EVP_PKEY_ALG_CTRL + 6)
+# define EVP_PKEY_CTRL_DH_KDF_MD                 (EVP_PKEY_ALG_CTRL + 7)
+# define EVP_PKEY_CTRL_GET_DH_KDF_MD             (EVP_PKEY_ALG_CTRL + 8)
+# define EVP_PKEY_CTRL_DH_KDF_OUTLEN             (EVP_PKEY_ALG_CTRL + 9)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN         (EVP_PKEY_ALG_CTRL + 10)
+# define EVP_PKEY_CTRL_DH_KDF_UKM                (EVP_PKEY_ALG_CTRL + 11)
+# define EVP_PKEY_CTRL_GET_DH_KDF_UKM            (EVP_PKEY_ALG_CTRL + 12)
+# define EVP_PKEY_CTRL_DH_KDF_OID                (EVP_PKEY_ALG_CTRL + 13)
+# define EVP_PKEY_CTRL_GET_DH_KDF_OID            (EVP_PKEY_ALG_CTRL + 14)
+
+/* KDF types */
+# define EVP_PKEY_DH_KDF_NONE                            1
+# define EVP_PKEY_DH_KDF_X9_42                           2
 
 /* BEGIN ERROR CODES */
 /*
@@ -252,6 +351,9 @@ void ERR_load_DH_strings(void);
 # define DH_F_COMPUTE_KEY                                 102
 # define DH_F_DHPARAMS_PRINT_FP                           101
 # define DH_F_DH_BUILTIN_GENPARAMS                        106
+# define DH_F_DH_CMS_DECRYPT                              117
+# define DH_F_DH_CMS_SET_PEERKEY                          118
+# define DH_F_DH_CMS_SET_SHARED_INFO                      119
 # define DH_F_DH_COMPUTE_KEY                              114
 # define DH_F_DH_GENERATE_KEY                             115
 # define DH_F_DH_GENERATE_PARAMETERS_EX                   116
@@ -273,6 +375,7 @@ void ERR_load_DH_strings(void);
 # define DH_R_BN_ERROR                                    106
 # define DH_R_DECODE_ERROR                                104
 # define DH_R_INVALID_PUBKEY                              102
+# define DH_R_KDF_PARAMETER_ERROR                         112
 # define DH_R_KEYS_NOT_SET                                108
 # define DH_R_KEY_SIZE_TOO_SMALL                          110
 # define DH_R_MODULUS_TOO_LARGE                           103
@@ -280,6 +383,8 @@ void ERR_load_DH_strings(void);
 # define DH_R_NO_PARAMETERS_SET                           107
 # define DH_R_NO_PRIVATE_VALUE                            100
 # define DH_R_PARAMETER_ENCODING_ERROR                    105
+# define DH_R_PEER_KEY_ERROR                              113
+# define DH_R_SHARED_INFO_ERROR                           114
 
 #ifdef  __cplusplus
 }

+ 492 - 27
libs/openssl/crypto/dh/dh_ameth.c

@@ -63,6 +63,31 @@
 #include <openssl/dh.h>
 #include <openssl/bn.h>
 #include "asn1_locl.h"
+#ifndef OPENSSL_NO_CMS
+# include <openssl/cms.h>
+#endif
+
+extern const EVP_PKEY_ASN1_METHOD dhx_asn1_meth;
+
+/*
+ * i2d/d2i like DH parameter functions which use the appropriate routine for
+ * PKCS#3 DH or X9.42 DH.
+ */
+
+static DH *d2i_dhp(const EVP_PKEY *pkey, const unsigned char **pp,
+                   long length)
+{
+    if (pkey->ameth == &dhx_asn1_meth)
+        return d2i_DHxparams(NULL, pp, length);
+    return d2i_DHparams(NULL, pp, length);
+}
+
+static int i2d_dhp(const EVP_PKEY *pkey, const DH *a, unsigned char **pp)
+{
+    if (pkey->ameth == &dhx_asn1_meth)
+        return i2d_DHxparams(a, pp);
+    return i2d_DHparams(a, pp);
+}
 
 static void int_dh_free(EVP_PKEY *pkey)
 {
@@ -94,7 +119,7 @@ static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
     pm = pstr->data;
     pmlen = pstr->length;
 
-    if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) {
+    if (!(dh = d2i_dhp(pkey, &pm, pmlen))) {
         DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR);
         goto err;
     }
@@ -111,7 +136,7 @@ static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
     }
 
     ASN1_INTEGER_free(public_key);
-    EVP_PKEY_assign_DH(pkey, dh);
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
     return 1;
 
  err:
@@ -139,7 +164,7 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
         DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
         goto err;
     }
-    str->length = i2d_DHparams(dh, &str->data);
+    str->length = i2d_dhp(pkey, dh, &str->data);
     if (str->length <= 0) {
         DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
         goto err;
@@ -159,7 +184,7 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
         goto err;
     }
 
-    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH),
+    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(pkey->ameth->pkey_id),
                                ptype, str, penc, penclen))
         return 1;
 
@@ -204,7 +229,7 @@ static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
     pstr = pval;
     pm = pstr->data;
     pmlen = pstr->length;
-    if (!(dh = d2i_DHparams(NULL, &pm, pmlen)))
+    if (!(dh = d2i_dhp(pkey, &pm, pmlen)))
         goto decerr;
     /* We have parameters now set private key */
     if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
@@ -215,7 +240,7 @@ static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
     if (!DH_generate_key(dh))
         goto dherr;
 
-    EVP_PKEY_assign_DH(pkey, dh);
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
 
     ASN1_STRING_clear_free(privkey);
 
@@ -243,7 +268,7 @@ static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
         goto err;
     }
 
-    params->length = i2d_DHparams(pkey->pkey.dh, &params->data);
+    params->length = i2d_dhp(pkey, pkey->pkey.dh, &params->data);
     if (params->length <= 0) {
         DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
         goto err;
@@ -263,7 +288,7 @@ static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
     ASN1_STRING_clear_free(prkey);
     prkey = NULL;
 
-    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0,
+    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(pkey->ameth->pkey_id), 0,
                          V_ASN1_SEQUENCE, params, dp, dplen))
         goto err;
 
@@ -292,17 +317,17 @@ static int dh_param_decode(EVP_PKEY *pkey,
                            const unsigned char **pder, int derlen)
 {
     DH *dh;
-    if (!(dh = d2i_DHparams(NULL, pder, derlen))) {
+    if (!(dh = d2i_dhp(pkey, pder, derlen))) {
         DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB);
         return 0;
     }
-    EVP_PKEY_assign_DH(pkey, dh);
+    EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh);
     return 1;
 }
 
 static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
 {
-    return i2d_DHparams(pkey->pkey.dh, pder);
+    return i2d_dhp(pkey, pkey->pkey.dh, pder);
 }
 
 static int do_dh_print(BIO *bp, const DH *x, int indent,
@@ -334,15 +359,18 @@ static int do_dh_print(BIO *bp, const DH *x, int indent,
     }
 
     update_buflen(x->g, &buf_len);
+    update_buflen(x->q, &buf_len);
+    update_buflen(x->j, &buf_len);
+    update_buflen(x->counter, &buf_len);
     update_buflen(pub_key, &buf_len);
     update_buflen(priv_key, &buf_len);
 
     if (ptype == 2)
-        ktype = "PKCS#3 DH Private-Key";
+        ktype = "DH Private-Key";
     else if (ptype == 1)
-        ktype = "PKCS#3 DH Public-Key";
+        ktype = "DH Public-Key";
     else
-        ktype = "PKCS#3 DH Parameters";
+        ktype = "DH Parameters";
 
     m = OPENSSL_malloc(buf_len + 10);
     if (m == NULL) {
@@ -364,6 +392,29 @@ static int do_dh_print(BIO *bp, const DH *x, int indent,
         goto err;
     if (!ASN1_bn_print(bp, "generator:", x->g, m, indent))
         goto err;
+    if (x->q && !ASN1_bn_print(bp, "subgroup order:", x->q, m, indent))
+        goto err;
+    if (x->j && !ASN1_bn_print(bp, "subgroup factor:", x->j, m, indent))
+        goto err;
+    if (x->seed) {
+        int i;
+        BIO_indent(bp, indent, 128);
+        BIO_puts(bp, "seed:");
+        for (i = 0; i < x->seedlen; i++) {
+            if ((i % 15) == 0) {
+                if (BIO_puts(bp, "\n") <= 0
+                    || !BIO_indent(bp, indent + 4, 128))
+                    goto err;
+            }
+            if (BIO_printf(bp, "%02x%s", x->seed[i],
+                           ((i + 1) == x->seedlen) ? "" : ":") <= 0)
+                goto err;
+        }
+        if (BIO_write(bp, "\n", 1) <= 0)
+            return (0);
+    }
+    if (x->counter && !ASN1_bn_print(bp, "counter:", x->counter, m, indent))
+        goto err;
     if (x->length != 0) {
         BIO_indent(bp, indent, 128);
         if (BIO_printf(bp, "recommended-private-length: %d bits\n",
@@ -396,29 +447,76 @@ static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
     if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) ||
         BN_cmp(a->pkey.dh->g, b->pkey.dh->g))
         return 0;
-    else
-        return 1;
+    else if (a->ameth == &dhx_asn1_meth) {
+        if (BN_cmp(a->pkey.dh->q, b->pkey.dh->q))
+            return 0;
+    }
+    return 1;
 }
 
-static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src)
 {
     BIGNUM *a;
+    if (src) {
+        a = BN_dup(src);
+        if (!a)
+            return 0;
+    } else
+        a = NULL;
+    if (*dst)
+        BN_free(*dst);
+    *dst = a;
+    return 1;
+}
 
-    if ((a = BN_dup(from->pkey.dh->p)) == NULL)
+static int int_dh_param_copy(DH *to, const DH *from, int is_x942)
+{
+    if (is_x942 == -1)
+        is_x942 = ! !from->q;
+    if (!int_dh_bn_cpy(&to->p, from->p))
         return 0;
-    if (to->pkey.dh->p != NULL)
-        BN_free(to->pkey.dh->p);
-    to->pkey.dh->p = a;
-
-    if ((a = BN_dup(from->pkey.dh->g)) == NULL)
+    if (!int_dh_bn_cpy(&to->g, from->g))
         return 0;
-    if (to->pkey.dh->g != NULL)
-        BN_free(to->pkey.dh->g);
-    to->pkey.dh->g = a;
-
+    if (is_x942) {
+        if (!int_dh_bn_cpy(&to->q, from->q))
+            return 0;
+        if (!int_dh_bn_cpy(&to->j, from->j))
+            return 0;
+        if (to->seed) {
+            OPENSSL_free(to->seed);
+            to->seed = NULL;
+            to->seedlen = 0;
+        }
+        if (from->seed) {
+            to->seed = BUF_memdup(from->seed, from->seedlen);
+            if (!to->seed)
+                return 0;
+            to->seedlen = from->seedlen;
+        }
+    } else
+        to->length = from->length;
     return 1;
 }
 
+DH *DHparams_dup(DH *dh)
+{
+    DH *ret;
+    ret = DH_new();
+    if (!ret)
+        return NULL;
+    if (!int_dh_param_copy(ret, dh, -1)) {
+        DH_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
+{
+    return int_dh_param_copy(to->pkey.dh, from->pkey.dh,
+                             from->ameth == &dhx_asn1_meth);
+}
+
 static int dh_missing_parameters(const EVP_PKEY *a)
 {
     if (!a->pkey.dh->p || !a->pkey.dh->g)
@@ -459,6 +557,33 @@ int DHparams_print(BIO *bp, const DH *x)
     return do_dh_print(bp, x, 4, NULL, 0);
 }
 
+#ifndef OPENSSL_NO_CMS
+static int dh_cms_decrypt(CMS_RecipientInfo *ri);
+static int dh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
+
+static int dh_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
+{
+    switch (op) {
+#ifndef OPENSSL_NO_CMS
+
+    case ASN1_PKEY_CTRL_CMS_ENVELOPE:
+        if (arg1 == 1)
+            return dh_cms_decrypt(arg2);
+        else if (arg1 == 0)
+            return dh_cms_encrypt(arg2);
+        return -2;
+
+    case ASN1_PKEY_CTRL_CMS_RI_TYPE:
+        *(int *)arg2 = CMS_RECIPINFO_AGREE;
+        return 1;
+#endif
+    default:
+        return -2;
+    }
+
+}
+
 const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
     EVP_PKEY_DH,
     EVP_PKEY_DH,
@@ -490,3 +615,343 @@ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
     int_dh_free,
     0
 };
+
+const EVP_PKEY_ASN1_METHOD dhx_asn1_meth = {
+    EVP_PKEY_DHX,
+    EVP_PKEY_DHX,
+    0,
+
+    "X9.42 DH",
+    "OpenSSL X9.42 DH method",
+
+    dh_pub_decode,
+    dh_pub_encode,
+    dh_pub_cmp,
+    dh_public_print,
+
+    dh_priv_decode,
+    dh_priv_encode,
+    dh_private_print,
+
+    int_dh_size,
+    dh_bits,
+
+    dh_param_decode,
+    dh_param_encode,
+    dh_missing_parameters,
+    dh_copy_parameters,
+    dh_cmp_parameters,
+    dh_param_print,
+    0,
+
+    int_dh_free,
+    dh_pkey_ctrl
+};
+
+#ifndef OPENSSL_NO_CMS
+
+static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+                              X509_ALGOR *alg, ASN1_BIT_STRING *pubkey)
+{
+    ASN1_OBJECT *aoid;
+    int atype;
+    void *aval;
+    ASN1_INTEGER *public_key = NULL;
+    int rv = 0;
+    EVP_PKEY *pkpeer = NULL, *pk = NULL;
+    DH *dhpeer = NULL;
+    const unsigned char *p;
+    int plen;
+
+    X509_ALGOR_get0(&aoid, &atype, &aval, alg);
+    if (OBJ_obj2nid(aoid) != NID_dhpublicnumber)
+        goto err;
+    /* Only absent parameters allowed in RFC XXXX */
+    if (atype != V_ASN1_UNDEF && atype == V_ASN1_NULL)
+        goto err;
+
+    pk = EVP_PKEY_CTX_get0_pkey(pctx);
+    if (!pk)
+        goto err;
+    if (pk->type != EVP_PKEY_DHX)
+        goto err;
+    /* Get parameters from parent key */
+    dhpeer = DHparams_dup(pk->pkey.dh);
+    /* We have parameters now set public key */
+    plen = ASN1_STRING_length(pubkey);
+    p = ASN1_STRING_data(pubkey);
+    if (!p || !plen)
+        goto err;
+
+    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, plen))) {
+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_DECODE_ERROR);
+        goto err;
+    }
+
+    /* We have parameters now set public key */
+    if (!(dhpeer->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
+        DHerr(DH_F_DH_CMS_SET_PEERKEY, DH_R_BN_DECODE_ERROR);
+        goto err;
+    }
+
+    pkpeer = EVP_PKEY_new();
+    if (!pkpeer)
+        goto err;
+    EVP_PKEY_assign(pkpeer, pk->ameth->pkey_id, dhpeer);
+    dhpeer = NULL;
+    if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0)
+        rv = 1;
+ err:
+    if (public_key)
+        ASN1_INTEGER_free(public_key);
+    if (pkpeer)
+        EVP_PKEY_free(pkpeer);
+    if (dhpeer)
+        DH_free(dhpeer);
+    return rv;
+}
+
+static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri)
+{
+    int rv = 0;
+
+    X509_ALGOR *alg, *kekalg = NULL;
+    ASN1_OCTET_STRING *ukm;
+    const unsigned char *p;
+    unsigned char *dukm = NULL;
+    size_t dukmlen = 0;
+    int keylen, plen;
+    const EVP_CIPHER *kekcipher;
+    EVP_CIPHER_CTX *kekctx;
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &alg, &ukm))
+        goto err;
+
+    /*
+     * For DH we only have one OID permissible. If ever any more get defined
+     * we will need something cleverer.
+     */
+    if (OBJ_obj2nid(alg->algorithm) != NID_id_smime_alg_ESDH) {
+        DHerr(DH_F_DH_CMS_SET_SHARED_INFO, DH_R_KDF_PARAMETER_ERROR);
+        goto err;
+    }
+
+    if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, EVP_PKEY_DH_KDF_X9_42) <= 0)
+        goto err;
+
+    if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, EVP_sha1()) <= 0)
+        goto err;
+
+    if (alg->parameter->type != V_ASN1_SEQUENCE)
+        goto err;
+
+    p = alg->parameter->value.sequence->data;
+    plen = alg->parameter->value.sequence->length;
+    kekalg = d2i_X509_ALGOR(NULL, &p, plen);
+    if (!kekalg)
+        goto err;
+    kekctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    if (!kekctx)
+        goto err;
+    kekcipher = EVP_get_cipherbyobj(kekalg->algorithm);
+    if (!kekcipher || EVP_CIPHER_mode(kekcipher) != EVP_CIPH_WRAP_MODE)
+        goto err;
+    if (!EVP_EncryptInit_ex(kekctx, kekcipher, NULL, NULL, NULL))
+        goto err;
+    if (EVP_CIPHER_asn1_to_param(kekctx, kekalg->parameter) <= 0)
+        goto err;
+
+    keylen = EVP_CIPHER_CTX_key_length(kekctx);
+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+    /* Use OBJ_nid2obj to ensure we use built in OID that isn't freed */
+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx,
+                                     OBJ_nid2obj(EVP_CIPHER_type(kekcipher)))
+        <= 0)
+        goto err;
+
+    if (ukm) {
+        dukmlen = ASN1_STRING_length(ukm);
+        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
+        if (!dukm)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+        goto err;
+    dukm = NULL;
+
+    rv = 1;
+ err:
+    if (kekalg)
+        X509_ALGOR_free(kekalg);
+    if (dukm)
+        OPENSSL_free(dukm);
+    return rv;
+}
+
+static int dh_cms_decrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* See if we need to set peer key */
+    if (!EVP_PKEY_CTX_get0_peerkey(pctx)) {
+        X509_ALGOR *alg;
+        ASN1_BIT_STRING *pubkey;
+        if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &alg, &pubkey,
+                                                 NULL, NULL, NULL))
+            return 0;
+        if (!alg || !pubkey)
+            return 0;
+        if (!dh_cms_set_peerkey(pctx, alg, pubkey)) {
+            DHerr(DH_F_DH_CMS_DECRYPT, DH_R_PEER_KEY_ERROR);
+            return 0;
+        }
+    }
+    /* Set DH derivation parameters and initialise unwrap context */
+    if (!dh_cms_set_shared_info(pctx, ri)) {
+        DHerr(DH_F_DH_CMS_DECRYPT, DH_R_SHARED_INFO_ERROR);
+        return 0;
+    }
+    return 1;
+}
+
+static int dh_cms_encrypt(CMS_RecipientInfo *ri)
+{
+    EVP_PKEY_CTX *pctx;
+    EVP_PKEY *pkey;
+    EVP_CIPHER_CTX *ctx;
+    int keylen;
+    X509_ALGOR *talg, *wrap_alg = NULL;
+    ASN1_OBJECT *aoid;
+    ASN1_BIT_STRING *pubkey;
+    ASN1_STRING *wrap_str;
+    ASN1_OCTET_STRING *ukm;
+    unsigned char *penc = NULL, *dukm = NULL;
+    int penclen;
+    size_t dukmlen = 0;
+    int rv = 0;
+    int kdf_type, wrap_nid;
+    const EVP_MD *kdf_md;
+    pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
+    if (!pctx)
+        return 0;
+    /* Get ephemeral key */
+    pkey = EVP_PKEY_CTX_get0_pkey(pctx);
+    if (!CMS_RecipientInfo_kari_get0_orig_id(ri, &talg, &pubkey,
+                                             NULL, NULL, NULL))
+        goto err;
+    X509_ALGOR_get0(&aoid, NULL, NULL, talg);
+    /* Is everything uninitialised? */
+    if (aoid == OBJ_nid2obj(NID_undef)) {
+        ASN1_INTEGER *pubk;
+        pubk = BN_to_ASN1_INTEGER(pkey->pkey.dh->pub_key, NULL);
+        if (!pubk)
+            goto err;
+        /* Set the key */
+
+        penclen = i2d_ASN1_INTEGER(pubk, &penc);
+        ASN1_INTEGER_free(pubk);
+        if (penclen <= 0)
+            goto err;
+        ASN1_STRING_set0(pubkey, penc, penclen);
+        pubkey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
+        pubkey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
+
+        penc = NULL;
+        X509_ALGOR_set0(talg, OBJ_nid2obj(NID_dhpublicnumber),
+                        V_ASN1_UNDEF, NULL);
+    }
+
+    /* See if custom paraneters set */
+    kdf_type = EVP_PKEY_CTX_get_dh_kdf_type(pctx);
+    if (kdf_type <= 0)
+        goto err;
+    if (!EVP_PKEY_CTX_get_dh_kdf_md(pctx, &kdf_md))
+        goto err;
+
+    if (kdf_type == EVP_PKEY_DH_KDF_NONE) {
+        kdf_type = EVP_PKEY_DH_KDF_X9_42;
+        if (EVP_PKEY_CTX_set_dh_kdf_type(pctx, kdf_type) <= 0)
+            goto err;
+    } else if (kdf_type != EVP_PKEY_DH_KDF_X9_42)
+        /* Unknown KDF */
+        goto err;
+    if (kdf_md == NULL) {
+        /* Only SHA1 supported */
+        kdf_md = EVP_sha1();
+        if (EVP_PKEY_CTX_set_dh_kdf_md(pctx, kdf_md) <= 0)
+            goto err;
+    } else if (EVP_MD_type(kdf_md) != NID_sha1)
+        /* Unsupported digest */
+        goto err;
+
+    if (!CMS_RecipientInfo_kari_get0_alg(ri, &talg, &ukm))
+        goto err;
+
+    /* Get wrap NID */
+    ctx = CMS_RecipientInfo_kari_get0_ctx(ri);
+    wrap_nid = EVP_CIPHER_CTX_type(ctx);
+    if (EVP_PKEY_CTX_set0_dh_kdf_oid(pctx, OBJ_nid2obj(wrap_nid)) <= 0)
+        goto err;
+    keylen = EVP_CIPHER_CTX_key_length(ctx);
+
+    /* Package wrap algorithm in an AlgorithmIdentifier */
+
+    wrap_alg = X509_ALGOR_new();
+    if (!wrap_alg)
+        goto err;
+    wrap_alg->algorithm = OBJ_nid2obj(wrap_nid);
+    wrap_alg->parameter = ASN1_TYPE_new();
+    if (!wrap_alg->parameter)
+        goto err;
+    if (EVP_CIPHER_param_to_asn1(ctx, wrap_alg->parameter) <= 0)
+        goto err;
+    if (ASN1_TYPE_get(wrap_alg->parameter) == NID_undef) {
+        ASN1_TYPE_free(wrap_alg->parameter);
+        wrap_alg->parameter = NULL;
+    }
+
+    if (EVP_PKEY_CTX_set_dh_kdf_outlen(pctx, keylen) <= 0)
+        goto err;
+
+    if (ukm) {
+        dukmlen = ASN1_STRING_length(ukm);
+        dukm = BUF_memdup(ASN1_STRING_data(ukm), dukmlen);
+        if (!dukm)
+            goto err;
+    }
+
+    if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0)
+        goto err;
+    dukm = NULL;
+
+    /*
+     * Now need to wrap encoding of wrap AlgorithmIdentifier into parameter
+     * of another AlgorithmIdentifier.
+     */
+    penc = NULL;
+    penclen = i2d_X509_ALGOR(wrap_alg, &penc);
+    if (!penc || !penclen)
+        goto err;
+    wrap_str = ASN1_STRING_new();
+    if (!wrap_str)
+        goto err;
+    ASN1_STRING_set0(wrap_str, penc, penclen);
+    penc = NULL;
+    X509_ALGOR_set0(talg, OBJ_nid2obj(NID_id_smime_alg_ESDH),
+                    V_ASN1_SEQUENCE, wrap_str);
+
+    rv = 1;
+
+ err:
+    if (penc)
+        OPENSSL_free(penc);
+    if (wrap_alg)
+        X509_ALGOR_free(wrap_alg);
+    return rv;
+}
+
+#endif

+ 96 - 2
libs/openssl/crypto/dh/dh_asn1.c

@@ -89,7 +89,101 @@ ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
 
 IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
 
-DH *DHparams_dup(DH *dh)
+/*
+ * Internal only structures for handling X9.42 DH: this gets translated to or
+ * from a DH structure straight away.
+ */
+
+typedef struct {
+    ASN1_BIT_STRING *seed;
+    BIGNUM *counter;
+} int_dhvparams;
+
+typedef struct {
+    BIGNUM *p;
+    BIGNUM *q;
+    BIGNUM *g;
+    BIGNUM *j;
+    int_dhvparams *vparams;
+} int_dhx942_dh;
+
+ASN1_SEQUENCE(DHvparams) = {
+        ASN1_SIMPLE(int_dhvparams, seed, ASN1_BIT_STRING),
+        ASN1_SIMPLE(int_dhvparams, counter, BIGNUM)
+} ASN1_SEQUENCE_END_name(int_dhvparams, DHvparams)
+
+ASN1_SEQUENCE(DHxparams) = {
+        ASN1_SIMPLE(int_dhx942_dh, p, BIGNUM),
+        ASN1_SIMPLE(int_dhx942_dh, g, BIGNUM),
+        ASN1_SIMPLE(int_dhx942_dh, q, BIGNUM),
+        ASN1_OPT(int_dhx942_dh, j, BIGNUM),
+        ASN1_OPT(int_dhx942_dh, vparams, DHvparams),
+} ASN1_SEQUENCE_END_name(int_dhx942_dh, DHxparams)
+
+int_dhx942_dh *d2i_int_dhx(int_dhx942_dh **a,
+                           const unsigned char **pp, long length);
+int i2d_int_dhx(const int_dhx942_dh *a, unsigned char **pp);
+
+IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(int_dhx942_dh, DHxparams, int_dhx)
+
+/* Application leve function: read in X9.42 DH parameters into DH structure */
+
+DH *d2i_DHxparams(DH **a, const unsigned char **pp, long length)
 {
-    return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh);
+    int_dhx942_dh *dhx = NULL;
+    DH *dh = NULL;
+    dh = DH_new();
+    if (!dh)
+        return NULL;
+    dhx = d2i_int_dhx(NULL, pp, length);
+    if (!dhx) {
+        DH_free(dh);
+        return NULL;
+    }
+
+    if (a) {
+        if (*a)
+            DH_free(*a);
+        *a = dh;
+    }
+
+    dh->p = dhx->p;
+    dh->q = dhx->q;
+    dh->g = dhx->g;
+    dh->j = dhx->j;
+
+    if (dhx->vparams) {
+        dh->seed = dhx->vparams->seed->data;
+        dh->seedlen = dhx->vparams->seed->length;
+        dh->counter = dhx->vparams->counter;
+        dhx->vparams->seed->data = NULL;
+        ASN1_BIT_STRING_free(dhx->vparams->seed);
+        OPENSSL_free(dhx->vparams);
+        dhx->vparams = NULL;
+    }
+
+    OPENSSL_free(dhx);
+    return dh;
+}
+
+int i2d_DHxparams(const DH *dh, unsigned char **pp)
+{
+    int_dhx942_dh dhx;
+    int_dhvparams dhv;
+    ASN1_BIT_STRING bs;
+    dhx.p = dh->p;
+    dhx.g = dh->g;
+    dhx.q = dh->q;
+    dhx.j = dh->j;
+    if (dh->counter && dh->seed && dh->seedlen > 0) {
+        bs.flags = ASN1_STRING_FLAG_BITS_LEFT;
+        bs.data = dh->seed;
+        bs.length = dh->seedlen;
+        dhv.seed = &bs;
+        dhv.counter = dh->counter;
+        dhx.vparams = &dhv;
+    } else
+        dhx.vparams = NULL;
+
+    return i2d_int_dhx(&dhx, pp);
 }

+ 36 - 10
libs/openssl/crypto/dh/dh_check.c

@@ -76,17 +76,43 @@ int DH_check(const DH *dh, int *ret)
     int ok = 0;
     BN_CTX *ctx = NULL;
     BN_ULONG l;
-    BIGNUM *q = NULL;
+    BIGNUM *t1 = NULL, *t2 = NULL;
 
     *ret = 0;
     ctx = BN_CTX_new();
     if (ctx == NULL)
         goto err;
-    q = BN_new();
-    if (q == NULL)
+    BN_CTX_start(ctx);
+    t1 = BN_CTX_get(ctx);
+    if (t1 == NULL)
+        goto err;
+    t2 = BN_CTX_get(ctx);
+    if (t2 == NULL)
         goto err;
 
-    if (BN_is_word(dh->g, DH_GENERATOR_2)) {
+    if (dh->q) {
+        if (BN_cmp(dh->g, BN_value_one()) <= 0)
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+        else if (BN_cmp(dh->g, dh->p) >= 0)
+            *ret |= DH_NOT_SUITABLE_GENERATOR;
+        else {
+            /* Check g^q == 1 mod p */
+            if (!BN_mod_exp(t1, dh->g, dh->q, dh->p, ctx))
+                goto err;
+            if (!BN_is_one(t1))
+                *ret |= DH_NOT_SUITABLE_GENERATOR;
+        }
+        if (!BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL))
+            *ret |= DH_CHECK_Q_NOT_PRIME;
+        /* Check p == 1 mod q  i.e. q divides p - 1 */
+        if (!BN_div(t1, t2, dh->p, dh->q, ctx))
+            goto err;
+        if (!BN_is_one(t2))
+            *ret |= DH_CHECK_INVALID_Q_VALUE;
+        if (dh->j && BN_cmp(dh->j, t1))
+            *ret |= DH_CHECK_INVALID_J_VALUE;
+
+    } else if (BN_is_word(dh->g, DH_GENERATOR_2)) {
         l = BN_mod_word(dh->p, 24);
         if (l != 11)
             *ret |= DH_NOT_SUITABLE_GENERATOR;
@@ -107,18 +133,18 @@ int DH_check(const DH *dh, int *ret)
 
     if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL))
         *ret |= DH_CHECK_P_NOT_PRIME;
-    else {
-        if (!BN_rshift1(q, dh->p))
+    else if (!dh->q) {
+        if (!BN_rshift1(t1, dh->p))
             goto err;
-        if (!BN_is_prime_ex(q, BN_prime_checks, ctx, NULL))
+        if (!BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL))
             *ret |= DH_CHECK_P_NOT_SAFE_PRIME;
     }
     ok = 1;
  err:
-    if (ctx != NULL)
+    if (ctx != NULL) {
+        BN_CTX_end(ctx);
         BN_CTX_free(ctx);
-    if (q != NULL)
-        BN_free(q);
+    }
     return (ok);
 }
 

+ 7 - 1
libs/openssl/crypto/dh/dh_err.c

@@ -1,6 +1,6 @@
 /* crypto/dh/dh_err.c */
 /* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2013 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
@@ -73,6 +73,9 @@ static ERR_STRING_DATA DH_str_functs[] = {
     {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"},
     {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"},
     {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"},
+    {ERR_FUNC(DH_F_DH_CMS_DECRYPT), "DH_CMS_DECRYPT"},
+    {ERR_FUNC(DH_F_DH_CMS_SET_PEERKEY), "DH_CMS_SET_PEERKEY"},
+    {ERR_FUNC(DH_F_DH_CMS_SET_SHARED_INFO), "DH_CMS_SET_SHARED_INFO"},
     {ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"},
     {ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"},
     {ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX), "DH_generate_parameters_ex"},
@@ -96,6 +99,7 @@ static ERR_STRING_DATA DH_str_reasons[] = {
     {ERR_REASON(DH_R_BN_ERROR), "bn error"},
     {ERR_REASON(DH_R_DECODE_ERROR), "decode error"},
     {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"},
+    {ERR_REASON(DH_R_KDF_PARAMETER_ERROR), "kdf parameter error"},
     {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"},
     {ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL), "key size too small"},
     {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"},
@@ -103,6 +107,8 @@ static ERR_STRING_DATA DH_str_reasons[] = {
     {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"},
     {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"},
     {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"},
+    {ERR_REASON(DH_R_PEER_KEY_ERROR), "peer key error"},
+    {ERR_REASON(DH_R_SHARED_INFO_ERROR), "shared info error"},
     {0, NULL}
 };
 

+ 187 - 0
libs/openssl/crypto/dh/dh_kdf.c

@@ -0,0 +1,187 @@
+/* crypto/dh/dh_kdf.c */
+/*
+ * Written by Stephen Henson for the OpenSSL project.
+ */
+/* ====================================================================
+ * Copyright (c) 2013 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
+ *    [email protected].
+ *
+ * 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 <string.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <openssl/asn1.h>
+#include <openssl/cms.h>
+
+/* Key derivation from X9.42/RFC2631 */
+
+#define DH_KDF_MAX      (1L << 30)
+
+/* Skip past an ASN1 structure: for OBJECT skip content octets too */
+
+static int skip_asn1(unsigned char **pp, long *plen, int exptag)
+{
+    const unsigned char *q = *pp;
+    int i, tag, xclass;
+    long tmplen;
+    i = ASN1_get_object(&q, &tmplen, &tag, &xclass, *plen);
+    if (i & 0x80)
+        return 0;
+    if (tag != exptag || xclass != V_ASN1_UNIVERSAL)
+        return 0;
+    if (tag == V_ASN1_OBJECT)
+        q += tmplen;
+    *plen -= q - *pp;
+    *pp = (unsigned char *)q;
+    return 1;
+}
+
+/*
+ * Encode the DH shared info structure, return an offset to the counter value
+ * so we can update the structure without reencoding it.
+ */
+
+static int dh_sharedinfo_encode(unsigned char **pder, unsigned char **pctr,
+                                ASN1_OBJECT *key_oid, size_t outlen,
+                                const unsigned char *ukm, size_t ukmlen)
+{
+    unsigned char *p;
+    int derlen;
+    long tlen;
+    /* "magic" value to check offset is sane */
+    static unsigned char ctr[4] = { 0xF3, 0x17, 0x22, 0x53 };
+    X509_ALGOR atmp;
+    ASN1_OCTET_STRING ctr_oct, ukm_oct, *pukm_oct;
+    ASN1_TYPE ctr_atype;
+    if (ukmlen > DH_KDF_MAX || outlen > DH_KDF_MAX)
+        return 0;
+    ctr_oct.data = ctr;
+    ctr_oct.length = 4;
+    ctr_oct.flags = 0;
+    ctr_oct.type = V_ASN1_OCTET_STRING;
+    ctr_atype.type = V_ASN1_OCTET_STRING;
+    ctr_atype.value.octet_string = &ctr_oct;
+    atmp.algorithm = key_oid;
+    atmp.parameter = &ctr_atype;
+    if (ukm) {
+        ukm_oct.type = V_ASN1_OCTET_STRING;
+        ukm_oct.flags = 0;
+        ukm_oct.data = (unsigned char *)ukm;
+        ukm_oct.length = ukmlen;
+        pukm_oct = &ukm_oct;
+    } else
+        pukm_oct = NULL;
+    derlen = CMS_SharedInfo_encode(pder, &atmp, pukm_oct, outlen);
+    if (derlen <= 0)
+        return 0;
+    p = *pder;
+    tlen = derlen;
+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_SEQUENCE))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_OBJECT))
+        return 0;
+    if (!skip_asn1(&p, &tlen, V_ASN1_OCTET_STRING))
+        return 0;
+    if (CRYPTO_memcmp(p, ctr, 4))
+        return 0;
+    *pctr = p;
+    return derlen;
+}
+
+int DH_KDF_X9_42(unsigned char *out, size_t outlen,
+                 const unsigned char *Z, size_t Zlen,
+                 ASN1_OBJECT *key_oid,
+                 const unsigned char *ukm, size_t ukmlen, const EVP_MD *md)
+{
+    EVP_MD_CTX mctx;
+    int rv = 0;
+    unsigned int i;
+    size_t mdlen;
+    unsigned char *der = NULL, *ctr;
+    int derlen;
+    if (Zlen > DH_KDF_MAX)
+        return 0;
+    mdlen = EVP_MD_size(md);
+    EVP_MD_CTX_init(&mctx);
+    derlen = dh_sharedinfo_encode(&der, &ctr, key_oid, outlen, ukm, ukmlen);
+    if (derlen == 0)
+        goto err;
+    for (i = 1;; i++) {
+        unsigned char mtmp[EVP_MAX_MD_SIZE];
+        EVP_DigestInit_ex(&mctx, md, NULL);
+        if (!EVP_DigestUpdate(&mctx, Z, Zlen))
+            goto err;
+        ctr[3] = i & 0xFF;
+        ctr[2] = (i >> 8) & 0xFF;
+        ctr[1] = (i >> 16) & 0xFF;
+        ctr[0] = (i >> 24) & 0xFF;
+        if (!EVP_DigestUpdate(&mctx, der, derlen))
+            goto err;
+        if (outlen >= mdlen) {
+            if (!EVP_DigestFinal(&mctx, out, NULL))
+                goto err;
+            outlen -= mdlen;
+            if (outlen == 0)
+                break;
+            out += mdlen;
+        } else {
+            if (!EVP_DigestFinal(&mctx, mtmp, NULL))
+                goto err;
+            memcpy(out, mtmp, outlen);
+            OPENSSL_cleanse(mtmp, mdlen);
+            break;
+        }
+    }
+    rv = 1;
+ err:
+    if (der)
+        OPENSSL_free(der);
+    EVP_MD_CTX_cleanup(&mctx);
+    return rv;
+}

+ 14 - 0
libs/openssl/crypto/dh/dh_key.c

@@ -94,6 +94,20 @@ int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
     return dh->meth->compute_key(key, pub_key, dh);
 }
 
+int DH_compute_key_padded(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+{
+    int rv, pad;
+    rv = dh->meth->compute_key(key, pub_key, dh);
+    if (rv <= 0)
+        return rv;
+    pad = BN_num_bytes(dh->p) - rv;
+    if (pad > 0) {
+        memmove(key + pad, key, rv);
+        memset(key, 0, pad);
+    }
+    return rv + pad;
+}
+
 static DH_METHOD dh_ossl = {
     "OpenSSL DH Method",
     generate_key,

+ 314 - 8
libs/openssl/crypto/dh/dh_pmeth.c

@@ -63,6 +63,10 @@
 #include <openssl/evp.h>
 #include <openssl/dh.h>
 #include <openssl/bn.h>
+#ifndef OPENSSL_NO_DSA
+# include <openssl/dsa.h>
+#endif
+#include <openssl/objects.h>
 #include "evp_locl.h"
 
 /* DH pkey context structure */
@@ -72,9 +76,23 @@ typedef struct {
     int prime_len;
     int generator;
     int use_dsa;
+    int subprime_len;
+    /* message digest used for parameter generation */
+    const EVP_MD *md;
+    int rfc5114_param;
     /* Keygen callback info */
     int gentmp[2];
-    /* message digest */
+    /* KDF (if any) to use for DH */
+    char kdf_type;
+    /* OID to use for KDF */
+    ASN1_OBJECT *kdf_oid;
+    /* Message digest to use for key derivation */
+    const EVP_MD *kdf_md;
+    /* User key material */
+    unsigned char *kdf_ukm;
+    size_t kdf_ukmlen;
+    /* KDF output length */
+    size_t kdf_outlen;
 } DH_PKEY_CTX;
 
 static int pkey_dh_init(EVP_PKEY_CTX *ctx)
@@ -84,8 +102,18 @@ static int pkey_dh_init(EVP_PKEY_CTX *ctx)
     if (!dctx)
         return 0;
     dctx->prime_len = 1024;
+    dctx->subprime_len = -1;
     dctx->generator = 2;
     dctx->use_dsa = 0;
+    dctx->md = NULL;
+    dctx->rfc5114_param = 0;
+
+    dctx->kdf_type = EVP_PKEY_DH_KDF_NONE;
+    dctx->kdf_oid = NULL;
+    dctx->kdf_md = NULL;
+    dctx->kdf_ukm = NULL;
+    dctx->kdf_ukmlen = 0;
+    dctx->kdf_outlen = 0;
 
     ctx->data = dctx;
     ctx->keygen_info = dctx->gentmp;
@@ -102,16 +130,35 @@ static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
     sctx = src->data;
     dctx = dst->data;
     dctx->prime_len = sctx->prime_len;
+    dctx->subprime_len = sctx->subprime_len;
     dctx->generator = sctx->generator;
     dctx->use_dsa = sctx->use_dsa;
+    dctx->md = sctx->md;
+    dctx->rfc5114_param = sctx->rfc5114_param;
+
+    dctx->kdf_type = sctx->kdf_type;
+    dctx->kdf_oid = OBJ_dup(sctx->kdf_oid);
+    if (!dctx->kdf_oid)
+        return 0;
+    dctx->kdf_md = sctx->kdf_md;
+    if (dctx->kdf_ukm) {
+        dctx->kdf_ukm = BUF_memdup(sctx->kdf_ukm, sctx->kdf_ukmlen);
+        dctx->kdf_ukmlen = sctx->kdf_ukmlen;
+    }
+    dctx->kdf_outlen = sctx->kdf_outlen;
     return 1;
 }
 
 static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx)
 {
     DH_PKEY_CTX *dctx = ctx->data;
-    if (dctx)
+    if (dctx) {
+        if (dctx->kdf_ukm)
+            OPENSSL_free(dctx->kdf_ukm);
+        if (dctx->kdf_oid)
+            ASN1_OBJECT_free(dctx->kdf_oid);
         OPENSSL_free(dctx);
+    }
 }
 
 static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
@@ -124,14 +171,89 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
         dctx->prime_len = p1;
         return 1;
 
+    case EVP_PKEY_CTRL_DH_PARAMGEN_SUBPRIME_LEN:
+        if (dctx->use_dsa == 0)
+            return -2;
+        dctx->subprime_len = p1;
+        return 1;
+
     case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR:
+        if (dctx->use_dsa)
+            return -2;
         dctx->generator = p1;
         return 1;
 
+    case EVP_PKEY_CTRL_DH_PARAMGEN_TYPE:
+#ifdef OPENSSL_NO_DSA
+        if (p1 != 0)
+            return -2;
+#else
+        if (p1 < 0 || p1 > 2)
+            return -2;
+#endif
+        dctx->use_dsa = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_RFC5114:
+        if (p1 < 1 || p1 > 3)
+            return -2;
+        dctx->rfc5114_param = p1;
+        return 1;
+
     case EVP_PKEY_CTRL_PEER_KEY:
         /* Default behaviour is OK */
         return 1;
 
+    case EVP_PKEY_CTRL_DH_KDF_TYPE:
+        if (p1 == -2)
+            return dctx->kdf_type;
+        if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
+            return -2;
+        dctx->kdf_type = p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_MD:
+        dctx->kdf_md = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_MD:
+        *(const EVP_MD **)p2 = dctx->kdf_md;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_OUTLEN:
+        if (p1 <= 0)
+            return -2;
+        dctx->kdf_outlen = (size_t)p1;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_OUTLEN:
+        *(int *)p2 = dctx->kdf_outlen;
+        return 1;
+
+    case EVP_PKEY_CTRL_DH_KDF_UKM:
+        if (dctx->kdf_ukm)
+            OPENSSL_free(dctx->kdf_ukm);
+        dctx->kdf_ukm = p2;
+        if (p2)
+            dctx->kdf_ukmlen = p1;
+        else
+            dctx->kdf_ukmlen = 0;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_UKM:
+        *(unsigned char **)p2 = dctx->kdf_ukm;
+        return dctx->kdf_ukmlen;
+
+    case EVP_PKEY_CTRL_DH_KDF_OID:
+        if (dctx->kdf_oid)
+            ASN1_OBJECT_free(dctx->kdf_oid);
+        dctx->kdf_oid = p2;
+        return 1;
+
+    case EVP_PKEY_CTRL_GET_DH_KDF_OID:
+        *(ASN1_OBJECT **)p2 = dctx->kdf_oid;
+        return 1;
+
     default:
         return -2;
 
@@ -146,30 +268,139 @@ static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx,
         len = atoi(value);
         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
     }
+    if (!strcmp(type, "dh_rfc5114")) {
+        DH_PKEY_CTX *dctx = ctx->data;
+        int len;
+        len = atoi(value);
+        if (len < 0 || len > 3)
+            return -2;
+        dctx->rfc5114_param = len;
+        return 1;
+    }
     if (!strcmp(type, "dh_paramgen_generator")) {
         int len;
         len = atoi(value);
         return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len);
     }
+    if (!strcmp(type, "dh_paramgen_subprime_len")) {
+        int len;
+        len = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_subprime_len(ctx, len);
+    }
+    if (!strcmp(type, "dh_paramgen_type")) {
+        int typ;
+        typ = atoi(value);
+        return EVP_PKEY_CTX_set_dh_paramgen_type(ctx, typ);
+    }
     return -2;
 }
 
+#ifndef OPENSSL_NO_DSA
+
+extern 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);
+
+extern int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
+                                 const EVP_MD *evpmd,
+                                 const unsigned char *seed_in,
+                                 size_t seed_len, int idx,
+                                 unsigned char *seed_out, int *counter_ret,
+                                 unsigned long *h_ret, BN_GENCB *cb);
+
+static DSA *dsa_dh_generate(DH_PKEY_CTX *dctx, BN_GENCB *pcb)
+{
+    DSA *ret;
+    int rv = 0;
+    int prime_len = dctx->prime_len;
+    int subprime_len = dctx->subprime_len;
+    const EVP_MD *md = dctx->md;
+    if (dctx->use_dsa > 2)
+        return NULL;
+    ret = DSA_new();
+    if (!ret)
+        return NULL;
+    if (subprime_len == -1) {
+        if (prime_len >= 2048)
+            subprime_len = 256;
+        else
+            subprime_len = 160;
+    }
+    if (md == NULL) {
+        if (prime_len >= 2048)
+            md = EVP_sha256();
+        else
+            md = EVP_sha1();
+    }
+    if (dctx->use_dsa == 1)
+        rv = dsa_builtin_paramgen(ret, prime_len, subprime_len, md,
+                                  NULL, 0, NULL, NULL, NULL, pcb);
+    else if (dctx->use_dsa == 2)
+        rv = dsa_builtin_paramgen2(ret, prime_len, subprime_len, md,
+                                   NULL, 0, -1, NULL, NULL, NULL, pcb);
+    if (rv <= 0) {
+        DSA_free(ret);
+        return NULL;
+    }
+    return ret;
+}
+
+#endif
+
 static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
 {
     DH *dh = NULL;
     DH_PKEY_CTX *dctx = ctx->data;
     BN_GENCB *pcb, cb;
     int ret;
+    if (dctx->rfc5114_param) {
+        switch (dctx->rfc5114_param) {
+        case 1:
+            dh = DH_get_1024_160();
+            break;
+
+        case 2:
+            dh = DH_get_2048_224();
+            break;
+
+        case 3:
+            dh = DH_get_2048_256();
+            break;
+
+        default:
+            return -2;
+        }
+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+        return 1;
+    }
+
     if (ctx->pkey_gencb) {
         pcb = &cb;
         evp_pkey_set_cb_translate(pcb, ctx);
     } else
         pcb = NULL;
+#ifndef OPENSSL_NO_DSA
+    if (dctx->use_dsa) {
+        DSA *dsa_dh;
+        dsa_dh = dsa_dh_generate(dctx, pcb);
+        if (!dsa_dh)
+            return 0;
+        dh = DSA_dup_DH(dsa_dh);
+        DSA_free(dsa_dh);
+        if (!dh)
+            return 0;
+        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+        return 1;
+    }
+#endif
     dh = DH_new();
     if (!dh)
         return 0;
     ret = DH_generate_parameters_ex(dh,
                                     dctx->prime_len, dctx->generator, pcb);
+
     if (ret)
         EVP_PKEY_assign_DH(pkey, dh);
     else
@@ -187,7 +418,7 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
     dh = DH_new();
     if (!dh)
         return 0;
-    EVP_PKEY_assign_DH(pkey, dh);
+    EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, dh);
     /* Note: if error return, pkey is freed by parent routine */
     if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
         return 0;
@@ -198,21 +429,96 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
                           size_t *keylen)
 {
     int ret;
+    DH *dh;
+    DH_PKEY_CTX *dctx = ctx->data;
+    BIGNUM *dhpub;
     if (!ctx->pkey || !ctx->peerkey) {
         DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET);
         return 0;
     }
-    ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key,
-                         ctx->pkey->pkey.dh);
-    if (ret < 0)
+    dh = ctx->pkey->pkey.dh;
+    dhpub = ctx->peerkey->pkey.dh->pub_key;
+    if (dctx->kdf_type == EVP_PKEY_DH_KDF_NONE) {
+        if (key == NULL) {
+            *keylen = DH_size(dh);
+            return 1;
+        }
+        ret = DH_compute_key(key, dhpub, dh);
+        if (ret < 0)
+            return ret;
+        *keylen = ret;
+        return 1;
+    } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
+        unsigned char *Z = NULL;
+        size_t Zlen = 0;
+        if (!dctx->kdf_outlen || !dctx->kdf_oid)
+            return 0;
+        if (key == NULL) {
+            *keylen = dctx->kdf_outlen;
+            return 1;
+        }
+        if (*keylen != dctx->kdf_outlen)
+            return 0;
+        ret = 0;
+        Zlen = DH_size(dh);
+        Z = OPENSSL_malloc(Zlen);
+        if (!Z) {
+            goto err;
+        }
+        if (DH_compute_key_padded(Z, dhpub, dh) <= 0)
+            goto err;
+        if (!DH_KDF_X9_42(key, *keylen, Z, Zlen, dctx->kdf_oid,
+                          dctx->kdf_ukm, dctx->kdf_ukmlen, dctx->kdf_md))
+            goto err;
+        *keylen = dctx->kdf_outlen;
+        ret = 1;
+ err:
+        if (Z) {
+            OPENSSL_cleanse(Z, Zlen);
+            OPENSSL_free(Z);
+        }
         return ret;
-    *keylen = ret;
+    }
     return 1;
 }
 
 const EVP_PKEY_METHOD dh_pkey_meth = {
     EVP_PKEY_DH,
-    EVP_PKEY_FLAG_AUTOARGLEN,
+    0,
+    pkey_dh_init,
+    pkey_dh_copy,
+    pkey_dh_cleanup,
+
+    0,
+    pkey_dh_paramgen,
+
+    0,
+    pkey_dh_keygen,
+
+    0,
+    0,
+
+    0,
+    0,
+
+    0, 0,
+
+    0, 0, 0, 0,
+
+    0, 0,
+
+    0, 0,
+
+    0,
+    pkey_dh_derive,
+
+    pkey_dh_ctrl,
+    pkey_dh_ctrl_str
+};
+
+const EVP_PKEY_METHOD dhx_pkey_meth = {
+    EVP_PKEY_DHX,
+    0,
     pkey_dh_init,
     pkey_dh_copy,
     pkey_dh_cleanup,

Some files were not shown because too many files changed in this diff