first commit

This commit is contained in:
Mateusz Gruszczyński committed 2026-10-28 09:16:54 +01:00
commit 32a7ba8e8f
168 files changed
+123856

No files matched your search

+49
View File
@@ -0,0 +1,49 @@
# Vendored from crates.io libssh2-sys 0.3.3; see PROVENANCE.md.
[package]
name = "libssh2-sys"
version = "0.3.3"
publish = false
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Wez Furlong <wez@wezfurlong.org>",
"Matteo Bigoi <bigo@crisidev.org>",
]
build = "build.rs"
links = "ssh2"
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Native bindings to the libssh2 library"
documentation = "https://docs.rs/libssh2-sys"
readme = false
license = "MIT OR Apache-2.0"
repository = "https://github.com/alexcrichton/ssh2-rs"
[features]
openssl-on-win32 = ["openssl-sys"]
vendored-openssl = ["openssl-sys/vendored"]
zlib-ng-compat = ["libz-sys/zlib-ng"]
[lib]
name = "libssh2_sys"
path = "lib.rs"
[dependencies.libc]
version = "0.2"
[dependencies.libz-sys]
version = "1.1.0"
features = ["libc"]
default-features = false
[build-dependencies.cc]
version = "1.0.25"
[target."cfg(unix)".dependencies.openssl-sys]
version = "0.9.35"
[target."cfg(windows)".dependencies.openssl-sys]
version = "0.9.35"
optional = true
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+25
View File
@@ -0,0 +1,25 @@
Copyright (c) 2014 Alex Crichton
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+93
View File
@@ -0,0 +1,93 @@
# Vendored libssh2 security backports
This directory contains the compilation sources of **libssh2-sys 0.3.3** from
crates.io, with narrowly scoped libssh2 security backports. The application uses
it through Cargo's `[patch.crates-io]` mechanism. It is not a new upstream release
and does not claim to be libssh2 1.11.2.
## Source identity and licensing
- Published package: <https://crates.io/crates/libssh2-sys/0.3.3>.
- Original archive: <https://static.crates.io/crates/libssh2-sys/libssh2-sys-0.3.3.crate>.
- Archive SHA-256: `0f5eb74291e8691cab524a01274a1b1e7742b1a94f29d8b101d8aadc8372c1cd`.
- Wrapper repository revision: `1abdbdb031cfea7e9e3dca7980ea36845bba1da8`.
- Bundled libssh2 revision: `090f23d1852a0b62e081bd12c4d05adc1c4af47a`.
- Wrapper license: `LICENSE-MIT` or `LICENSE-APACHE`, preserved verbatim.
- Native library license and additional notices: `libssh2/COPYING`,
`libssh2/LICENSES/`, and the original source headers, preserved verbatim.
Only files needed by the original Cargo build and licenses were copied. Upstream
examples, CI files, manuals and unrelated build-system files are omitted. The
original Rust FFI source and C headers are unchanged. The small tests in this
directory are new regression checks for this distribution, licensed under MIT.
The published source is based on libssh2 1.11.1 and already includes backports for
CVE-2025-15661, CVE-2026-55199 and CVE-2026-55200, plus the SFTP status follow-up
`4ed26f5740bdd409269ed9fb48a28bf8f565b681`. Those fixes are retained.
## Additional patches
The unmodified upstream patch downloads are in `patches/upstream/`.
`patches/upstream-manifest.json` records each URL, full commit and SHA-256.
| Issue | Upstream commit | Change carried into the bundled code |
|---|---|---|
| CVE-2026-7598 | [256d04b60d80](https://github.com/libssh2/libssh2/commit/256d04b60d80bf1190e96b0ad1e91b2174d744b1) | Reject overflowing username lengths in authentication APIs; correct the password-change length comparison. |
| CVE-2026-66032 | [5e4776146552](https://github.com/libssh2/libssh2/commit/5e4776146552d898b9c0e1b313cd093fa8dc92d0) | Null the freed SFTP response pointer before waiting for a handle response. |
| CVE-2026-66033 | [a2ed82d40964](https://github.com/libssh2/libssh2/commit/a2ed82d40964bbc0d64cd717aa0a5a892117d2e6) | Apply AES-GCM bounds checks in release builds before computing the cipher length. |
| CVE-2026-66034 | [a13bb6c773f0](https://github.com/libssh2/libssh2/commit/a13bb6c773f0d55ad1628cede57e99803cd898d9) | Check remaining publickey response data before consuming a server-supplied comment length. |
| CVE-2026-66035 | [42e33d81577e](https://github.com/libssh2/libssh2/commit/42e33d81577ed4b95d4b4f6f845e5ee8efe5eeb4) | Reject an ETM packet too short for its MAC, length and first cipher block before decrypting. |
| CVE-2026-58050 | [34497525929b](https://github.com/libssh2/libssh2/commit/34497525929b9a47f03dfb81887ac896202b7e12) | Bound publickey attribute count to 1024 before multiplying for allocation. |
| CVE-2026-58051 | [a9758da45a52](https://github.com/libssh2/libssh2/commit/a9758da45a52bc8c630ec9493804d0c6ea30b24a) | Initialize newly allocated publickey list entries before error cleanup can inspect them. |
| Publickey cleanup follow-up | [c2f1a3a21b4c](https://github.com/libssh2/libssh2/commit/c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a) | Initialize all new entries and free partially initialized attribute allocations. |
| Publickey terminator follow-up | [ad16eb112f4a](https://github.com/libssh2/libssh2/commit/ad16eb112f4a9591acdf5f6f2981328613e6b626) | Include the reserved terminator entry in zero-initialization. |
Upstream renamed private symbols after the bundled base revision. Backports use
the corresponding old `_libssh2_*` / `LIBSSH2_*` names and local formatting.
Upstream `SSH2_SAFEFREE(session, p->payload)` is represented by the equivalent
`LIBSSH2_FREE(session, p->payload); p->payload = NULL;`. The three publickey
initialization/cleanup patches are combined into their final corrected form.
These mechanical adaptations do not change their conditions or error codes.
## Reproducible patch and build selection
`patches/security-backports.patch` applies to an extracted, original 0.3.3 crate
with `patch -p1`. Its SHA-256 is:
```text
b6f970cfc5749e0ba35695b7d49b0774a191779d159a438249f9065ecc8a88bd
```
Replay was checked on a fresh copy: all seven modified files were byte-identical
to the shipped source. `SHA256SUMS` covers the shipped vendor files except the
checksum list itself. Verify it from this directory with `sha256sum -c SHA256SUMS`.
`build.rs` always compiles the bundled C source. It rejects
`LIBSSH2_SYS_USE_PKG_CONFIG`; automatic vcpkg fallback and the build-time Git
submodule command are removed. Source/header changes trigger a rebuild. This
prevents a local system libssh2 from silently replacing the corrected source.
OpenSSL and zlib remain the original supported backend dependencies. Their
operating-system packages require the usual security maintenance.
The wrapper manifest is marked `publish = false`; unused pkg-config/vcpkg direct
build dependencies are removed. All other wrapper features and dependencies are
preserved.
## Regression verification
After a Linux Cargo build, use the archive emitted by this exact path dependency:
```sh
vendor/libssh2-sys/tests/run-security-regressions.sh \
/absolute/path/to/target/debug/build/libssh2-sys-<build-id>/out/build/libssh2.a
```
The test passes deliberately malformed short and oversized AES-GCM blocks and
overflowing username lengths, without a network connection. It requires a C
compiler and the OpenSSL/zlib development libraries used by the normal build.
The application integration tests separately exercise real SSH, SFTP, SCP,
configuration export and binary upload against a local SSH server.
The published `README.md` records which checks were actually run. A
clean RustSec report alone does not audit bundled C code, prove absence of other
vulnerabilities, or replace device testing.
+91
View File
@@ -0,0 +1,91 @@
67553c86d569577e9ab8548c8d819ef71760d73d34374f23c0c0cd21c8c1f8ee Cargo.toml
a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2 LICENSE-APACHE
378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397 LICENSE-MIT
57601e789769e6719ef9b6d7eff6f83e7c8a07a92afb471de629e21e316ce1d5 PROVENANCE.md
f4db47339ee857174c97128c78bd9b9abc95220b2eb4cc64e9dc4d9e38dae341 build.rs
d7b081dc4c07012e5e125352e2f2b939cce93a7a70ae657c77655aa93a9f05ec lib.rs
f7f9633cf9ff2f1333f3d7ce46973a8716a4d2a2815ad56f30d437d5fea7bafe libssh2/COPYING
3aedabc2618dd11c18747e1ccc680b2841b4aa414de661ae9dc1d4602c0b93f0 libssh2/LICENSES/BSD-2-Clause.txt
3cf06aba3588c41c514f6946bb2d757b413ff6491647d474800f55edca75dcb4 libssh2/LICENSES/BSD-3-Clause.txt
ffff0ec9c19fc90efbad30c66b7e335ab1f824a7ef806d943b45d28b67c75f9a libssh2/LICENSES/FSFULLR.txt
002c2696d92b5c8cf956c11072baa58eaf9f6ade995c031ea635c6a1ee342ad1 libssh2/LICENSES/MIT.txt
49f2fc047b5f5cc66be8a70dd65825a37386f9bb8d08d6ed939351a3a7750b90 libssh2/LICENSES/SAX-PD-2.0.txt
d3483fbbf511197d9b8402e48bf4bb5dc8c082abef0ae957334a2c3e8f32e976 libssh2/LICENSES/curl.txt
767d54ff5ae2cd0dab48895ccbcb8ee045a17f826f77a24c06461634fef62778 libssh2/include/libssh2.h
f1cd086f3950e65635827ee3332c1c6ca62887c0f84369ec58e31974debb36e9 libssh2/include/libssh2_publickey.h
b5d864f19af69521278ed953b20b76a32cfdc08014da81d38f59964e7e2e2575 libssh2/include/libssh2_sftp.h
938b40033559b6b82d8f98872180dc9c0d7953b4dbd2f9217b3b77e506bac330 libssh2/libssh2.pc.in
11691629d5f88a4031d5ccf6ac756a66d1b1abfe6e138e81161e82b3ff4cbbbf libssh2/src/.gitignore
3857309526ae9794db496de79b509bda925798fcc857f5b30c50509823ac7841 libssh2/src/CMakeLists.txt
a71aa8dde39f76e726d57514f71c88402523f241a6c3edae8b269664e8ea0aa5 libssh2/src/Makefile.am
ed8a644a5c476a0eea976189d1dc277af23426046cadfbd0095db44305fdbd6f libssh2/src/Makefile.inc
a2e9b5a7c2bcba8fd252219f4308ddf5c192695a0957e1934000a9d3a6cbd470 libssh2/src/agent.c
3236e068f656cb381fac00350f14b281cb55cc84e1495af41dfec930e85c2f5d libssh2/src/agent_win.c
8df5f079c77ae9e5b452a575e2ecf33bf4478b356d2975c9a55eef364c84a415 libssh2/src/bcrypt_pbkdf.c
baeedac57701200ce12ab4beef6ff56dd6bfb787eaa9d9c1f4fe16fbdf690a32 libssh2/src/blowfish.c
0a1efb5884580f0b279fcd8782e455f8e3ca07bbdfebc457706f6e8bf18f296c libssh2/src/chacha.c
b42346b01acd60d6502e689802059648205c118035ede40bec8e0d60cf238518 libssh2/src/chacha.h
79c49c36e65178847087eb3a1c140772c291899b838c705b579214929a14742e libssh2/src/channel.c
0ed48da58c98ab7afcbb9a86177a29c92bb66dbd8793e1a8e477da0ef2f66e6d libssh2/src/channel.h
d9f806b81541de62184e3190b7e1c4f7ab576fd290e3558fe25bf0e00f115f5d libssh2/src/cipher-chachapoly.c
f6a69fb48994da6bf7f286884ed473ee0546027bba3af433b38b95d1b4442f5f libssh2/src/cipher-chachapoly.h
b2d1642bc02e0b50b02f2619393ac9afd15985bdbc088231a6ea876a82f23226 libssh2/src/comp.c
95aa07dee4c6f2c33f6bc762c6532997e37303bf1be1bb1276f4ecd5e7092443 libssh2/src/comp.h
2d69312c6059192560bb72e4bfa967e4b6e7c4453383580da90ab86233e98aa4 libssh2/src/crypt.c
f3eaf5a3a69d91b144f3d4c2f36313dc3264aada85aa1f42d7c1f6bbf969116f libssh2/src/crypto.c
1d3d7a56800f0b5b0d008a68d09aaaa26e326879cfd8ace7df8b99406e97f659 libssh2/src/crypto.h
e541d1a3b2a5e74733ce745a4d016175fa4ed1fb6571b8a4d69fdf5efdb576c2 libssh2/src/crypto_config.h
a6c325a335875d6d0fa0dbe544334a469cec32b45879b9372a49419da13bb492 libssh2/src/global.c
32edcf5a3023c67740b8a5e290a2db4957a547be7fb9f1778c143f08a622b65f libssh2/src/hostkey.c
93c0427472296781c0e01275e60b1d74c0f678112c45eebd5e233b31f4e4bbca libssh2/src/keepalive.c
50b90f522575d794b853802221e8b2f2cc99c3b68ff191e1252d70ed1276b6b5 libssh2/src/kex.c
f466648bff0197c06e3ea2380b9083b634f0002d41293f1102341247dd208872 libssh2/src/knownhost.c
90c46b20d6cc0288f4f3f272d5a4e8d2c0495d3f728d0b62ed9e0e026baf2532 libssh2/src/libgcrypt.c
0ae0284295424a04dba948432527b70fb12d447e8be8ce28e2be1e480323d4ac libssh2/src/libgcrypt.h
26d6cae6049b6fb7d32df0ea8a30ffbc0c52f1871be257bcb2986f40555ddada libssh2/src/libssh2.rc
a2d971a484dc63bea9cc46693ffc3de6227e118a32153df7db3df9139be14b00 libssh2/src/libssh2_config_cmake.h.in
c3da0fff8726b52b3dd2429bbaf26f75d93f0188367d650557d6710017ebb890 libssh2/src/libssh2_priv.h
d5d1c31758f49ef67e6afac92a7c8fc0ccb53b1fd2bba550e57a3042c17ba55b libssh2/src/libssh2_setup.h
b21e1b85582e43c9696c74fce826c664003326522d1bafb7a9ba6b28a0a6f64d libssh2/src/mac.c
acdc44807370d226c64958e870f3daec767378b45246bbcdee37db87120dab61 libssh2/src/mac.h
e56b0dafc27140de389926bb7e8417ab3e5255e74126ee4a588c18d70ad188cd libssh2/src/mbedtls.c
f26002e949125aac18471f10e590cbb5bee47c70de8a7798763604ef0ddcd44c libssh2/src/mbedtls.h
c4e749f78c4f5224fcb02eb50de65dc804ed4aaaa59a734b10a12f54fe2fa085 libssh2/src/misc.c
608eb5736eb367b82e93c96b8bc94fb87b23141f4658ee991307e64a721c4fa9 libssh2/src/misc.h
2df90530491643625921e42abbab3f7c4ffc981ce2276e1d0826cc38e896f484 libssh2/src/openssl.c
bdc6cc39f5a075d4497cc0222892ac371418133e6cfcaa357b131cd62d54e82a libssh2/src/openssl.h
31e230fdef9acdb23cd2de667b532f7b6853aacd403f54dbf1f700d2e68dbaca libssh2/src/os400qc3.c
c1f8a950a42a8a05ca00ac142915d9fd5bd99ef0c9a3545a12823c03ccb8673d libssh2/src/os400qc3.h
6ec4270e721ec1e0a5e57af52f59006b87438568bcca6057eb76cdcfd3a0b6ca libssh2/src/packet.c
66ded0eea0be5b4c1f5217e053941a848e5106311eb9338dd39f1bc48713a4c4 libssh2/src/packet.h
eba1a89ba4beb0aa9aaf4e4da68be5f2f890e7367001e8bb705c697b9485d416 libssh2/src/pem.c
cc0597e7de057ab22ab988bb98d4418d716ea26bb2ad418879007dd38dce2ebf libssh2/src/poly1305.c
58a34be15d390cae4cb5a215ccf139f0ca359cdb47ea846e6e7e1e6141d3409e libssh2/src/poly1305.h
ba80e17329a880d5bea1f8cf035dcf140c002ba1ed83eceaaec8dc352b6b3d28 libssh2/src/publickey.c
6a12ddc4c246b510ff61337d908c683714d4223fdb27f1256605a29f3925dc1a libssh2/src/scp.c
9f9c0a55ee7ca5204f73f2eb6e6c37957d1fe3f160ea7a819248310e1a58d8aa libssh2/src/session.c
19ebee873e9f5e1f56850bf263053d2527c28a184f30ac42f66aa09fb38d1b5a libssh2/src/session.h
93d9ed061a7b050649804e13aa208e9a726a6e694d696926bffddd5f011d84ec libssh2/src/sftp.c
9c53d613cfdb14d4244ab0643918de60363d9a360a40413cd2e4d682f3e32125 libssh2/src/sftp.h
5291489a6da89018354d67edb1675cec9ea14dcae232628527078e7094b6cae2 libssh2/src/transport.c
f2a55152b28ab3290d426767d9e33b053312300b0b4105cc0d20814c1b133ff3 libssh2/src/transport.h
4fff87fde157b9936c536fe545c2966a1b2d7f4e387db352849220020f98eadc libssh2/src/userauth.c
23eb97c342ab6bc51606fe917828e8c01cd4bda4c956d5f22b66d86b6db0d1a3 libssh2/src/userauth.h
e58477ff04c25b7a7f3c0654e36cbc483eef6a4ccc2d66b88223678d757502d2 libssh2/src/userauth_kbd_packet.c
570d9cbca0e3969d1f7dac2e3d89b0ad3b79bd9f0993d60b830a3b30113ae9f3 libssh2/src/userauth_kbd_packet.h
2710abb5561557c62613f1780fb593d9bc423105bdee81d0ace9bc1ab3b5fb23 libssh2/src/version.c
cd98e55761c4adebec10256ebe0f0b4f59ab23605d5663f5ccb7e7e2827debfe libssh2/src/wincng.c
78deb417e2cb9e514ad9da35db2f918d2649034318959b2b7a0fa15a9e5f960a libssh2/src/wincng.h
b6f970cfc5749e0ba35695b7d49b0774a191779d159a438249f9065ecc8a88bd patches/security-backports.patch
9cb033e07004a755675e2095eb7f05ebeaafa70b0920a1fdb8f6ad23498047d9 patches/upstream/58050-34497525929b.patch
0aee020bbc88acd2a3d828f1c85861f9f5a36204c07543cddc0abd68d4b5ed0a patches/upstream/58051-a9758da45a52.patch
a70ff256ce24fc5e4144fcc4409a5874c397e1f9e1b1d437120e4be3f5fc051d patches/upstream/66032-5e4776146552.patch
f59ff6d6575ec8f17af41825aac4dc6c8ddcdd6909dc6ae3a535fa13dba8a290 patches/upstream/66033-a2ed82d40964.patch
896ff800992af462519f0b2d2f47a84f5096728f27c9faf36b1676eaa9c6620f patches/upstream/66034-a13bb6c773f0.patch
0422c11e22df21dc8154fa0aeb812157d0798d990bd9ab2cd05844dc21653693 patches/upstream/66035-42e33d81577e.patch
fd4775228fe04a11532043355099fe2643993aae4fb63576620b1941f9a80645 patches/upstream/7598-256d04b60d80.patch
8d0e86562978b93406b85531e1f391d2f03c0387c057fb8b3a6e14b228aabdb5 patches/upstream/publickey-leak-c2f1a3a21b4c.patch
6464c70d8d34249e5d0a0969136f35c1a2a0e3d0424c2889c5b8e6fbe874f232 patches/upstream/publickey-terminator-ad16eb112f4a.patch
3c238183c67b3aad6497cdc8368d32cde5a4392dcba3134da0fa40c50882963e patches/upstream-manifest.json
00641403f44417872ef9fe45fe2a581451e4b9fd12305d1b3902f1433036edcc tests/run-security-regressions.sh
4d21796cd08f3dbf44664f3e53122960847940d306792ac7efcb8720794320cf tests/security-regression.c
+180
View File
@@ -0,0 +1,180 @@
extern crate cc;
use std::env;
use std::fs;
use std::path::PathBuf;
fn main() {
// This distribution contains reviewed security backports that an
// arbitrary system libssh2 may lack. Always compile this source tree.
println!("cargo:rerun-if-env-changed=LIBSSH2_SYS_USE_PKG_CONFIG");
if env::var_os("LIBSSH2_SYS_USE_PKG_CONFIG").is_some() {
panic!("This distribution requires its patched bundled libssh2; unset LIBSSH2_SYS_USE_PKG_CONFIG");
}
println!("cargo:rerun-if-changed=libssh2/src");
println!("cargo:rerun-if-changed=libssh2/include");
println!("cargo:rerun-if-changed=libssh2/libssh2.pc.in");
let target = env::var("TARGET").unwrap();
let profile = env::var("PROFILE").unwrap();
let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
let mut cfg = cc::Build::new();
let include = dst.join("include");
println!("cargo:include={}", include.display());
println!("cargo:root={}", dst.display());
let build = dst.join("build");
cfg.out_dir(&build);
fs::create_dir_all(&build).unwrap();
fs::create_dir_all(&include).unwrap();
fs::copy("libssh2/include/libssh2.h", include.join("libssh2.h")).unwrap();
fs::copy(
"libssh2/include/libssh2_publickey.h",
include.join("libssh2_publickey.h"),
)
.unwrap();
fs::copy(
"libssh2/include/libssh2_sftp.h",
include.join("libssh2_sftp.h"),
)
.unwrap();
cfg.file("libssh2/src/agent.c")
.file("libssh2/src/bcrypt_pbkdf.c")
.file("libssh2/src/blowfish.c")
.file("libssh2/src/chacha.c")
.file("libssh2/src/channel.c")
.file("libssh2/src/cipher-chachapoly.c")
.file("libssh2/src/comp.c")
.file("libssh2/src/crypt.c")
.file("libssh2/src/crypto.c")
.file("libssh2/src/global.c")
.file("libssh2/src/hostkey.c")
.file("libssh2/src/keepalive.c")
.file("libssh2/src/kex.c")
.file("libssh2/src/knownhost.c")
.file("libssh2/src/mac.c")
.file("libssh2/src/misc.c")
.file("libssh2/src/packet.c")
.file("libssh2/src/pem.c")
.file("libssh2/src/poly1305.c")
.file("libssh2/src/publickey.c")
.file("libssh2/src/scp.c")
.file("libssh2/src/session.c")
.file("libssh2/src/sftp.c")
.file("libssh2/src/transport.c")
.file("libssh2/src/userauth.c")
.file("libssh2/src/userauth_kbd_packet.c")
.include(&include)
.include("libssh2/src");
cfg.define("HAVE_LONGLONG", None);
if target.contains("windows") {
cfg.include("libssh2/win32");
cfg.define("LIBSSH2_WIN32", None);
cfg.file("libssh2/src/agent_win.c");
if env::var_os("CARGO_FEATURE_OPENSSL_ON_WIN32").is_some() {
cfg.define("LIBSSH2_OPENSSL", None);
cfg.define("HAVE_EVP_AES_128_CTR", None);
let lib_prefix = if target.contains("windows-msvc") {
"lib"
} else {
""
};
println!("cargo:rustc-link-lib=static={lib_prefix}ssl");
println!("cargo:rustc-link-lib=static={lib_prefix}crypto");
println!("cargo:rustc-link-lib=advapi32");
} else {
cfg.define("LIBSSH2_WINCNG", None);
}
} else {
cfg.flag("-fvisibility=hidden");
cfg.define("HAVE_SNPRINTF", None);
cfg.define("HAVE_UNISTD_H", None);
cfg.define("HAVE_INTTYPES_H", None);
cfg.define("HAVE_STDLIB_H", None);
cfg.define("HAVE_SYS_SELECT_H", None);
cfg.define("HAVE_SYS_SOCKET_H", None);
cfg.define("HAVE_SYS_IOCTL_H", None);
cfg.define("HAVE_SYS_TIME_H", None);
cfg.define("HAVE_SYS_UN_H", None);
cfg.define("HAVE_O_NONBLOCK", None);
cfg.define("LIBSSH2_OPENSSL", None);
cfg.define("HAVE_LIBCRYPT32", None);
cfg.define("HAVE_EVP_AES_128_CTR", None);
cfg.define("HAVE_POLL", None);
cfg.define("HAVE_GETTIMEOFDAY", None);
// Create `libssh2_config.h`
let config = fs::read_to_string("libssh2/src/libssh2_config_cmake.h.in").unwrap();
let config = config
.lines()
.filter(|l| !l.contains("#cmakedefine"))
.collect::<Vec<_>>()
.join("\n");
fs::write(build.join("libssh2_config.h"), &config).unwrap();
cfg.include(&build);
}
/* Enable newer diffie-hellman-group-exchange-sha1 syntax */
cfg.define("LIBSSH2_DH_GEX_NEW", None);
cfg.define("LIBSSH2_HAVE_ZLIB", None);
if profile.contains("debug") {
cfg.define("LIBSSH2DEBUG", None);
}
println!("cargo:rerun-if-env-changed=DEP_Z_INCLUDE");
if let Some(path) = env::var_os("DEP_Z_INCLUDE") {
cfg.include(path);
}
println!("cargo:rerun-if-env-changed=DEP_OPENSSL_INCLUDE");
if let Some(path) = env::var_os("DEP_OPENSSL_INCLUDE") {
if let Some(path) = env::split_paths(&path).next() {
if let Some(path) = path.to_str() {
if path.len() > 0 {
cfg.include(path);
}
}
}
}
let libssh2h = fs::read_to_string("libssh2/include/libssh2.h").unwrap();
let version_line = libssh2h
.lines()
.find(|l| l.contains("LIBSSH2_VERSION"))
.unwrap();
let version = &version_line[version_line.find('"').unwrap() + 1..version_line.len() - 1];
let pkgconfig = dst.join("lib/pkgconfig");
fs::create_dir_all(&pkgconfig).unwrap();
fs::write(
pkgconfig.join("libssh2.pc"),
fs::read_to_string("libssh2/libssh2.pc.in")
.unwrap()
.replace("@prefix@", dst.to_str().unwrap())
.replace("@exec_prefix@", "")
.replace("@libdir@", dst.join("lib").to_str().unwrap())
.replace("@includedir@", include.to_str().unwrap())
.replace("@LIBS@", "")
.replace("@LIBSREQUIRED@", "")
.replace("@LIBSSH2VER@", version),
)
.unwrap();
cfg.warnings(false);
cfg.compile("ssh2");
if target.contains("windows") {
println!("cargo:rustc-link-lib=bcrypt");
println!("cargo:rustc-link-lib=crypt32");
println!("cargo:rustc-link-lib=user32");
println!("cargo:rustc-link-lib=ntdll");
}
}
+787
View File
@@ -0,0 +1,787 @@
#![doc(html_root_url = "http://alexcrichton.com/ssh2-rs")]
#![allow(bad_style)]
#![allow(unused_extern_crates)]
extern crate libc;
extern crate libz_sys;
#[cfg(unix)]
extern crate openssl_sys;
use libc::ssize_t;
use libc::{c_char, c_int, c_long, c_uchar, c_uint, c_ulong, c_void, size_t};
pub const SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT: c_int = 1;
pub const SSH_DISCONNECT_PROTOCOL_ERROR: c_int = 2;
pub const SSH_DISCONNECT_KEY_EXCHANGE_FAILED: c_int = 3;
pub const SSH_DISCONNECT_RESERVED: c_int = 4;
pub const SSH_DISCONNECT_MAC_ERROR: c_int = 5;
pub const SSH_DISCONNECT_COMPRESSION_ERROR: c_int = 6;
pub const SSH_DISCONNECT_SERVICE_NOT_AVAILABLE: c_int = 7;
pub const SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED: c_int = 8;
pub const SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE: c_int = 9;
pub const SSH_DISCONNECT_CONNECTION_LOST: c_int = 10;
pub const SSH_DISCONNECT_BY_APPLICATION: c_int = 11;
pub const SSH_DISCONNECT_TOO_MANY_CONNECTIONS: c_int = 12;
pub const SSH_DISCONNECT_AUTH_CANCELLED_BY_USER: c_int = 13;
pub const SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE: c_int = 14;
pub const SSH_DISCONNECT_ILLEGAL_USER_NAME: c_int = 15;
pub const LIBSSH2_FLAG_SIGPIPE: c_int = 1;
pub const LIBSSH2_FLAG_COMPRESS: c_int = 2;
pub const LIBSSH2_HOSTKEY_TYPE_UNKNOWN: c_int = 0;
pub const LIBSSH2_HOSTKEY_TYPE_RSA: c_int = 1;
pub const LIBSSH2_HOSTKEY_TYPE_DSS: c_int = 2;
pub const LIBSSH2_HOSTKEY_TYPE_ECDSA_256: c_int = 3;
pub const LIBSSH2_HOSTKEY_TYPE_ECDSA_384: c_int = 4;
pub const LIBSSH2_HOSTKEY_TYPE_ECDSA_521: c_int = 5;
pub const LIBSSH2_HOSTKEY_TYPE_ED25519: c_int = 6;
pub const LIBSSH2_METHOD_KEX: c_int = 0;
pub const LIBSSH2_METHOD_HOSTKEY: c_int = 1;
pub const LIBSSH2_METHOD_CRYPT_CS: c_int = 2;
pub const LIBSSH2_METHOD_CRYPT_SC: c_int = 3;
pub const LIBSSH2_METHOD_MAC_CS: c_int = 4;
pub const LIBSSH2_METHOD_MAC_SC: c_int = 5;
pub const LIBSSH2_METHOD_COMP_CS: c_int = 6;
pub const LIBSSH2_METHOD_COMP_SC: c_int = 7;
pub const LIBSSH2_METHOD_LANG_CS: c_int = 8;
pub const LIBSSH2_METHOD_LANG_SC: c_int = 9;
pub const LIBSSH2_METHOD_SIGN_ALGO: c_int = 10;
pub const LIBSSH2_CHANNEL_PACKET_DEFAULT: c_uint = 32768;
pub const LIBSSH2_CHANNEL_WINDOW_DEFAULT: c_uint = 2 * 1024 * 1024;
pub const LIBSSH2_ERROR_BANNER_RECV: c_int = -2;
pub const LIBSSH2_ERROR_BANNER_SEND: c_int = -3;
pub const LIBSSH2_ERROR_INVALID_MAC: c_int = -4;
pub const LIBSSH2_ERROR_KEX_FAILURE: c_int = -5;
pub const LIBSSH2_ERROR_ALLOC: c_int = -6;
pub const LIBSSH2_ERROR_SOCKET_SEND: c_int = -7;
pub const LIBSSH2_ERROR_KEY_EXCHANGE_FAILURE: c_int = -8;
pub const LIBSSH2_ERROR_TIMEOUT: c_int = -9;
pub const LIBSSH2_ERROR_HOSTKEY_INIT: c_int = -10;
pub const LIBSSH2_ERROR_HOSTKEY_SIGN: c_int = -11;
pub const LIBSSH2_ERROR_DECRYPT: c_int = -12;
pub const LIBSSH2_ERROR_SOCKET_DISCONNECT: c_int = -13;
pub const LIBSSH2_ERROR_PROTO: c_int = -14;
pub const LIBSSH2_ERROR_PASSWORD_EXPIRED: c_int = -15;
pub const LIBSSH2_ERROR_FILE: c_int = -16;
pub const LIBSSH2_ERROR_METHOD_NONE: c_int = -17;
pub const LIBSSH2_ERROR_AUTHENTICATION_FAILED: c_int = -18;
pub const LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED: c_int = LIBSSH2_ERROR_AUTHENTICATION_FAILED;
pub const LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED: c_int = -19;
pub const LIBSSH2_ERROR_CHANNEL_OUTOFORDER: c_int = -20;
pub const LIBSSH2_ERROR_CHANNEL_FAILURE: c_int = -21;
pub const LIBSSH2_ERROR_CHANNEL_REQUEST_DENIED: c_int = -22;
pub const LIBSSH2_ERROR_CHANNEL_UNKNOWN: c_int = -23;
pub const LIBSSH2_ERROR_CHANNEL_WINDOW_EXCEEDED: c_int = -24;
pub const LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED: c_int = -25;
pub const LIBSSH2_ERROR_CHANNEL_CLOSED: c_int = -26;
pub const LIBSSH2_ERROR_CHANNEL_EOF_SENT: c_int = -27;
pub const LIBSSH2_ERROR_SCP_PROTOCOL: c_int = -28;
pub const LIBSSH2_ERROR_ZLIB: c_int = -29;
pub const LIBSSH2_ERROR_SOCKET_TIMEOUT: c_int = -30;
pub const LIBSSH2_ERROR_SFTP_PROTOCOL: c_int = -31;
pub const LIBSSH2_ERROR_REQUEST_DENIED: c_int = -32;
pub const LIBSSH2_ERROR_METHOD_NOT_SUPPORTED: c_int = -33;
pub const LIBSSH2_ERROR_INVAL: c_int = -34;
pub const LIBSSH2_ERROR_INVALID_POLL_TYPE: c_int = -35;
pub const LIBSSH2_ERROR_PUBLICKEY_PROTOCOL: c_int = -36;
pub const LIBSSH2_ERROR_EAGAIN: c_int = -37;
pub const LIBSSH2_ERROR_BUFFER_TOO_SMALL: c_int = -38;
pub const LIBSSH2_ERROR_BAD_USE: c_int = -39;
pub const LIBSSH2_ERROR_COMPRESS: c_int = -40;
pub const LIBSSH2_ERROR_OUT_OF_BOUNDARY: c_int = -41;
pub const LIBSSH2_ERROR_AGENT_PROTOCOL: c_int = -42;
pub const LIBSSH2_ERROR_SOCKET_RECV: c_int = -43;
pub const LIBSSH2_ERROR_ENCRYPT: c_int = -44;
pub const LIBSSH2_ERROR_BAD_SOCKET: c_int = -45;
pub const LIBSSH2_ERROR_KNOWN_HOSTS: c_int = -46;
pub const LIBSSH2_ERROR_CHANNEL_WINDOW_FULL: c_int = -47;
pub const LIBSSH2_ERROR_KEYFILE_AUTH_FAILED: c_int = -48;
pub const LIBSSH2_ERROR_RANDGEN: c_int = -49;
pub const LIBSSH2_ERROR_MISSING_USERAUTH_BANNER: c_int = -50;
pub const LIBSSH2_ERROR_ALGO_UNSUPPORTED: c_int = -51;
pub const LIBSSH2_FX_EOF: c_int = 1;
pub const LIBSSH2_FX_NO_SUCH_FILE: c_int = 2;
pub const LIBSSH2_FX_PERMISSION_DENIED: c_int = 3;
pub const LIBSSH2_FX_FAILURE: c_int = 4;
pub const LIBSSH2_FX_BAD_MESSAGE: c_int = 5;
pub const LIBSSH2_FX_NO_CONNECTION: c_int = 6;
pub const LIBSSH2_FX_CONNECTION_LOST: c_int = 7;
pub const LIBSSH2_FX_OP_UNSUPPORTED: c_int = 8;
pub const LIBSSH2_FX_INVALID_HANDLE: c_int = 9;
pub const LIBSSH2_FX_NO_SUCH_PATH: c_int = 10;
pub const LIBSSH2_FX_FILE_ALREADY_EXISTS: c_int = 11;
pub const LIBSSH2_FX_WRITE_PROTECT: c_int = 12;
pub const LIBSSH2_FX_NO_MEDIA: c_int = 13;
pub const LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM: c_int = 14;
pub const LIBSSH2_FX_QUOTA_EXCEEDED: c_int = 15;
pub const LIBSSH2_FX_UNKNOWN_PRINCIPAL: c_int = 16;
pub const LIBSSH2_FX_LOCK_CONFLICT: c_int = 17;
pub const LIBSSH2_FX_DIR_NOT_EMPTY: c_int = 18;
pub const LIBSSH2_FX_NOT_A_DIRECTORY: c_int = 19;
pub const LIBSSH2_FX_INVALID_FILENAME: c_int = 20;
pub const LIBSSH2_FX_LINK_LOOP: c_int = 21;
pub const LIBSSH2_HOSTKEY_HASH_MD5: c_int = 1;
pub const LIBSSH2_HOSTKEY_HASH_SHA1: c_int = 2;
pub const LIBSSH2_HOSTKEY_HASH_SHA256: c_int = 3;
pub const LIBSSH2_KNOWNHOST_FILE_OPENSSH: c_int = 1;
pub const LIBSSH2_KNOWNHOST_CHECK_MATCH: c_int = 0;
pub const LIBSSH2_KNOWNHOST_CHECK_MISMATCH: c_int = 1;
pub const LIBSSH2_KNOWNHOST_CHECK_NOTFOUND: c_int = 2;
pub const LIBSSH2_KNOWNHOST_CHECK_FAILURE: c_int = 3;
pub const LIBSSH2_KNOWNHOST_TYPE_PLAIN: c_int = 1;
pub const LIBSSH2_KNOWNHOST_TYPE_SHA1: c_int = 2;
pub const LIBSSH2_KNOWNHOST_TYPE_CUSTOM: c_int = 3;
pub const LIBSSH2_KNOWNHOST_KEYENC_RAW: c_int = 1 << 16;
pub const LIBSSH2_KNOWNHOST_KEYENC_BASE64: c_int = 2 << 16;
pub const LIBSSH2_KNOWNHOST_KEY_RSA1: c_int = 1 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_SSHRSA: c_int = 2 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_SSHDSS: c_int = 3 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_ECDSA_256: c_int = 4 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_ECDSA_384: c_int = 5 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_ECDSA_521: c_int = 6 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_ED25519: c_int = 7 << 18;
pub const LIBSSH2_KNOWNHOST_KEY_UNKNOWN: c_int = 15 << 18;
pub const LIBSSH2_FXF_READ: c_ulong = 0x00000001;
pub const LIBSSH2_FXF_WRITE: c_ulong = 0x00000002;
pub const LIBSSH2_FXF_APPEND: c_ulong = 0x00000004;
pub const LIBSSH2_FXF_CREAT: c_ulong = 0x00000008;
pub const LIBSSH2_FXF_TRUNC: c_ulong = 0x00000010;
pub const LIBSSH2_FXF_EXCL: c_ulong = 0x00000020;
pub const LIBSSH2_SFTP_OPENFILE: c_int = 0;
pub const LIBSSH2_SFTP_OPENDIR: c_int = 1;
pub const LIBSSH2_SFTP_ATTR_SIZE: c_ulong = 0x00000001;
pub const LIBSSH2_SFTP_ATTR_UIDGID: c_ulong = 0x00000002;
pub const LIBSSH2_SFTP_ATTR_PERMISSIONS: c_ulong = 0x00000004;
pub const LIBSSH2_SFTP_ATTR_ACMODTIME: c_ulong = 0x00000008;
pub const LIBSSH2_SFTP_ATTR_EXTENDED: c_ulong = 0x80000000;
pub const LIBSSH2_SFTP_STAT: c_int = 0;
pub const LIBSSH2_SFTP_LSTAT: c_int = 1;
pub const LIBSSH2_SFTP_SETSTAT: c_int = 2;
pub const LIBSSH2_SFTP_SYMLINK: c_int = 0;
pub const LIBSSH2_SFTP_READLINK: c_int = 1;
pub const LIBSSH2_SFTP_REALPATH: c_int = 2;
pub const LIBSSH2_SFTP_RENAME_OVERWRITE: c_long = 0x1;
pub const LIBSSH2_SFTP_RENAME_ATOMIC: c_long = 0x2;
pub const LIBSSH2_SFTP_RENAME_NATIVE: c_long = 0x4;
pub const LIBSSH2_INIT_NO_CRYPTO: c_int = 0x1;
pub const LIBSSH2_SFTP_S_IFMT: c_ulong = 0o170000;
pub const LIBSSH2_SFTP_S_IFIFO: c_ulong = 0o010000;
pub const LIBSSH2_SFTP_S_IFCHR: c_ulong = 0o020000;
pub const LIBSSH2_SFTP_S_IFDIR: c_ulong = 0o040000;
pub const LIBSSH2_SFTP_S_IFBLK: c_ulong = 0o060000;
pub const LIBSSH2_SFTP_S_IFREG: c_ulong = 0o100000;
pub const LIBSSH2_SFTP_S_IFLNK: c_ulong = 0o120000;
pub const LIBSSH2_SFTP_S_IFSOCK: c_ulong = 0o140000;
pub const LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL: c_int = 0;
pub const LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE: c_int = 1;
pub const LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE: c_int = 2;
pub const LIBSSH2_SESSION_BLOCK_INBOUND: c_int = 1;
pub const LIBSSH2_SESSION_BLOCK_OUTBOUND: c_int = 2;
pub const LIBSSH2_TRACE_TRANS : c_int = 1<<1;
pub const LIBSSH2_TRACE_KEX : c_int = 1<<2;
pub const LIBSSH2_TRACE_AUTH : c_int = 1<<3;
pub const LIBSSH2_TRACE_CONN : c_int = 1<<4;
pub const LIBSSH2_TRACE_SCP : c_int = 1<<5;
pub const LIBSSH2_TRACE_SFTP : c_int = 1<<6;
pub const LIBSSH2_TRACE_ERROR : c_int = 1<<7;
pub const LIBSSH2_TRACE_PUBLICKEY : c_int = 1<<8;
pub const LIBSSH2_TRACE_SOCKET : c_int = 1<<9;
pub enum LIBSSH2_SESSION {}
pub enum LIBSSH2_AGENT {}
pub enum LIBSSH2_CHANNEL {}
pub enum LIBSSH2_LISTENER {}
pub enum LIBSSH2_KNOWNHOSTS {}
pub enum LIBSSH2_SFTP {}
pub enum LIBSSH2_SFTP_HANDLE {}
pub type libssh2_int64_t = i64;
pub type libssh2_uint64_t = u64;
// libssh2_struct_stat is a typedef for libc::stat on all platforms, however,
// Windows has a bunch of legacy around struct stat that makes things more
// complicated to validate with systest.
// The most reasonable looking solution to this is a newtype that derefs
// to libc::stat.
// We cannot use `pub struct libssh2_struct_stat(pub libc::stat)` because
// that triggers a `no tuple structs in FFI` error.
#[repr(C)]
pub struct libssh2_struct_stat(libc::stat);
impl std::ops::Deref for libssh2_struct_stat {
type Target = libc::stat;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[repr(C)]
pub struct libssh2_agent_publickey {
pub magic: c_uint,
pub node: *mut c_void,
pub blob: *mut c_uchar,
pub blob_len: size_t,
pub comment: *mut c_char,
}
#[repr(C)]
pub struct libssh2_knownhost {
pub magic: c_uint,
pub node: *mut c_void,
pub name: *mut c_char,
pub key: *mut c_char,
pub typemask: c_int,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct LIBSSH2_SFTP_ATTRIBUTES {
pub flags: c_ulong,
pub filesize: libssh2_uint64_t,
pub uid: c_ulong,
pub gid: c_ulong,
pub permissions: c_ulong,
pub atime: c_ulong,
pub mtime: c_ulong,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct LIBSSH2_SFTP_STATVFS {
pub f_bsize: libssh2_uint64_t,
pub f_frsize: libssh2_uint64_t,
pub f_blocks: libssh2_uint64_t,
pub f_bfree: libssh2_uint64_t,
pub f_bavail: libssh2_uint64_t,
pub f_files: libssh2_uint64_t,
pub f_ffree: libssh2_uint64_t,
pub f_favail: libssh2_uint64_t,
pub f_fsid: libssh2_uint64_t,
pub f_flag: libssh2_uint64_t,
pub f_namemax: libssh2_uint64_t,
}
pub type LIBSSH2_ALLOC_FUNC = extern "C" fn(size_t, *mut *mut c_void) -> *mut c_void;
pub type LIBSSH2_FREE_FUNC = extern "C" fn(*mut c_void, *mut *mut c_void);
pub type LIBSSH2_REALLOC_FUNC = extern "C" fn(*mut c_void, size_t, *mut *mut c_void) -> *mut c_void;
pub type LIBSSH2_PASSWD_CHANGEREQ_FUNC = extern "C" fn(
sess: *mut LIBSSH2_SESSION,
newpw: *mut *mut c_char,
newpw_len: *mut c_int,
abstrakt: *mut *mut c_void,
);
pub type LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC = extern "C" fn(
username: *const c_char,
username_len: c_int,
instruction: *const c_char,
instruction_len: c_int,
num_prompts: c_int,
prompts: *const LIBSSH2_USERAUTH_KBDINT_PROMPT,
responses: *mut LIBSSH2_USERAUTH_KBDINT_RESPONSE,
abstrakt: *mut *mut c_void,
);
#[repr(C)]
pub struct LIBSSH2_USERAUTH_KBDINT_PROMPT {
pub text: *mut c_uchar,
pub length: size_t,
pub echo: c_uchar,
}
#[repr(C)]
pub struct LIBSSH2_USERAUTH_KBDINT_RESPONSE {
pub text: *mut c_char,
pub length: c_uint,
}
#[cfg(unix)]
pub type libssh2_socket_t = c_int;
#[cfg(all(windows, target_pointer_width = "32"))]
pub type libssh2_socket_t = u32;
#[cfg(all(windows, target_pointer_width = "64"))]
pub type libssh2_socket_t = u64;
extern "C" {
// misc
pub fn libssh2_init(flag: c_int) -> c_int;
pub fn libssh2_exit();
pub fn libssh2_free(sess: *mut LIBSSH2_SESSION, ptr: *mut c_void);
pub fn libssh2_hostkey_hash(session: *mut LIBSSH2_SESSION, hash_type: c_int) -> *const c_char;
pub fn libssh2_trace(session: *mut LIBSSH2_SESSION, bitmask: c_int) -> c_int;
// session
pub fn libssh2_session_init_ex(
alloc: Option<LIBSSH2_ALLOC_FUNC>,
free: Option<LIBSSH2_FREE_FUNC>,
realloc: Option<LIBSSH2_REALLOC_FUNC>,
abstrakt: *mut c_void,
) -> *mut LIBSSH2_SESSION;
pub fn libssh2_session_abstract(session: *mut LIBSSH2_SESSION) -> *mut *mut c_void;
pub fn libssh2_session_free(sess: *mut LIBSSH2_SESSION) -> c_int;
pub fn libssh2_session_banner_get(sess: *mut LIBSSH2_SESSION) -> *const c_char;
pub fn libssh2_session_banner_set(sess: *mut LIBSSH2_SESSION, banner: *const c_char) -> c_int;
pub fn libssh2_session_disconnect_ex(
sess: *mut LIBSSH2_SESSION,
reason: c_int,
description: *const c_char,
lang: *const c_char,
) -> c_int;
pub fn libssh2_session_flag(sess: *mut LIBSSH2_SESSION, flag: c_int, value: c_int) -> c_int;
pub fn libssh2_session_get_blocking(session: *mut LIBSSH2_SESSION) -> c_int;
pub fn libssh2_session_get_timeout(sess: *mut LIBSSH2_SESSION) -> c_long;
pub fn libssh2_session_hostkey(
sess: *mut LIBSSH2_SESSION,
len: *mut size_t,
kind: *mut c_int,
) -> *const c_char;
pub fn libssh2_session_method_pref(
sess: *mut LIBSSH2_SESSION,
method_type: c_int,
prefs: *const c_char,
) -> c_int;
pub fn libssh2_session_methods(sess: *mut LIBSSH2_SESSION, method_type: c_int)
-> *const c_char;
pub fn libssh2_session_set_blocking(session: *mut LIBSSH2_SESSION, blocking: c_int);
pub fn libssh2_session_set_timeout(session: *mut LIBSSH2_SESSION, timeout: c_long);
pub fn libssh2_session_supported_algs(
session: *mut LIBSSH2_SESSION,
method_type: c_int,
algs: *mut *mut *const c_char,
) -> c_int;
pub fn libssh2_session_last_errno(sess: *mut LIBSSH2_SESSION) -> c_int;
pub fn libssh2_session_last_error(
sess: *mut LIBSSH2_SESSION,
msg: *mut *mut c_char,
len: *mut c_int,
want_buf: c_int,
) -> c_int;
pub fn libssh2_session_handshake(sess: *mut LIBSSH2_SESSION, socket: libssh2_socket_t)
-> c_int;
pub fn libssh2_keepalive_config(
sess: *mut LIBSSH2_SESSION,
want_reply: c_int,
interval: c_uint,
);
pub fn libssh2_keepalive_send(sess: *mut LIBSSH2_SESSION, seconds_to_next: *mut c_int)
-> c_int;
pub fn libssh2_session_block_directions(sess: *mut LIBSSH2_SESSION) -> c_int;
// agent
pub fn libssh2_agent_init(sess: *mut LIBSSH2_SESSION) -> *mut LIBSSH2_AGENT;
pub fn libssh2_agent_free(agent: *mut LIBSSH2_AGENT);
pub fn libssh2_agent_connect(agent: *mut LIBSSH2_AGENT) -> c_int;
pub fn libssh2_agent_disconnect(agent: *mut LIBSSH2_AGENT) -> c_int;
pub fn libssh2_agent_list_identities(agent: *mut LIBSSH2_AGENT) -> c_int;
pub fn libssh2_agent_get_identity(
agent: *mut LIBSSH2_AGENT,
store: *mut *mut libssh2_agent_publickey,
prev: *mut libssh2_agent_publickey,
) -> c_int;
pub fn libssh2_agent_userauth(
agent: *mut LIBSSH2_AGENT,
username: *const c_char,
identity: *mut libssh2_agent_publickey,
) -> c_int;
pub fn libssh2_agent_set_identity_path(agent: *mut LIBSSH2_AGENT, path: *const c_char);
pub fn libssh2_agent_get_identity_path(agent: *mut LIBSSH2_AGENT) -> *const c_char;
// channels
pub fn libssh2_channel_free(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_close(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_wait_closed(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_wait_eof(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_eof(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_process_startup(
chan: *mut LIBSSH2_CHANNEL,
req: *const c_char,
req_len: c_uint,
msg: *const c_char,
msg_len: c_uint,
) -> c_int;
pub fn libssh2_channel_flush_ex(chan: *mut LIBSSH2_CHANNEL, streamid: c_int) -> c_int;
pub fn libssh2_channel_write_ex(
chan: *mut LIBSSH2_CHANNEL,
stream_id: c_int,
buf: *const c_char,
buflen: size_t,
) -> ssize_t;
pub fn libssh2_channel_get_exit_signal(
chan: *mut LIBSSH2_CHANNEL,
exitsignal: *mut *mut c_char,
exitsignal_len: *mut size_t,
errmsg: *mut *mut c_char,
errmsg_len: *mut size_t,
langtag: *mut *mut c_char,
langtag_len: *mut size_t,
) -> c_int;
pub fn libssh2_channel_get_exit_status(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_open_ex(
sess: *mut LIBSSH2_SESSION,
channel_type: *const c_char,
channel_type_len: c_uint,
window_size: c_uint,
packet_size: c_uint,
message: *const c_char,
message_len: c_uint,
) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_channel_read_ex(
chan: *mut LIBSSH2_CHANNEL,
stream_id: c_int,
buf: *mut c_char,
buflen: size_t,
) -> ssize_t;
pub fn libssh2_channel_setenv_ex(
chan: *mut LIBSSH2_CHANNEL,
var: *const c_char,
varlen: c_uint,
val: *const c_char,
vallen: c_uint,
) -> c_int;
pub fn libssh2_channel_send_eof(chan: *mut LIBSSH2_CHANNEL) -> c_int;
pub fn libssh2_channel_request_pty_ex(
chan: *mut LIBSSH2_CHANNEL,
term: *const c_char,
termlen: c_uint,
modes: *const c_char,
modeslen: c_uint,
width: c_int,
height: c_int,
width_px: c_int,
height_px: c_int,
) -> c_int;
pub fn libssh2_channel_request_pty_size_ex(
chan: *mut LIBSSH2_CHANNEL,
width: c_int,
height: c_int,
width_px: c_int,
height_px: c_int,
) -> c_int;
pub fn libssh2_channel_window_read_ex(
chan: *mut LIBSSH2_CHANNEL,
read_avail: *mut c_ulong,
window_size_initial: *mut c_ulong,
) -> c_ulong;
pub fn libssh2_channel_window_write_ex(
chan: *mut LIBSSH2_CHANNEL,
window_size_initial: *mut c_ulong,
) -> c_ulong;
pub fn libssh2_channel_receive_window_adjust2(
chan: *mut LIBSSH2_CHANNEL,
adjust: c_ulong,
force: c_uchar,
window: *mut c_uint,
) -> c_int;
pub fn libssh2_channel_direct_tcpip_ex(
ses: *mut LIBSSH2_SESSION,
host: *const c_char,
port: c_int,
shost: *const c_char,
sport: c_int,
) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_channel_direct_streamlocal_ex(
ses: *mut LIBSSH2_SESSION,
socket_path: *const c_char,
shost: *const c_char,
sport: c_int,
) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_channel_forward_accept(listener: *mut LIBSSH2_LISTENER) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_channel_forward_cancel(listener: *mut LIBSSH2_LISTENER) -> c_int;
pub fn libssh2_channel_forward_listen_ex(
sess: *mut LIBSSH2_SESSION,
host: *const c_char,
port: c_int,
bound_port: *mut c_int,
queue_maxsize: c_int,
) -> *mut LIBSSH2_LISTENER;
pub fn libssh2_channel_handle_extended_data2(
channel: *mut LIBSSH2_CHANNEL,
mode: c_int,
) -> c_int;
pub fn libssh2_channel_request_auth_agent(channel: *mut LIBSSH2_CHANNEL) -> c_int;
// userauth
pub fn libssh2_userauth_banner(sess: *mut LIBSSH2_SESSION, banner: *mut *mut c_char) -> c_int;
pub fn libssh2_userauth_authenticated(sess: *mut LIBSSH2_SESSION) -> c_int;
pub fn libssh2_userauth_list(
sess: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: c_uint,
) -> *mut c_char;
pub fn libssh2_userauth_hostbased_fromfile_ex(
sess: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: c_uint,
publickey: *const c_char,
privatekey: *const c_char,
passphrase: *const c_char,
hostname: *const c_char,
hostname_len: c_uint,
local_username: *const c_char,
local_len: c_uint,
) -> c_int;
pub fn libssh2_userauth_publickey_fromfile_ex(
sess: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: c_uint,
publickey: *const c_char,
privatekey: *const c_char,
passphrase: *const c_char,
) -> c_int;
pub fn libssh2_userauth_publickey_frommemory(
sess: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: size_t,
publickeydata: *const c_char,
publickeydata_len: size_t,
privatekeydata: *const c_char,
privatekeydata_len: size_t,
passphrase: *const c_char,
) -> c_int;
pub fn libssh2_userauth_password_ex(
session: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: c_uint,
password: *const c_char,
password_len: c_uint,
password_change_cb: Option<LIBSSH2_PASSWD_CHANGEREQ_FUNC>,
) -> c_int;
pub fn libssh2_userauth_keyboard_interactive_ex(
session: *mut LIBSSH2_SESSION,
username: *const c_char,
username_len: c_uint,
callback: Option<LIBSSH2_USERAUTH_KBDINT_RESPONSE_FUNC>,
) -> c_int;
// knownhost
pub fn libssh2_knownhost_free(hosts: *mut LIBSSH2_KNOWNHOSTS);
pub fn libssh2_knownhost_addc(
hosts: *mut LIBSSH2_KNOWNHOSTS,
host: *const c_char,
salt: *const c_char,
key: *const c_char,
keylen: size_t,
comment: *const c_char,
commentlen: size_t,
typemask: c_int,
store: *mut *mut libssh2_knownhost,
) -> c_int;
pub fn libssh2_knownhost_check(
hosts: *mut LIBSSH2_KNOWNHOSTS,
host: *const c_char,
key: *const c_char,
keylen: size_t,
typemask: c_int,
knownhost: *mut *mut libssh2_knownhost,
) -> c_int;
pub fn libssh2_knownhost_checkp(
hosts: *mut LIBSSH2_KNOWNHOSTS,
host: *const c_char,
port: c_int,
key: *const c_char,
keylen: size_t,
typemask: c_int,
knownhost: *mut *mut libssh2_knownhost,
) -> c_int;
pub fn libssh2_knownhost_del(
hosts: *mut LIBSSH2_KNOWNHOSTS,
entry: *mut libssh2_knownhost,
) -> c_int;
pub fn libssh2_knownhost_get(
hosts: *mut LIBSSH2_KNOWNHOSTS,
store: *mut *mut libssh2_knownhost,
prev: *mut libssh2_knownhost,
) -> c_int;
pub fn libssh2_knownhost_readfile(
hosts: *mut LIBSSH2_KNOWNHOSTS,
filename: *const c_char,
kind: c_int,
) -> c_int;
pub fn libssh2_knownhost_readline(
hosts: *mut LIBSSH2_KNOWNHOSTS,
line: *const c_char,
len: size_t,
kind: c_int,
) -> c_int;
pub fn libssh2_knownhost_writefile(
hosts: *mut LIBSSH2_KNOWNHOSTS,
filename: *const c_char,
kind: c_int,
) -> c_int;
pub fn libssh2_knownhost_writeline(
hosts: *mut LIBSSH2_KNOWNHOSTS,
known: *mut libssh2_knownhost,
buffer: *mut c_char,
buflen: size_t,
outlen: *mut size_t,
kind: c_int,
) -> c_int;
pub fn libssh2_knownhost_init(sess: *mut LIBSSH2_SESSION) -> *mut LIBSSH2_KNOWNHOSTS;
// scp
#[deprecated(note = "dangerously unsafe on windows, use libssh2_scp_recv2 instead")]
pub fn libssh2_scp_recv(
sess: *mut LIBSSH2_SESSION,
path: *const c_char,
sb: *mut libc::stat,
) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_scp_recv2(
sess: *mut LIBSSH2_SESSION,
path: *const c_char,
sb: *mut libssh2_struct_stat,
) -> *mut LIBSSH2_CHANNEL;
pub fn libssh2_scp_send64(
sess: *mut LIBSSH2_SESSION,
path: *const c_char,
mode: c_int,
size: libssh2_int64_t,
mtime: libc::time_t,
atime: libc::time_t,
) -> *mut LIBSSH2_CHANNEL;
// sftp
pub fn libssh2_sftp_init(sess: *mut LIBSSH2_SESSION) -> *mut LIBSSH2_SFTP;
pub fn libssh2_sftp_shutdown(sftp: *mut LIBSSH2_SFTP) -> c_int;
pub fn libssh2_sftp_last_error(sftp: *mut LIBSSH2_SFTP) -> c_ulong;
pub fn libssh2_sftp_open_ex(
sftp: *mut LIBSSH2_SFTP,
filename: *const c_char,
filename_len: c_uint,
flags: c_ulong,
mode: c_long,
open_type: c_int,
) -> *mut LIBSSH2_SFTP_HANDLE;
pub fn libssh2_sftp_close_handle(handle: *mut LIBSSH2_SFTP_HANDLE) -> c_int;
pub fn libssh2_sftp_mkdir_ex(
sftp: *mut LIBSSH2_SFTP,
path: *const c_char,
path_len: c_uint,
mode: c_long,
) -> c_int;
pub fn libssh2_sftp_fsync(handle: *mut LIBSSH2_SFTP_HANDLE) -> c_int;
pub fn libssh2_sftp_fstat_ex(
handle: *mut LIBSSH2_SFTP_HANDLE,
attrs: *mut LIBSSH2_SFTP_ATTRIBUTES,
setstat: c_int,
) -> c_int;
pub fn libssh2_sftp_fstatvfs(
handle: *mut LIBSSH2_SFTP_HANDLE,
attrs: *mut LIBSSH2_SFTP_STATVFS,
) -> c_int;
pub fn libssh2_sftp_stat_ex(
sftp: *mut LIBSSH2_SFTP,
path: *const c_char,
path_len: c_uint,
stat_type: c_int,
attrs: *mut LIBSSH2_SFTP_ATTRIBUTES,
) -> c_int;
pub fn libssh2_sftp_read(
handle: *mut LIBSSH2_SFTP_HANDLE,
buf: *mut c_char,
len: size_t,
) -> ssize_t;
pub fn libssh2_sftp_symlink_ex(
sftp: *mut LIBSSH2_SFTP,
path: *const c_char,
path_len: c_uint,
target: *mut c_char,
target_len: c_uint,
link_type: c_int,
) -> c_int;
pub fn libssh2_sftp_rename_ex(
sftp: *mut LIBSSH2_SFTP,
src: *const c_char,
src_len: c_uint,
dst: *const c_char,
dst_len: c_uint,
flags: c_long,
) -> c_int;
pub fn libssh2_sftp_rmdir_ex(
sftp: *mut LIBSSH2_SFTP,
path: *const c_char,
path_len: c_uint,
) -> c_int;
pub fn libssh2_sftp_write(
handle: *mut LIBSSH2_SFTP_HANDLE,
buffer: *const c_char,
len: size_t,
) -> ssize_t;
pub fn libssh2_sftp_tell64(handle: *mut LIBSSH2_SFTP_HANDLE) -> libssh2_uint64_t;
pub fn libssh2_sftp_seek64(handle: *mut LIBSSH2_SFTP_HANDLE, off: libssh2_uint64_t);
pub fn libssh2_sftp_readdir_ex(
handle: *mut LIBSSH2_SFTP_HANDLE,
buffer: *mut c_char,
buffer_len: size_t,
longentry: *mut c_char,
longentry_len: size_t,
attrs: *mut LIBSSH2_SFTP_ATTRIBUTES,
) -> c_int;
pub fn libssh2_sftp_unlink_ex(
sftp: *mut LIBSSH2_SFTP,
filename: *const c_char,
filename_len: c_uint,
) -> c_int;
}
#[test]
fn smoke() {
unsafe { libssh2_init(0) };
}
#[doc(hidden)]
pub fn issue_14344_workaround() {}
pub fn init() {
use std::sync::Once;
static INIT: Once = Once::new();
INIT.call_once(|| unsafe {
platform_init();
assert_eq!(libc::atexit(shutdown), 0);
});
extern "C" fn shutdown() {
unsafe {
libssh2_exit();
}
}
#[cfg(unix)]
unsafe fn platform_init() {
// On Unix we want to funnel through openssl_sys to initialize OpenSSL,
// so be sure to tell libssh2 to not do its own thing as we've already
// taken care of it.
openssl_sys::init();
assert_eq!(libssh2_init(LIBSSH2_INIT_NO_CRYPTO), 0);
}
#[cfg(windows)]
unsafe fn platform_init() {
// On Windows we want to be sure to tell libssh2 to initialize
// everything, as we're not managing crypto elsewhere ourselves. Also to
// fix alexcrichton/git2-rs#202
assert_eq!(libssh2_init(0), 0);
}
}
+43
View File
@@ -0,0 +1,43 @@
/* Copyright (C) 2004-2007 Sara Golemon <sarag@libssh2.org>
* Copyright (C) 2005,2006 Mikhail Gusarov <dottedmag@dottedmag.net>
* Copyright (C) 2006-2007 The Written Word, Inc.
* Copyright (C) 2007 Eli Fant <elifantu@mail.ru>
* Copyright (C) 2009-2023 Daniel Stenberg
* Copyright (C) 2008, 2009 Simon Josefsson
* Copyright (C) 2000 Markus Friedl
* Copyright (C) 2015 Microsoft Corp.
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/
+9
View File
@@ -0,0 +1,9 @@
Copyright <YEAR> <COPYRIGHT HOLDER>
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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+11
View File
@@ -0,0 +1,11 @@
Copyright (c) <year> <owner>.
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. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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.
+5
View File
@@ -0,0 +1,5 @@
# Copyright Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) [year] [fullname]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+7
View File
@@ -0,0 +1,7 @@
SAX IS FREE -----------
I hereby abandon any property rights to SAX 2.0 (the Simple API for XML), and release all of the SAX 2.0 source code, compiled code, and documentation contained in this distribution into the Public Domain. SAX comes with NO WARRANTY or guarantee of fitness for any purpose.
David Megginson, Megginson Technologies Ltd.
2000-05-05
+21
View File
@@ -0,0 +1,21 @@
COPYRIGHT AND PERMISSION NOTICE
Copyright (C) Daniel Stenberg, <daniel@haxx.se>, and many contributors.
All rights reserved.
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization of the copyright holder.
File diff suppressed because it is too large. Load diff
+128
View File
@@ -0,0 +1,128 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*/
/* Note: This include file is only needed for using the
* publickey SUBSYSTEM which is not the same as publickey
* authentication. For authentication you only need libssh2.h
*
* For more information on the publickey subsystem,
* refer to IETF draft: secsh-publickey
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_PUBLICKEY_H
#define LIBSSH2_PUBLICKEY_H 1
#include "libssh2.h"
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
typedef struct _libssh2_publickey_attribute {
const char *name;
unsigned long name_len;
const char *value;
unsigned long value_len;
char mandatory;
} libssh2_publickey_attribute;
typedef struct _libssh2_publickey_list {
unsigned char *packet; /* For freeing */
const unsigned char *name;
unsigned long name_len;
const unsigned char *blob;
unsigned long blob_len;
unsigned long num_attrs;
libssh2_publickey_attribute *attrs; /* free me */
} libssh2_publickey_list;
/* Generally use the first macro here, but if both name and value are string
literals, you can use _fast() to take advantage of preprocessing */
#define libssh2_publickey_attribute(name, value, mandatory) \
{ (name), strlen(name), (value), strlen(value), (mandatory) },
#define libssh2_publickey_attribute_fast(name, value, mandatory) \
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
#ifdef __cplusplus
extern "C" {
#endif
/* Publickey Subsystem */
LIBSSH2_API LIBSSH2_PUBLICKEY *
libssh2_publickey_init(LIBSSH2_SESSION *session);
LIBSSH2_API int
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name,
unsigned long name_len,
const unsigned char *blob,
unsigned long blob_len, char overwrite,
unsigned long num_attrs,
const libssh2_publickey_attribute attrs[]);
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
num_attrs, attrs) \
libssh2_publickey_add_ex((pkey), \
(name), strlen(name), \
(blob), (blob_len), \
(overwrite), (num_attrs), (attrs))
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
const unsigned char *name,
unsigned long name_len,
const unsigned char *blob,
unsigned long blob_len);
#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
libssh2_publickey_remove_ex((pkey), \
(name), strlen(name), \
(blob), (blob_len))
LIBSSH2_API int
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
unsigned long *num_keys,
libssh2_publickey_list **pkey_list);
LIBSSH2_API void
libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
libssh2_publickey_list *pkey_list);
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LIBSSH2_PUBLICKEY_H */
+382
View File
@@ -0,0 +1,382 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_SFTP_H
#define LIBSSH2_SFTP_H 1
#include "libssh2.h"
#ifndef _WIN32
#include <unistd.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Note: Version 6 was documented at the time of writing
* However it was marked as "DO NOT IMPLEMENT" due to pending changes
*
* Let's start with Version 3 (The version found in OpenSSH) and go from there
*/
#define LIBSSH2_SFTP_VERSION 3
typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP;
typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE;
typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS;
/* Flags for open_ex() */
#define LIBSSH2_SFTP_OPENFILE 0
#define LIBSSH2_SFTP_OPENDIR 1
/* Flags for rename_ex() */
#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001
#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002
#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004
/* Flags for stat_ex() */
#define LIBSSH2_SFTP_STAT 0
#define LIBSSH2_SFTP_LSTAT 1
#define LIBSSH2_SFTP_SETSTAT 2
/* Flags for symlink_ex() */
#define LIBSSH2_SFTP_SYMLINK 0
#define LIBSSH2_SFTP_READLINK 1
#define LIBSSH2_SFTP_REALPATH 2
/* Flags for sftp_mkdir() */
#define LIBSSH2_SFTP_DEFAULT_MODE -1
/* SFTP attribute flag bits */
#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001
#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002
#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004
#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008
#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000
/* SFTP statvfs flag bits */
#define LIBSSH2_SFTP_ST_RDONLY 0x00000001
#define LIBSSH2_SFTP_ST_NOSUID 0x00000002
struct _LIBSSH2_SFTP_ATTRIBUTES {
/* If flags & ATTR_* bit is set, then the value in this struct will be
* meaningful Otherwise it should be ignored
*/
unsigned long flags;
libssh2_uint64_t filesize;
unsigned long uid, gid;
unsigned long permissions;
unsigned long atime, mtime;
};
struct _LIBSSH2_SFTP_STATVFS {
libssh2_uint64_t f_bsize; /* file system block size */
libssh2_uint64_t f_frsize; /* fragment size */
libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */
libssh2_uint64_t f_bfree; /* # free blocks */
libssh2_uint64_t f_bavail; /* # free blocks for non-root */
libssh2_uint64_t f_files; /* # inodes */
libssh2_uint64_t f_ffree; /* # free inodes */
libssh2_uint64_t f_favail; /* # free inodes for non-root */
libssh2_uint64_t f_fsid; /* file system ID */
libssh2_uint64_t f_flag; /* mount flags */
libssh2_uint64_t f_namemax; /* maximum filename length */
};
/* SFTP filetypes */
#define LIBSSH2_SFTP_TYPE_REGULAR 1
#define LIBSSH2_SFTP_TYPE_DIRECTORY 2
#define LIBSSH2_SFTP_TYPE_SYMLINK 3
#define LIBSSH2_SFTP_TYPE_SPECIAL 4
#define LIBSSH2_SFTP_TYPE_UNKNOWN 5
#define LIBSSH2_SFTP_TYPE_SOCKET 6
#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7
#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8
#define LIBSSH2_SFTP_TYPE_FIFO 9
/*
* Reproduce the POSIX file modes here for systems that are not POSIX
* compliant.
*
* These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
*/
/* File type */
#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */
#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */
#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */
#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */
#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */
#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */
#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */
#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */
/* File mode */
/* Read, write, execute/search by owner */
#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */
#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */
#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */
#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */
/* Read, write, execute/search by group */
#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */
#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */
#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */
#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */
/* Read, write, execute/search by others */
#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */
#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */
#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */
#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */
/* macros to check for specific file types, added in 1.2.5 */
#define LIBSSH2_SFTP_S_ISLNK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)
#define LIBSSH2_SFTP_S_ISREG(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG)
#define LIBSSH2_SFTP_S_ISDIR(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR)
#define LIBSSH2_SFTP_S_ISCHR(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR)
#define LIBSSH2_SFTP_S_ISBLK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK)
#define LIBSSH2_SFTP_S_ISFIFO(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO)
#define LIBSSH2_SFTP_S_ISSOCK(m) \
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK)
/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
* Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
#define LIBSSH2_FXF_READ 0x00000001
#define LIBSSH2_FXF_WRITE 0x00000002
#define LIBSSH2_FXF_APPEND 0x00000004
#define LIBSSH2_FXF_CREAT 0x00000008
#define LIBSSH2_FXF_TRUNC 0x00000010
#define LIBSSH2_FXF_EXCL 0x00000020
/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */
#define LIBSSH2_FX_OK 0UL
#define LIBSSH2_FX_EOF 1UL
#define LIBSSH2_FX_NO_SUCH_FILE 2UL
#define LIBSSH2_FX_PERMISSION_DENIED 3UL
#define LIBSSH2_FX_FAILURE 4UL
#define LIBSSH2_FX_BAD_MESSAGE 5UL
#define LIBSSH2_FX_NO_CONNECTION 6UL
#define LIBSSH2_FX_CONNECTION_LOST 7UL
#define LIBSSH2_FX_OP_UNSUPPORTED 8UL
#define LIBSSH2_FX_INVALID_HANDLE 9UL
#define LIBSSH2_FX_NO_SUCH_PATH 10UL
#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11UL
#define LIBSSH2_FX_WRITE_PROTECT 12UL
#define LIBSSH2_FX_NO_MEDIA 13UL
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14UL
#define LIBSSH2_FX_QUOTA_EXCEEDED 15UL
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16UL /* Initial mis-spelling */
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16UL
#define LIBSSH2_FX_LOCK_CONFlICT 17UL /* Initial mis-spelling */
#define LIBSSH2_FX_LOCK_CONFLICT 17UL
#define LIBSSH2_FX_DIR_NOT_EMPTY 18UL
#define LIBSSH2_FX_NOT_A_DIRECTORY 19UL
#define LIBSSH2_FX_INVALID_FILENAME 20UL
#define LIBSSH2_FX_LINK_LOOP 21UL
/* Returned by any function that would block during a read/write operation */
#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
/* SFTP API */
LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp);
/* File / Directory Ops */
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
const char *filename,
unsigned int filename_len,
unsigned long flags,
long mode, int open_type);
#define libssh2_sftp_open(sftp, filename, flags, mode) \
libssh2_sftp_open_ex((sftp), \
(filename), (unsigned int)strlen(filename), \
(flags), (mode), LIBSSH2_SFTP_OPENFILE)
#define libssh2_sftp_opendir(sftp, path) \
libssh2_sftp_open_ex((sftp), \
(path), (unsigned int)strlen(path), \
0, 0, LIBSSH2_SFTP_OPENDIR)
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
libssh2_sftp_open_ex_r(LIBSSH2_SFTP *sftp,
const char *filename,
size_t filename_len,
unsigned long flags,
long mode, int open_type,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_open_r(sftp, filename, flags, mode, attrs) \
libssh2_sftp_open_ex_r((sftp), (filename), strlen(filename), \
(flags), (mode), LIBSSH2_SFTP_OPENFILE, \
(attrs))
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
char *buffer, size_t buffer_maxlen);
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
char *buffer, size_t buffer_maxlen,
char *longentry,
size_t longentry_maxlen,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \
(attrs))
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
const char *buffer, size_t count);
LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle,
libssh2_uint64_t offset);
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_ATTRIBUTES *attrs,
int setstat);
#define libssh2_sftp_fstat(handle, attrs) \
libssh2_sftp_fstat_ex((handle), (attrs), 0)
#define libssh2_sftp_fsetstat(handle, attrs) \
libssh2_sftp_fstat_ex((handle), (attrs), 1)
/* Miscellaneous Ops */
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,
const char *source_filename,
unsigned int srouce_filename_len,
const char *dest_filename,
unsigned int dest_filename_len,
long flags);
#define libssh2_sftp_rename(sftp, sourcefile, destfile) \
libssh2_sftp_rename_ex((sftp), \
(sourcefile), (unsigned int)strlen(sourcefile), \
(destfile), (unsigned int)strlen(destfile), \
LIBSSH2_SFTP_RENAME_OVERWRITE | \
LIBSSH2_SFTP_RENAME_ATOMIC | \
LIBSSH2_SFTP_RENAME_NATIVE)
LIBSSH2_API int libssh2_sftp_posix_rename_ex(LIBSSH2_SFTP *sftp,
const char *source_filename,
size_t srouce_filename_len,
const char *dest_filename,
size_t dest_filename_len);
#define libssh2_sftp_posix_rename(sftp, sourcefile, destfile) \
libssh2_sftp_posix_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
(destfile), strlen(destfile))
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
const char *filename,
unsigned int filename_len);
#define libssh2_sftp_unlink(sftp, filename) \
libssh2_sftp_unlink_ex((sftp), (filename), (unsigned int)strlen(filename))
LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
LIBSSH2_SFTP_STATVFS *st);
LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp,
const char *path,
size_t path_len,
LIBSSH2_SFTP_STATVFS *st);
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len, long mode);
#define libssh2_sftp_mkdir(sftp, path, mode) \
libssh2_sftp_mkdir_ex((sftp), (path), (unsigned int)strlen(path), (mode))
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len);
#define libssh2_sftp_rmdir(sftp, path) \
libssh2_sftp_rmdir_ex((sftp), (path), (unsigned int)strlen(path))
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len,
int stat_type,
LIBSSH2_SFTP_ATTRIBUTES *attrs);
#define libssh2_sftp_stat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_STAT, (attrs))
#define libssh2_sftp_lstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_LSTAT, (attrs))
#define libssh2_sftp_setstat(sftp, path, attrs) \
libssh2_sftp_stat_ex((sftp), (path), (unsigned int)strlen(path), \
LIBSSH2_SFTP_SETSTAT, (attrs))
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
const char *path,
unsigned int path_len,
char *target,
unsigned int target_len,
int link_type);
#define libssh2_sftp_symlink(sftp, orig, linkpath) \
libssh2_sftp_symlink_ex((sftp), \
(orig), (unsigned int)strlen(orig), \
(linkpath), (unsigned int)strlen(linkpath), \
LIBSSH2_SFTP_SYMLINK)
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), \
(path), (unsigned int)strlen(path), \
(target), (maxlen), \
LIBSSH2_SFTP_READLINK)
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \
libssh2_sftp_symlink_ex((sftp), \
(path), (unsigned int)strlen(path), \
(target), (maxlen), \
LIBSSH2_SFTP_REALPATH)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LIBSSH2_SFTP_H */
+21
View File
@@ -0,0 +1,21 @@
###########################################################################
# libssh2 installation details
#
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
###########################################################################
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: libssh2
URL: https://libssh2.org/
Description: Library for SSH-based communication
Version: @LIBSSH2_VERSION@
Requires: @LIBSSH2_PC_REQUIRES@
Requires.private: @LIBSSH2_PC_REQUIRES_PRIVATE@
Libs: -L${libdir} -lssh2 @LIBSSH2_PC_LIBS@
Libs.private: @LIBSSH2_PC_LIBS_PRIVATE@
Cflags: -I${includedir}
@@ -0,0 +1,7 @@
.deps
.libs
Makefile.inc.cmake
libssh2.pc
libssh2_config.h
libssh2_config.h.in
stamp-h1
+341
View File
@@ -0,0 +1,341 @@
# Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
# Copyright (C) Viktor Szakats
#
# 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 copyright holder nor the names
# of any other contributors may be used to endorse or
# promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
#
# SPDX-License-Identifier: BSD-3-Clause
set(_libssh2_soversion 1)
set(_libssh2_libversion 1.0.1)
if(CRYPTO_BACKEND)
list(APPEND PRIVATE_COMPILE_DEFINITIONS ${CRYPTO_BACKEND_DEFINE})
list(APPEND PRIVATE_INCLUDE_DIRECTORIES ${CRYPTO_BACKEND_INCLUDE_DIR})
add_feature_info("Crypto backend" ON "${CRYPTO_BACKEND}")
else()
message(FATAL_ERROR "No suitable cryptography backend found.")
endif()
## Options
unset(_libssh2_definitions)
option(CLEAR_MEMORY "Enable clearing of memory before being freed" ON)
if(NOT CLEAR_MEMORY)
list(APPEND _libssh2_definitions "LIBSSH2_NO_CLEAR_MEMORY")
endif()
option(ENABLE_ZLIB_COMPRESSION "Use zlib for compression" OFF)
add_feature_info(Compression ENABLE_ZLIB_COMPRESSION
"using zlib for compression")
if(ENABLE_ZLIB_COMPRESSION)
find_package(ZLIB REQUIRED)
list(APPEND libssh2_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS})
list(APPEND LIBSSH2_LIBS ${ZLIB_LIBRARIES})
list(APPEND LIBSSH2_PC_REQUIRES_PRIVATE "zlib")
if(ZLIB_FOUND)
list(APPEND _libssh2_definitions "LIBSSH2_HAVE_ZLIB")
endif()
endif()
list(APPEND LIBSSH2_LIBS ${LIBSSH2_LIBS_SOCKET})
# to find generated header
list(APPEND libssh2_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
if(MSVC)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /Zi /Od")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DEBUG")
endif()
## Sources
include(GNUInstallDirs)
transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
# Get 'CSOURCES' and 'HHEADERS' variables
include("${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake")
set(_sources ${CSOURCES} ${HHEADERS})
## Library definition
# Ensure that the static library and import library filenames are different,
# when building both static and shared library. On Windows, with certain
# toolchains (e.g. MSVC) these libraries get the same by default, overwriting
# each other. MinGW is not affected.
if(WIN32 AND BUILD_STATIC_LIBS AND BUILD_SHARED_LIBS AND
NOT STATIC_LIB_SUFFIX AND NOT IMPORT_LIB_SUFFIX AND
CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL CMAKE_IMPORT_LIBRARY_SUFFIX)
set(STATIC_LIB_SUFFIX "_static")
endif()
unset(_libssh2_export)
# we want it to be called libssh2 on all platforms
if(BUILD_STATIC_LIBS)
list(APPEND _libssh2_export ${LIB_STATIC})
add_library(${LIB_STATIC} STATIC ${_sources})
add_library(${PROJECT_NAME}::${LIB_STATIC} ALIAS ${LIB_STATIC})
target_compile_definitions(${LIB_STATIC} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${_libssh2_definitions})
target_link_libraries(${LIB_STATIC} PRIVATE ${LIBSSH2_LIBS})
set_target_properties(${LIB_STATIC} PROPERTIES
PREFIX "" OUTPUT_NAME "libssh2" SOVERSION "${_libssh2_soversion}" VERSION "${_libssh2_libversion}"
SUFFIX "${STATIC_LIB_SUFFIX}${CMAKE_STATIC_LIBRARY_SUFFIX}")
target_include_directories(${LIB_STATIC}
PRIVATE
"${PROJECT_SOURCE_DIR}/include"
${libssh2_INCLUDE_DIRS}
${PRIVATE_INCLUDE_DIRECTORIES}
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif()
if(BUILD_SHARED_LIBS)
list(APPEND _libssh2_export ${LIB_SHARED})
add_library(${LIB_SHARED} SHARED ${_sources})
add_library(${PROJECT_NAME}::${LIB_SHARED} ALIAS ${LIB_SHARED})
if(WIN32)
set_property(TARGET ${LIB_SHARED} APPEND PROPERTY SOURCES "libssh2.rc")
endif()
target_compile_definitions(${LIB_SHARED} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS} ${_libssh2_definitions} ${LIB_SHARED_DEFINITIONS})
target_compile_options(${LIB_SHARED} PRIVATE ${LIB_SHARED_C_FLAGS})
target_link_libraries(${LIB_SHARED} PRIVATE ${LIBSSH2_LIBS})
set_target_properties(${LIB_SHARED} PROPERTIES
PREFIX "" OUTPUT_NAME "libssh2" SOVERSION "${_libssh2_soversion}" VERSION "${_libssh2_libversion}"
IMPORT_PREFIX "" IMPORT_SUFFIX "${IMPORT_LIB_SUFFIX}${CMAKE_IMPORT_LIBRARY_SUFFIX}"
POSITION_INDEPENDENT_CODE ON)
target_include_directories(${LIB_SHARED}
PRIVATE
"${PROJECT_SOURCE_DIR}/include"
${libssh2_INCLUDE_DIRS}
${PRIVATE_INCLUDE_DIRECTORIES}
PUBLIC
"$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>"
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/${CMAKE_INSTALL_INCLUDEDIR}>")
endif()
add_library(${PROJECT_NAME}::${LIB_NAME} ALIAS ${LIB_SELECTED})
add_library(${LIB_NAME} ALIAS ${LIB_SELECTED})
## Installation
install(FILES
"${PROJECT_SOURCE_DIR}/include/libssh2.h"
"${PROJECT_SOURCE_DIR}/include/libssh2_publickey.h"
"${PROJECT_SOURCE_DIR}/include/libssh2_sftp.h"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(BUILD_STATIC_LIBS)
install(TARGETS ${LIB_STATIC}
EXPORT "${PROJECT_NAME}-targets"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
if(BUILD_SHARED_LIBS)
install(TARGETS ${LIB_SHARED}
EXPORT "${PROJECT_NAME}-targets"
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
list(APPEND _RUNTIME_DEPENDENCIES $<TARGET_FILE:${LIB_SHARED}>)
endif()
set(RUNTIME_DEPENDENCIES ${_RUNTIME_DEPENDENCIES} CACHE INTERNAL
"Files that must be in the same directory as the executables at runtime.")
# Package config
## During package installation, install libssh2-targets.cmake
install(EXPORT "${PROJECT_NAME}-targets"
NAMESPACE "${PROJECT_NAME}::"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
## During build, register directly from build tree
# create libssh2-targets.cmake
export(TARGETS ${_libssh2_export} NAMESPACE "${PROJECT_NAME}::" FILE "${PROJECT_NAME}-targets.cmake")
export(PACKAGE ${PROJECT_NAME}) # register it
# Generate libssh2-config.cmake into build tree and install it with dependencies
configure_file("${PROJECT_SOURCE_DIR}/cmake/libssh2-config.cmake.in" "${PROJECT_NAME}-config.cmake" @ONLY)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake"
"${PROJECT_SOURCE_DIR}/cmake/FindLibgcrypt.cmake"
"${PROJECT_SOURCE_DIR}/cmake/FindMbedTLS.cmake"
"${PROJECT_SOURCE_DIR}/cmake/FindWolfSSL.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
# Calculate variables for pkg-config
set(LIBSSH2_PC_LIBS_PRIVATE "")
if(WIN32)
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-lws2_32")
endif()
set(_ldflags "")
# Avoid getting unnecessary -L options for known system directories.
unset(_sys_libdirs)
foreach(_libdir IN LISTS CMAKE_SYSTEM_PREFIX_PATH)
if(_libdir MATCHES "/$")
set(_libdir "${_libdir}lib")
else()
set(_libdir "${_libdir}/lib")
endif()
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
if(DEFINED CMAKE_LIBRARY_ARCHITECTURE)
set(_libdir "${_libdir}/${CMAKE_LIBRARY_ARCHITECTURE}")
if(IS_DIRECTORY "${_libdir}")
list(APPEND _sys_libdirs "${_libdir}")
endif()
endif()
endforeach()
foreach(_libdir IN LISTS LIBSSH2_LIBDIRS)
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
endif()
endforeach()
unset(_implicit_libs)
if(NOT MINGW AND NOT UNIX)
set(_implicit_libs ${CMAKE_C_IMPLICIT_LINK_LIBRARIES})
endif()
foreach(_lib IN LISTS _implicit_libs LIBSSH2_LIBS)
if(TARGET "${_lib}")
set(_libname "${_lib}")
get_target_property(_imported "${_libname}" IMPORTED)
if(NOT _imported)
# Reading the LOCATION property on non-imported target will error out.
# Assume the user will not need this information in the .pc file.
continue()
endif()
get_target_property(_lib "${_libname}" LOCATION)
if(NOT _lib)
message(WARNING "Bad lib in library list: ${_libname}")
continue()
endif()
endif()
if(_lib MATCHES "^-")
list(APPEND _ldflags "${_lib}")
elseif(_lib MATCHES ".*/.*")
# This gets a bit more complex, because we want to specify the
# directory separately, and only once per directory
get_filename_component(_libdir ${_lib} DIRECTORY)
get_filename_component(_libname ${_lib} NAME_WE)
if(_libname MATCHES "^lib")
list(FIND _sys_libdirs "${_libdir}" _libdir_index)
if(_libdir_index LESS 0)
list(APPEND _ldflags "-L${_libdir}")
endif()
string(REGEX REPLACE "^lib" "" _libname "${_libname}")
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-l${_libname}")
else()
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "${_lib}")
endif()
else()
list(APPEND LIBSSH2_PC_LIBS_PRIVATE "-l${_lib}")
endif()
endforeach()
if(LIBSSH2_PC_REQUIRES_PRIVATE)
string(REPLACE ";" "," LIBSSH2_PC_REQUIRES_PRIVATE "${LIBSSH2_PC_REQUIRES_PRIVATE}")
endif()
if(LIBSSH2_PC_LIBS_PRIVATE)
list(REMOVE_DUPLICATES LIBSSH2_PC_LIBS_PRIVATE)
string(REPLACE ";" " " LIBSSH2_PC_LIBS_PRIVATE "${LIBSSH2_PC_LIBS_PRIVATE}")
endif()
if(_ldflags)
list(REMOVE_DUPLICATES _ldflags)
string(REPLACE ";" " " _ldflags "${_ldflags}")
set(LIBSSH2_PC_LIBS_PRIVATE "${_ldflags} ${LIBSSH2_PC_LIBS_PRIVATE}")
string(STRIP "${LIBSSH2_PC_LIBS_PRIVATE}" LIBSSH2_PC_LIBS_PRIVATE)
endif()
# Merge pkg-config private fields into public ones when static-only
if(BUILD_SHARED_LIBS)
set(LIBSSH2_PC_REQUIRES "")
set(LIBSSH2_PC_LIBS "")
else()
set(LIBSSH2_PC_REQUIRES "${LIBSSH2_PC_REQUIRES_PRIVATE}")
set(LIBSSH2_PC_LIBS "${LIBSSH2_PC_LIBS_PRIVATE}")
endif()
set(prefix "${CMAKE_INSTALL_PREFIX}")
set(exec_prefix "\${prefix}")
if(IS_ABSOLUTE ${CMAKE_INSTALL_INCLUDEDIR})
set(includedir "${CMAKE_INSTALL_INCLUDEDIR}")
else()
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
if(IS_ABSOLUTE ${CMAKE_INSTALL_LIBDIR})
set(libdir "${CMAKE_INSTALL_LIBDIR}")
else()
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
endif()
# Generate a pkg-config file for client projects not using CMake.
# Consumed variables:
# exec_prefix
# includedir
# LIBSSH2_PC_LIBS
# LIBSSH2_PC_LIBS_PRIVATE
# LIBSSH2_PC_REQUIRES
# LIBSSH2_PC_REQUIRES_PRIVATE
# LIBSSH2_VERSION
# libdir
# prefix
configure_file("${PROJECT_SOURCE_DIR}/libssh2.pc.in" "libssh2.pc" @ONLY)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/libssh2.pc"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig")
#
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
VERSION "${LIBSSH2_VERSION_MAJOR}.${LIBSSH2_VERSION_MINOR}.${LIBSSH2_VERSION_PATCH}"
COMPATIBILITY SameMajorVersion)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
+61
View File
@@ -0,0 +1,61 @@
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
AUTOMAKE_OPTIONS = foreign nostdinc
# Get the CSOURCES, HHEADERS and EXTRA_DIST defines
include Makefile.inc
libssh2_la_SOURCES = $(CSOURCES) $(HHEADERS)
if HAVE_WINDRES
libssh2_la_SOURCES += libssh2.rc
endif
EXTRA_DIST += libssh2_config.h.in libssh2_config_cmake.h.in CMakeLists.txt
lib_LTLIBRARIES = libssh2.la
# srcdir/include for the shipped headers
# builddir/src for the generated config header when building out of the source
# tree
AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/include
# This might hold -Werror
AM_CFLAGS = @LIBSSH2_CFLAG_EXTRAS@
VERSION=-version-info 1:1:0
# This flag accepts an argument of the form current[:revision[:age]]. So,
# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to
# 1.
#
# If either revision or age are omitted, they default to 0. Also note that age
# must be less than or equal to the current interface number.
#
# Here are a set of rules to help you update your library version information:
#
# 1.Start with version information of 0:0:0 for each libtool library.
#
# 2.Update the version information only immediately before a public release of
# your software. More frequent updates are unnecessary, and only guarantee
# that the current interface number gets larger faster.
#
# 3.If the library source code has changed at all since the last update, then
# increment revision (c:r+1:a)
#
# 4.If any interfaces have been added, removed, or changed since the last
# update, increment current, and set revision to 0. (c+1:r=0:a)
#
# 5.If any interfaces have been added since the last public release, then
# increment age. (c:r:a+1)
#
# 6.If any interfaces have been removed since the last public release, then
# set age to 0. (c:r:a=0)
#
libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
-export-symbols-regex '^libssh2_.*'
if HAVE_WINDRES
.rc.lo:
$(LIBTOOL) --tag=RC --mode=compile $(RC) -I$(top_srcdir)/include $(RCFLAGS) -i $< -o $@
endif
+62
View File
@@ -0,0 +1,62 @@
# Copyright (C) The libssh2 project and its contributors.
# SPDX-License-Identifier: BSD-3-Clause
CSOURCES = \
agent.c \
bcrypt_pbkdf.c \
channel.c \
comp.c \
chacha.c \
cipher-chachapoly.c \
crypt.c \
crypto.c \
global.c \
hostkey.c \
keepalive.c \
kex.c \
knownhost.c \
mac.c \
misc.c \
packet.c \
pem.c \
poly1305.c \
publickey.c \
scp.c \
session.c \
sftp.c \
transport.c \
userauth.c \
userauth_kbd_packet.c \
version.c
HHEADERS = \
chacha.h \
channel.h \
cipher-chachapoly.h \
comp.h \
crypto.h \
crypto_config.h \
libgcrypt.h \
libssh2_priv.h \
libssh2_setup.h \
mac.h \
mbedtls.h \
misc.h \
openssl.h \
os400qc3.h \
packet.h \
poly1305.h \
session.h \
sftp.h \
transport.h \
userauth.h \
userauth_kbd_packet.h \
wincng.h
EXTRA_DIST = \
agent_win.c \
blowfish.c \
libgcrypt.c \
mbedtls.c \
openssl.c \
os400qc3.c \
wincng.c
File diff suppressed because it is too large. Load diff
+349
View File
@@ -0,0 +1,349 @@
/*
* Copyright (C) Daiki Ueno
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause AND BSD-2-Clause
*/
#ifdef HAVE_WIN32_AGENTS /* Compile this via agent.c */
#include <stdlib.h> /* for getenv() */
/* Code to talk to OpenSSH was taken and modified from the Win32 port of
* Portable OpenSSH by the PowerShell team. Commit
* 8ab565c53f3619d6a1f5ac229e212cad8a52852c of
* https://github.com/PowerShell/openssh-portable.git was used as the base,
* specifically the following files:
*
* - contrib\win32\win32compat\fileio.c
* - Structure of agent_connect_openssh from ssh_get_authentication_socket
* - Structure of agent_transact_openssh from ssh_request_reply
* - contrib\win32\win32compat\wmain_common.c
* - Windows equivalent functions for common Unix functions, inlined into
* this implementation
* - fileio_connect replacing connect
* - fileio_read replacing read
* - fileio_write replacing write
* - fileio_close replacing close
*
* Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
* All rights reserved
* Functions for connecting the local authentication agent.
*
* As far as I am concerned, the code I have written for this software
* can be used freely for any purpose. Any derived versions of this
* software must be clearly marked as such, and if the derived work is
* incompatible with the protocol description in the RFC file, it must be
* called by a name other than "ssh" or "Secure Shell".
*
* SSH2 implementation,
* Copyright (C) 2000 Markus Friedl. 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*
* Copyright (C) 2015 Microsoft Corp.
* All rights reserved
*
* Microsoft openssh win32 port
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*/
#define WIN32_OPENSSH_AGENT_SOCK "\\\\.\\pipe\\openssh-ssh-agent"
static int
agent_connect_openssh(LIBSSH2_AGENT *agent)
{
int ret = LIBSSH2_ERROR_NONE;
const char *path;
HANDLE pipe = INVALID_HANDLE_VALUE;
HANDLE event = NULL;
path = agent->identity_agent_path;
if(!path) {
path = getenv("SSH_AUTH_SOCK");
if(!path)
path = WIN32_OPENSSH_AGENT_SOCK;
}
for(;;) {
pipe = CreateFileA(
path,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
/* Non-blocking mode for agent connections is not implemented at
* the point this was implemented. The code for Win32 OpenSSH
* should support non-blocking IO, but the code calling it doesn't
* support it as of yet.
* When non-blocking IO is implemented for the surrounding code,
* uncomment the following line to enable support within the Win32
* OpenSSH code.
*/
/* FILE_FLAG_OVERLAPPED | */
SECURITY_SQOS_PRESENT |
SECURITY_IDENTIFICATION,
NULL
);
if(pipe != INVALID_HANDLE_VALUE)
break;
if(GetLastError() != ERROR_PIPE_BUSY)
break;
/* Wait up to 1 second for a pipe instance to become available */
if(!WaitNamedPipeA(path, 1000))
break;
}
if(pipe == INVALID_HANDLE_VALUE) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to connect to agent pipe");
goto cleanup;
}
if(SetHandleInformation(pipe, HANDLE_FLAG_INHERIT, 0) == FALSE) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to set handle information of agent pipe");
goto cleanup;
}
event = CreateEventA(NULL, TRUE, FALSE, NULL);
if(!event) {
ret = _libssh2_error(agent->session, LIBSSH2_ERROR_AGENT_PROTOCOL,
"unable to create async I/O event");
goto cleanup;
}
agent->pipe = pipe;
pipe = INVALID_HANDLE_VALUE;
agent->overlapped.hEvent = event;
event = NULL;
agent->fd = 0; /* Mark as the connection has been established */
cleanup:
if(event)
CloseHandle(event);
if(pipe != INVALID_HANDLE_VALUE)
CloseHandle(pipe);
return ret;
}
#define RECV_SEND_ALL(func, agent, buffer, length, total) \
DWORD bytes_transfered; \
BOOL ret; \
DWORD err; \
int rc; \
\
while(*total < length) { \
if(!agent->pending_io) \
ret = func(agent->pipe, (char *)buffer + *total, \
(DWORD)(length - *total), &bytes_transfered, \
&agent->overlapped); \
else \
ret = GetOverlappedResult(agent->pipe, &agent->overlapped, \
&bytes_transfered, FALSE); \
\
*total += bytes_transfered; \
if(!ret) { \
err = GetLastError(); \
if((!agent->pending_io && ERROR_IO_PENDING == err) \
|| (agent->pending_io && ERROR_IO_INCOMPLETE == err)) { \
agent->pending_io = TRUE; \
return LIBSSH2_ERROR_EAGAIN; \
} \
\
return LIBSSH2_ERROR_SOCKET_NONE; \
} \
agent->pending_io = FALSE; \
} \
\
rc = (int)*total; \
*total = 0; \
return rc;
static int
win32_openssh_send_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
size_t *send_recv_total)
{
RECV_SEND_ALL(WriteFile, agent, buffer, length, send_recv_total)
}
static int
win32_openssh_recv_all(LIBSSH2_AGENT *agent, void *buffer, size_t length,
size_t *send_recv_total)
{
RECV_SEND_ALL(ReadFile, agent, buffer, length, send_recv_total)
}
#undef RECV_SEND_ALL
static int
agent_transact_openssh(LIBSSH2_AGENT *agent, agent_transaction_ctx_t transctx)
{
unsigned char buf[4];
int rc;
/* Send the length of the request */
if(transctx->state == agent_NB_state_request_created) {
_libssh2_htonu32(buf, (uint32_t)transctx->request_len);
rc = win32_openssh_send_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
transctx->state = agent_NB_state_request_length_sent;
}
/* Send the request body */
if(transctx->state == agent_NB_state_request_length_sent) {
rc = win32_openssh_send_all(agent, transctx->request,
transctx->request_len,
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_SEND,
"agent send failed");
transctx->state = agent_NB_state_request_sent;
}
/* Receive the length of the body */
if(transctx->state == agent_NB_state_request_sent) {
rc = win32_openssh_recv_all(agent, buf, sizeof(buf),
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
transctx->response_len = _libssh2_ntohu32(buf);
transctx->response = LIBSSH2_ALLOC(agent->session,
transctx->response_len);
if(!transctx->response)
return LIBSSH2_ERROR_ALLOC;
transctx->state = agent_NB_state_response_length_received;
}
/* Receive the response body */
if(transctx->state == agent_NB_state_response_length_received) {
rc = win32_openssh_recv_all(agent, transctx->response,
transctx->response_len,
&transctx->send_recv_total);
if(rc == LIBSSH2_ERROR_EAGAIN)
return LIBSSH2_ERROR_EAGAIN;
else if(rc < 0)
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_RECV,
"agent recv failed");
transctx->state = agent_NB_state_response_received;
}
return LIBSSH2_ERROR_NONE;
}
static int
agent_disconnect_openssh(LIBSSH2_AGENT *agent)
{
if(!CancelIo(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to cancel pending IO of agent pipe");
if(!CloseHandle(agent->overlapped.hEvent))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to async I/O event");
agent->overlapped.hEvent = NULL;
/* let queued APCs (if any) drain */
SleepEx(0, TRUE);
if(!CloseHandle(agent->pipe))
return _libssh2_error(agent->session, LIBSSH2_ERROR_SOCKET_DISCONNECT,
"failed to close handle to agent pipe");
agent->pipe = INVALID_HANDLE_VALUE;
agent->fd = LIBSSH2_INVALID_SOCKET;
return LIBSSH2_ERROR_NONE;
}
static struct agent_ops agent_ops_openssh = {
agent_connect_openssh,
agent_transact_openssh,
agent_disconnect_openssh
};
#endif /* HAVE_WIN32_AGENTS */
+210
View File
@@ -0,0 +1,210 @@
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
/*
* Copyright (C) Ted Unangst <tedu@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: MIT
*/
#include "libssh2_priv.h"
#ifndef HAVE_BCRYPT_PBKDF
#include <stdlib.h>
#define LIBSSH2_BCRYPT_PBKDF_C
#include "blowfish.c"
/*
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
*
* The bcrypt hash function is derived from the bcrypt password hashing
* function with the following modifications:
* 1. The input password and salt are preprocessed with SHA512.
* 2. The output length is expanded to 256 bits.
* 3. Subsequently the magic string to be encrypted is lengthened and modified
* to "OxychromaticBlowfishSwatDynamite"
* 4. The hash function is defined to perform 64 rounds of initial state
* expansion. (More rounds are performed by iterating the hash.)
*
* Note that this implementation pulls the SHA512 operations into the caller
* as a performance optimization.
*
* One modification from official pbkdf2. Instead of outputting key material
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
* generate (i.e.) 512 bits of key material for use as two 256 bit keys, an
* attacker can merely run once through the outer loop below, but the user
* always runs it twice. Shuffling output bytes requires computing the
* entirety of the key material to assemble any subkey. This is something a
* wise caller could do; we just do it for you.
*/
#define BCRYPT_BLOCKS 8
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4)
static void
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
{
blf_ctx state;
uint8_t ciphertext[BCRYPT_HASHSIZE] = {
'O', 'x', 'y', 'c', 'h', 'r', 'o', 'm', 'a', 't', 'i', 'c',
'B', 'l', 'o', 'w', 'f', 'i', 's', 'h',
'S', 'w', 'a', 't',
'D', 'y', 'n', 'a', 'm', 'i', 't', 'e' };
uint32_t cdata[BCRYPT_BLOCKS];
int i;
uint16_t j;
uint16_t shalen = SHA512_DIGEST_LENGTH;
/* key expansion */
Blowfish_initstate(&state);
Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
for(i = 0; i < 64; i++) {
Blowfish_expand0state(&state, sha2salt, shalen);
Blowfish_expand0state(&state, sha2pass, shalen);
}
/* encryption */
j = 0;
for(i = 0; i < BCRYPT_BLOCKS; i++)
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
&j);
for(i = 0; i < 64; i++)
blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
/* copy out */
for(i = 0; i < BCRYPT_BLOCKS; i++) {
out[4 * i + 3] = (uint8_t)((cdata[i] >> 24) & 0xff);
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
out[4 * i + 0] = cdata[i] & 0xff;
}
/* zap */
_libssh2_explicit_zero(ciphertext, sizeof(ciphertext));
_libssh2_explicit_zero(cdata, sizeof(cdata));
_libssh2_explicit_zero(&state, sizeof(state));
}
static int
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
size_t saltlen,
uint8_t *key, size_t keylen, unsigned int rounds)
{
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
uint8_t out[BCRYPT_HASHSIZE];
uint8_t tmpout[BCRYPT_HASHSIZE];
uint8_t *countsalt;
size_t i, j, amt, stride;
uint32_t count;
size_t origkeylen = keylen;
libssh2_sha512_ctx ctx;
/* nothing crazy */
if(rounds < 1)
return -1;
if(passlen == 0 || saltlen == 0 || keylen == 0 ||
keylen > sizeof(out) * sizeof(out) || saltlen > 1 << 20)
return -1;
countsalt = calloc(1, saltlen + 4);
if(!countsalt)
return -1;
stride = (keylen + sizeof(out) - 1) / sizeof(out);
amt = (keylen + stride - 1) / stride;
memcpy(countsalt, salt, saltlen);
/* collapse password */
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, pass, passlen) ||
!libssh2_sha512_final(ctx, sha2pass)) {
free(countsalt);
return -1;
}
/* generate key, sizeof(out) at a time */
for(count = 1; keylen > 0; count++) {
countsalt[saltlen + 0] = (uint8_t)((count >> 24) & 0xff);
countsalt[saltlen + 1] = (count >> 16) & 0xff;
countsalt[saltlen + 2] = (count >> 8) & 0xff;
countsalt[saltlen + 3] = count & 0xff;
/* first round, salt is salt */
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, countsalt, saltlen + 4) ||
!libssh2_sha512_final(ctx, sha2salt)) {
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return -1;
}
bcrypt_hash(sha2pass, sha2salt, tmpout);
memcpy(out, tmpout, sizeof(out));
for(i = 1; i < rounds; i++) {
/* subsequent rounds, salt is previous output */
if(!libssh2_sha512_init(&ctx) ||
!libssh2_sha512_update(ctx, tmpout, sizeof(tmpout)) ||
!libssh2_sha512_final(ctx, sha2salt)) {
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return -1;
}
bcrypt_hash(sha2pass, sha2salt, tmpout);
for(j = 0; j < sizeof(out); j++)
out[j] ^= tmpout[j];
}
/*
* pbkdf2 deviation: output the key material non-linearly.
*/
amt = LIBSSH2_MIN(amt, keylen);
for(i = 0; i < amt; i++) {
size_t dest = i * stride + (count - 1);
if(dest >= origkeylen) {
break;
}
key[dest] = out[i];
}
keylen -= i;
}
/* zap */
_libssh2_explicit_zero(out, sizeof(out));
free(countsalt);
return 0;
}
#endif /* HAVE_BCRYPT_PBKDF */
/* Wrapper */
int _libssh2_bcrypt_pbkdf(const char *pass,
size_t passlen,
const uint8_t *salt,
size_t saltlen,
uint8_t *key,
size_t keylen,
unsigned int rounds)
{
return bcrypt_pbkdf(pass,
passlen,
salt,
saltlen,
key,
keylen,
rounds);
}
+751
View File
@@ -0,0 +1,751 @@
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
/*
* Blowfish for OpenBSD - a fast block cipher designed by Bruce Schneier
*
* Copyright (C) Niels Provos <provos@physnet.uni-hamburg.de>
* All rights reserved.
*
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* This code is derived from section 14.3 and the given source
* in section V of Applied Cryptography, second edition.
* Blowfish is an unpatented fast block cipher designed by
* Bruce Schneier.
*/
#if defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH)
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
!defined(HAVE_BLF_ENC))
#ifdef _DEBUG_BLOWFISH
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#endif
/* Schneier specifies a maximum key length of 56 bytes.
* This ensures that every key bit affects every cipher
* bit. However, the subkeys can hold up to 72 bytes.
* Warning: For normal blowfish encryption only 56 bytes
* of the key affect all cipherbits.
*/
#define BLF_N 16 /* Number of Subkeys */
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
/* Blowfish context */
typedef struct BlowfishContext {
uint32_t S[4][256]; /* S-Boxes */
uint32_t P[BLF_N + 2]; /* Subkeys */
} blf_ctx;
/* Raw access to customized Blowfish
* blf_key is just:
* Blowfish_initstate( state )
* Blowfish_expand0state( state, key, keylen )
*/
static void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
#ifdef _DEBUG_BLOWFISH
static void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
#endif
static void Blowfish_initstate(blf_ctx *);
static void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
static void Blowfish_expandstate
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
/* Standard Blowfish */
#ifdef _DEBUG_BLOWFISH
static void blf_key(blf_ctx *, const uint8_t *, uint16_t);
#endif
static void blf_enc(blf_ctx *, uint32_t *, uint16_t);
#ifdef _DEBUG_BLOWFISH
static void blf_dec(blf_ctx *, uint32_t *, uint16_t);
#endif
#if 0
static void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
static void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
static void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
#endif
/* Converts uint8_t to uint32_t */
static uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
/* Function for Feistel Networks */
#define F(s, x) ((((s)[ (((x) >> 24) & 0xFF)] \
+ (s)[0x100 + (((x) >> 16) & 0xFF)]) \
^ (s)[0x200 + (((x) >> 8) & 0xFF)]) \
+ (s)[0x300 + ( (x) & 0xFF)])
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
static void
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[0];
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
*xl = Xr ^ p[17];
*xr = Xl;
}
#ifdef _DEBUG_BLOWFISH
static void
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
{
uint32_t Xl;
uint32_t Xr;
uint32_t *s = c->S[0];
uint32_t *p = c->P;
Xl = *xl;
Xr = *xr;
Xl ^= p[17];
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
*xl = Xr ^ p[0];
*xr = Xl;
}
#endif
static void
Blowfish_initstate(blf_ctx *c)
{
/* P-box and S-box tables initialized with digits of Pi */
static const blf_ctx initstate =
{ {
{
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
{
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
{
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
{
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
},
{
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
0x9216d5d9, 0x8979fb1b
} };
*c = initstate;
}
static uint32_t
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
uint16_t *current)
{
uint8_t i;
uint16_t j;
uint32_t temp;
temp = 0x00000000;
j = *current;
for(i = 0; i < 4; i++, j++) {
if(j >= databytes)
j = 0;
temp = (temp << 8) | data[j];
}
*current = j;
return temp;
}
static void
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
{
int i;
int k;
uint16_t j;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
static void
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
const uint8_t *key, uint16_t keybytes)
{
int i;
int k;
uint16_t j;
uint32_t temp;
uint32_t datal;
uint32_t datar;
j = 0;
for(i = 0; i < BLF_N + 2; i++) {
/* Extract 4 int8 to 1 int32 from keystream */
temp = Blowfish_stream2word(key, keybytes, &j);
c->P[i] = c->P[i] ^ temp;
}
j = 0;
datal = 0x00000000;
datar = 0x00000000;
for(i = 0; i < BLF_N + 2; i += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->P[i] = datal;
c->P[i + 1] = datar;
}
for(i = 0; i < 4; i++) {
for(k = 0; k < 256; k += 2) {
datal ^= Blowfish_stream2word(data, databytes, &j);
datar ^= Blowfish_stream2word(data, databytes, &j);
Blowfish_encipher(c, &datal, &datar);
c->S[i][k] = datal;
c->S[i][k + 1] = datar;
}
}
}
#ifdef _DEBUG_BLOWFISH
static void
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
{
/* Initialize S-boxes and subkeys with Pi */
Blowfish_initstate(c);
/* Transform S-boxes and subkeys with key */
Blowfish_expand0state(c, k, len);
}
#endif
static void
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_encipher(c, d, d + 1);
d += 2;
}
}
#ifdef _DEBUG_BLOWFISH
static void
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
{
uint32_t *d;
uint16_t i;
d = data;
for(i = 0; i < blocks; i++) {
Blowfish_decipher(c, d, d + 1);
d += 2;
}
}
#endif
#if 0
static void
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
static void
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i;
for(i = 0; i < len; i += 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
data += 8;
}
}
static void
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint32_t i, j;
for(i = 0; i < len; i += 8) {
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_encipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
iv = data;
data += 8;
}
}
static void
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
{
uint32_t l, r;
uint8_t *iv;
uint32_t i, j;
iv = data + len - 16;
data = data + len - 8;
for(i = len - 8; i >= 8; i -= 8) {
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iv[j];
iv -= 8;
data -= 8;
}
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
Blowfish_decipher(c, &l, &r);
data[0] = (uint8_t)(l >> 24 & 0xff);
data[1] = l >> 16 & 0xff;
data[2] = l >> 8 & 0xff;
data[3] = l & 0xff;
data[4] = (uint8_t)(r >> 24 & 0xff);
data[5] = r >> 16 & 0xff;
data[6] = r >> 8 & 0xff;
data[7] = r & 0xff;
for(j = 0; j < 8; j++)
data[j] ^= iva[j];
}
#endif
#ifdef _DEBUG_BLOWFISH
static void
report(uint32_t data[], uint16_t len)
{
int i;
for(i = 0; i < len; i += 2)
printf("Block %d: 0x%08lx 0x%08lx.\n",
i / 2, (unsigned long)data[i], (unsigned long)data[i + 1]);
}
int
main(void)
{
blf_ctx c;
char key[] = "AAAAA";
char key2[] = "abcdefghijklmnopqrstuvwxyz";
uint32_t data[10];
uint32_t data2[] =
{0x424c4f57l, 0x46495348l};
uint16_t i;
/* First test */
for(i = 0; i < 10; i++)
data[i] = i;
blf_key(&c, (uint8_t *) key, 5);
blf_enc(&c, data, 5);
blf_dec(&c, data, 1);
blf_dec(&c, data + 2, 4);
printf("Should read as 0 - 9.\n");
report(data, 10);
/* Second test */
blf_key(&c, (uint8_t *) key2, (uint16_t)strlen(key2));
blf_enc(&c, data2, 1);
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
report(data2, 2);
blf_dec(&c, data2, 1);
printf("\nShould read as: 0x424c4f57 0x46495348.\n");
report(data2, 2);
return 0;
}
#endif
#endif /* !defined(HAVE_BCRYPT_PBKDF) && \
(!defined(HAVE_BLOWFISH_INITSTATE) || \
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
'!defined(HAVE_BLF_ENC)) */
#endif /* defined(LIBSSH2_BCRYPT_PBKDF_C) || defined(_DEBUG_BLOWFISH) */
+224
View File
@@ -0,0 +1,224 @@
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#include "libssh2_priv.h"
#include "chacha.h"
/* $OpenBSD: chacha.c,v 1.1 2013/11/21 00:45:44 djm Exp $ */
typedef unsigned char u8;
typedef unsigned int u32;
typedef struct chacha_ctx chacha_ctx;
#define U8C(v) (v##U)
#define U32C(v) (v##U)
#define U8V(v) ((u8)(v) & U8C(0xFF))
#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF))
#define ROTL32(v, n) \
(U32V((v) << (n)) | ((v) >> (32 - (n))))
#define U8TO32_LITTLE(p) \
(((u32)((p)[0]) ) | \
((u32)((p)[1]) << 8) | \
((u32)((p)[2]) << 16) | \
((u32)((p)[3]) << 24))
#define U32TO8_LITTLE(p, v) \
do { \
(p)[0] = U8V((v) ); \
(p)[1] = U8V((v) >> 8); \
(p)[2] = U8V((v) >> 16); \
(p)[3] = U8V((v) >> 24); \
} while (0)
#define ROTATE(v,c) (ROTL32(v,c))
#define XOR(v,w) ((v) ^ (w))
#define PLUS(v,w) (U32V((v) + (w)))
#define PLUSONE(v) (PLUS((v),1))
#define QUARTERROUND(a,b,c,d) \
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
static const char sigma[17] = "expand 32-byte k";
static const char tau[17] = "expand 16-byte k";
void
chacha_keysetup(chacha_ctx *x, const u8 *k, u32 kbits)
{
const char *constants;
x->input[4] = U8TO32_LITTLE(k + 0);
x->input[5] = U8TO32_LITTLE(k + 4);
x->input[6] = U8TO32_LITTLE(k + 8);
x->input[7] = U8TO32_LITTLE(k + 12);
if(kbits == 256) { /* recommended */
k += 16;
constants = sigma;
}
else { /* kbits == 128 */
constants = tau;
}
x->input[8] = U8TO32_LITTLE(k + 0);
x->input[9] = U8TO32_LITTLE(k + 4);
x->input[10] = U8TO32_LITTLE(k + 8);
x->input[11] = U8TO32_LITTLE(k + 12);
x->input[0] = U8TO32_LITTLE(constants + 0);
x->input[1] = U8TO32_LITTLE(constants + 4);
x->input[2] = U8TO32_LITTLE(constants + 8);
x->input[3] = U8TO32_LITTLE(constants + 12);
}
void
chacha_ivsetup(chacha_ctx *x, const u8 *iv, const u8 *counter)
{
x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
x->input[14] = U8TO32_LITTLE(iv + 0);
x->input[15] = U8TO32_LITTLE(iv + 4);
}
void
chacha_encrypt_bytes(chacha_ctx *x, const u8 *m, u8 *c, u32 bytes)
{
u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
u8 *ctarget = NULL;
u8 tmp[64];
u_int i;
if(!bytes)
return;
j0 = x->input[0];
j1 = x->input[1];
j2 = x->input[2];
j3 = x->input[3];
j4 = x->input[4];
j5 = x->input[5];
j6 = x->input[6];
j7 = x->input[7];
j8 = x->input[8];
j9 = x->input[9];
j10 = x->input[10];
j11 = x->input[11];
j12 = x->input[12];
j13 = x->input[13];
j14 = x->input[14];
j15 = x->input[15];
for(;;) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) tmp[i] = m[i];
m = tmp;
ctarget = c;
c = tmp;
}
x0 = j0;
x1 = j1;
x2 = j2;
x3 = j3;
x4 = j4;
x5 = j5;
x6 = j6;
x7 = j7;
x8 = j8;
x9 = j9;
x10 = j10;
x11 = j11;
x12 = j12;
x13 = j13;
x14 = j14;
x15 = j15;
for(i = 20; i > 0; i -= 2) {
QUARTERROUND(x0, x4, x8, x12)
QUARTERROUND(x1, x5, x9, x13)
QUARTERROUND(x2, x6, x10, x14)
QUARTERROUND(x3, x7, x11, x15)
QUARTERROUND(x0, x5, x10, x15)
QUARTERROUND(x1, x6, x11, x12)
QUARTERROUND(x2, x7, x8, x13)
QUARTERROUND(x3, x4, x9, x14)
}
x0 = PLUS(x0, j0);
x1 = PLUS(x1, j1);
x2 = PLUS(x2, j2);
x3 = PLUS(x3, j3);
x4 = PLUS(x4, j4);
x5 = PLUS(x5, j5);
x6 = PLUS(x6, j6);
x7 = PLUS(x7, j7);
x8 = PLUS(x8, j8);
x9 = PLUS(x9, j9);
x10 = PLUS(x10, j10);
x11 = PLUS(x11, j11);
x12 = PLUS(x12, j12);
x13 = PLUS(x13, j13);
x14 = PLUS(x14, j14);
x15 = PLUS(x15, j15);
x0 = XOR(x0, U8TO32_LITTLE(m + 0));
x1 = XOR(x1, U8TO32_LITTLE(m + 4));
x2 = XOR(x2, U8TO32_LITTLE(m + 8));
x3 = XOR(x3, U8TO32_LITTLE(m + 12));
x4 = XOR(x4, U8TO32_LITTLE(m + 16));
x5 = XOR(x5, U8TO32_LITTLE(m + 20));
x6 = XOR(x6, U8TO32_LITTLE(m + 24));
x7 = XOR(x7, U8TO32_LITTLE(m + 28));
x8 = XOR(x8, U8TO32_LITTLE(m + 32));
x9 = XOR(x9, U8TO32_LITTLE(m + 36));
x10 = XOR(x10, U8TO32_LITTLE(m + 40));
x11 = XOR(x11, U8TO32_LITTLE(m + 44));
x12 = XOR(x12, U8TO32_LITTLE(m + 48));
x13 = XOR(x13, U8TO32_LITTLE(m + 52));
x14 = XOR(x14, U8TO32_LITTLE(m + 56));
x15 = XOR(x15, U8TO32_LITTLE(m + 60));
j12 = PLUSONE(j12);
if(!j12) {
j13 = PLUSONE(j13);
/* stopping at 2^70 bytes per nonce is user's responsibility */
}
U32TO8_LITTLE(c + 0, x0);
U32TO8_LITTLE(c + 4, x1);
U32TO8_LITTLE(c + 8, x2);
U32TO8_LITTLE(c + 12, x3);
U32TO8_LITTLE(c + 16, x4);
U32TO8_LITTLE(c + 20, x5);
U32TO8_LITTLE(c + 24, x6);
U32TO8_LITTLE(c + 28, x7);
U32TO8_LITTLE(c + 32, x8);
U32TO8_LITTLE(c + 36, x9);
U32TO8_LITTLE(c + 40, x10);
U32TO8_LITTLE(c + 44, x11);
U32TO8_LITTLE(c + 48, x12);
U32TO8_LITTLE(c + 52, x13);
U32TO8_LITTLE(c + 56, x14);
U32TO8_LITTLE(c + 60, x15);
if(bytes <= 64) {
if(bytes < 64) {
for(i = 0; i < bytes;++i) ctarget[i] = c[i];
}
x->input[12] = j12;
x->input[13] = j13;
return;
}
bytes -= 64;
c += 64;
m += 64;
}
}
+33
View File
@@ -0,0 +1,33 @@
/* $OpenBSD: chacha.h,v 1.4 2016/08/27 04:04:56 guenther Exp $ */
/*
* chacha-merged.c version 20080118
* D. J. Bernstein
* Public domain.
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef CHACHA_H
#define CHACHA_H
#include <stdlib.h>
struct chacha_ctx {
u_int input[16];
};
#define CHACHA_MINKEYLEN 16
#define CHACHA_NONCELEN 8
#define CHACHA_CTRLEN 8
#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits);
void chacha_ivsetup(struct chacha_ctx *x, const u_char *iv, const u_char *ctr);
void chacha_encrypt_bytes(struct chacha_ctx *x, const u_char *m,
u_char *c, u_int bytes);
#endif /* CHACHA_H */
File diff suppressed because it is too large. Load diff
+142
View File
@@ -0,0 +1,142 @@
#ifndef LIBSSH2_CHANNEL_H
#define LIBSSH2_CHANNEL_H
/* Copyright (C) Daniel Stenberg
*
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* _libssh2_channel_receive_window_adjust
*
* Adjust the receive window for a channel by adjustment bytes. If the amount
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
* adjustment amount will be queued for a later packet.
*
* Always non-blocking.
*/
int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
uint32_t adjustment,
unsigned char force,
unsigned int *store);
/*
* _libssh2_channel_flush
*
* Flush data from one (or all) stream
* Returns number of bytes flushed, or negative on failure
*/
int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid);
/*
* _libssh2_channel_free
*
* Make sure a channel is closed, then remove the channel from the session
* and free its resource(s)
*
* Returns 0 on success, negative on failure
*/
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel);
int
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
/*
* _libssh2_channel_write
*
* Send data to a channel
*/
ssize_t
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
const unsigned char *buf, size_t buflen);
/*
* _libssh2_channel_open
*
* Establish a generic session channel
*/
LIBSSH2_CHANNEL *
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
uint32_t channel_type_len,
uint32_t window_size,
uint32_t packet_size,
const unsigned char *message, size_t message_len);
/*
* _libssh2_channel_process_startup
*
* Primitive for libssh2_channel_(shell|exec|subsystem)
*/
int
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
const char *request, size_t request_len,
const char *message, size_t message_len);
/*
* _libssh2_channel_read
*
* Read data from a channel
*
* It is important to not return 0 until the currently read channel is
* complete. If we read stuff from the wire but it was no payload data to fill
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
*/
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
char *buf, size_t buflen);
uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session);
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
uint32_t channel_id);
size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
int stream_id);
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
/*
* _libssh2_channel_forward_cancel
*
* Stop listening on a remote port and free the listener
* Toss out any pending (un-accept()ed) connections
*
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
*/
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
#endif /* LIBSSH2_CHANNEL_H */
+134
View File
@@ -0,0 +1,134 @@
/*
* Copyright (c) 2013 Damien Miller <djm@mindrot.org>
*
* Adapted by Will Cosgrove <will@panic.com> for libssh2
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
/* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */
#include "libssh2_priv.h"
#include "misc.h"
#include "cipher-chachapoly.h"
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n);
int
chachapoly_init(struct chachapoly_ctx *ctx, const u_char *key, u_int keylen)
{
if(keylen != (32 + 32)) /* 2 x 256 bit keys */
return LIBSSH2_ERROR_INVAL;
chacha_keysetup(&ctx->main_ctx, key, 256);
chacha_keysetup(&ctx->header_ctx, key + 32, 256);
return 0;
}
/*
* chachapoly_crypt() operates as following:
* En/decrypt with header key 'aadlen' bytes from 'src', storing result
* to 'dest'. The ciphertext here is treated as additional authenticated
* data for MAC calculation.
* En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use
* POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication
* tag. This tag is written on encryption and verified on decryption.
*/
int
chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest,
const u_char *src, u_int len, u_int aadlen, int do_encrypt)
{
u_char seqbuf[8];
const u_char one[8] = { 1, 0, 0, 0, 0, 0, 0, 0 }; /* NB little-endian */
u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN];
int r = LIBSSH2_ERROR_INVAL;
unsigned char *ptr = NULL;
/*
* Run ChaCha20 once to generate the Poly1305 key. The IV is the
* packet sequence number.
*/
memset(poly_key, 0, sizeof(poly_key));
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->main_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->main_ctx,
poly_key, poly_key, sizeof(poly_key));
/* If decrypting, check tag before anything else */
if(!do_encrypt) {
const u_char *tag = src + aadlen + len;
poly1305_auth(expected_tag, src, aadlen + len, poly_key);
if(chachapoly_timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN)
!= 0) {
r = LIBSSH2_ERROR_DECRYPT;
goto out;
}
}
/* Crypt additional data */
if(aadlen) {
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, src, dest, aadlen);
}
/* Set Chacha's block counter to 1 */
chacha_ivsetup(&ctx->main_ctx, seqbuf, one);
chacha_encrypt_bytes(&ctx->main_ctx, src + aadlen,
dest + aadlen, len);
/* If encrypting, calculate and append tag */
if(do_encrypt) {
poly1305_auth(dest + aadlen + len, dest, aadlen + len,
poly_key);
}
r = 0;
out:
memset(expected_tag, 0, sizeof(expected_tag));
memset(seqbuf, 0, sizeof(seqbuf));
memset(poly_key, 0, sizeof(poly_key));
return r;
}
/* Decrypt and extract the encrypted packet length */
int
chachapoly_get_length(struct chachapoly_ctx *ctx, unsigned int *plenp,
unsigned int seqnr, const unsigned char *cp,
unsigned int len)
{
u_char buf[4], seqbuf[8];
unsigned char *ptr = NULL;
if(len < 4)
return -1;
ptr = &seqbuf[0];
_libssh2_store_u64(&ptr, seqnr);
chacha_ivsetup(&ctx->header_ctx, seqbuf, NULL);
chacha_encrypt_bytes(&ctx->header_ctx, cp, buf, 4);
*plenp = _libssh2_ntohu32(buf);
return 0;
}
int
chachapoly_timingsafe_bcmp(const void *b1, const void *b2, size_t n)
{
const unsigned char *p1 = b1, *p2 = b2;
int ret = 0;
for(; n > 0; n--)
ret |= *p1++ ^ *p2++;
return (ret != 0);
}
+41
View File
@@ -0,0 +1,41 @@
/* $OpenBSD: cipher-chachapoly.h,v 1.4 2014/06/24 01:13:21 djm Exp $ */
/*
* Copyright (c) Damien Miller 2013 <djm@mindrot.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef CHACHA_POLY_AEAD_H
#define CHACHA_POLY_AEAD_H
#include "chacha.h"
#include "poly1305.h"
#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */
struct chachapoly_ctx {
struct chacha_ctx main_ctx, header_ctx;
};
int chachapoly_init(struct chachapoly_ctx *cpctx,
const u_char *key, u_int keylen);
int chachapoly_crypt(struct chachapoly_ctx *cpctx, u_int seqnr,
u_char *dest, const u_char *src, u_int len, u_int aadlen,
int do_encrypt);
int chachapoly_get_length(struct chachapoly_ctx *cpctx,
u_int *plenp, u_int seqnr, const u_char *cp,
u_int len);
#endif /* CHACHA_POLY_AEAD_H */
+381
View File
@@ -0,0 +1,381 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg <daniel@haxx.se>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef LIBSSH2_HAVE_ZLIB
#include <zlib.h>
#undef compress /* dodge name clash with ZLIB macro */
#endif
#include "comp.h"
/* ********
* none *
******** */
/*
* comp_method_none_comp
*
* Minimalist compression: Absolutely none
*/
static int
comp_method_none_comp(LIBSSH2_SESSION *session,
unsigned char *dest,
size_t *dest_len,
const unsigned char *src,
size_t src_len,
void **abstract)
{
(void)session;
(void)abstract;
(void)dest;
(void)dest_len;
(void)src;
(void)src_len;
return 0;
}
/*
* comp_method_none_decomp
*
* Minimalist decompression: Absolutely none
*/
static int
comp_method_none_decomp(LIBSSH2_SESSION * session,
unsigned char **dest,
size_t *dest_len,
size_t payload_limit,
const unsigned char *src,
size_t src_len, void **abstract)
{
(void)session;
(void)payload_limit;
(void)abstract;
*dest = (unsigned char *) src;
*dest_len = src_len;
return 0;
}
static const LIBSSH2_COMP_METHOD comp_method_none = {
"none",
0, /* not really compressing */
0, /* isn't used in userauth, go figure */
NULL,
comp_method_none_comp,
comp_method_none_decomp,
NULL
};
#ifdef LIBSSH2_HAVE_ZLIB
/* ********
* zlib *
******** */
/* Memory management wrappers
* Yes, I realize we're doing a callback to a callback,
* Deal...
*/
static voidpf
comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
return (voidpf) LIBSSH2_ALLOC(session, items * size);
}
static void
comp_method_zlib_free(voidpf opaque, voidpf address)
{
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
LIBSSH2_FREE(session, address);
}
/* libssh2_comp_method_zlib_init
* All your bandwidth are belong to us (so save some)
*/
static int
comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
void **abstract)
{
z_stream *strm;
int status;
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
if(!strm) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"zlib compression/decompression");
}
strm->opaque = (voidpf) session;
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
strm->zfree = (free_func) comp_method_zlib_free;
if(compr) {
/* deflate */
status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
}
else {
/* inflate */
status = inflateInit(strm);
}
if(status != Z_OK) {
LIBSSH2_FREE(session, strm);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return LIBSSH2_ERROR_COMPRESS;
}
*abstract = strm;
return LIBSSH2_ERROR_NONE;
}
/*
* libssh2_comp_method_zlib_comp
*
* Compresses source to destination. Without allocation.
*/
static int
comp_method_zlib_comp(LIBSSH2_SESSION *session,
unsigned char *dest,
/* dest_len is a pointer to allow this function to
update it with the final actual size used */
size_t *dest_len,
const unsigned char *src,
size_t src_len,
void **abstract)
{
z_stream *strm = *abstract;
uInt out_maxlen = (uInt)*dest_len;
int status;
strm->next_in = (unsigned char *) src;
strm->avail_in = (uInt)src_len;
strm->next_out = dest;
strm->avail_out = out_maxlen;
status = deflate(strm, Z_PARTIAL_FLUSH);
if((status == Z_OK) && (strm->avail_out > 0)) {
*dest_len = out_maxlen - strm->avail_out;
return 0;
}
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib compression error %d, avail_out %u",
status, strm->avail_out));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
}
/*
* libssh2_comp_method_zlib_decomp
*
* Decompresses source to destination. Allocates the output memory.
*/
static int
comp_method_zlib_decomp(LIBSSH2_SESSION * session,
unsigned char **dest,
size_t *dest_len,
size_t payload_limit,
const unsigned char *src,
size_t src_len, void **abstract)
{
z_stream *strm = *abstract;
/* A short-term alloc of a full data chunk is better than a series of
reallocs */
char *out;
size_t out_maxlen;
if(src_len <= SIZE_MAX / 4)
out_maxlen = (uInt)src_len * 4;
else
out_maxlen = payload_limit;
/* If strm is null, then we have not yet been initialized. */
if(!strm)
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
"decompression uninitialized");
/* In practice they never come smaller than this */
if(out_maxlen < 25)
out_maxlen = 25;
if(out_maxlen > payload_limit)
out_maxlen = payload_limit;
strm->next_in = (unsigned char *) src;
strm->avail_in = (uInt)src_len;
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session,
(uInt)out_maxlen);
out = (char *) strm->next_out;
strm->avail_out = (uInt)out_maxlen;
if(!strm->next_out)
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate decompression buffer");
/* Loop until it's all inflated or hit error */
for(;;) {
int status;
size_t out_ofs;
char *newout;
status = inflate(strm, Z_PARTIAL_FLUSH);
if(status == Z_OK) {
if(strm->avail_out > 0)
/* status is OK and the output buffer has not been exhausted
so we're done */
break;
}
else if(status == Z_BUF_ERROR) {
/* the input data has been exhausted so we are done */
break;
}
else {
/* error state */
LIBSSH2_FREE(session, out);
_libssh2_debug((session, LIBSSH2_TRACE_TRANS,
"unhandled zlib error %d", status));
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"decompression failure");
}
if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
"Excessive growth in decompression phase");
}
/* If we get here we need to grow the output buffer and try again */
out_ofs = out_maxlen - strm->avail_out;
out_maxlen *= 2;
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
if(!newout) {
LIBSSH2_FREE(session, out);
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to expand decompression buffer");
}
out = newout;
strm->next_out = (unsigned char *) out + out_ofs;
strm->avail_out = (uInt)(out_maxlen - out_ofs);
}
*dest = (unsigned char *) out;
*dest_len = out_maxlen - strm->avail_out;
return 0;
}
/* libssh2_comp_method_zlib_dtor
* All done, no more compression for you
*/
static int
comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
{
z_stream *strm = *abstract;
if(strm) {
if(compr)
deflateEnd(strm);
else
inflateEnd(strm);
LIBSSH2_FREE(session, strm);
}
*abstract = NULL;
return 0;
}
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
"zlib",
1, /* yes, this compresses */
1, /* do compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
comp_method_zlib_dtor,
};
static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = {
"zlib@openssh.com",
1, /* yes, this compresses */
0, /* don't use compression during userauth */
comp_method_zlib_init,
comp_method_zlib_comp,
comp_method_zlib_decomp,
comp_method_zlib_dtor,
};
#endif /* LIBSSH2_HAVE_ZLIB */
/* If compression is enabled by the API, then this array is used which then
may allow compression if zlib is available at build time */
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
#ifdef LIBSSH2_HAVE_ZLIB
&comp_method_zlib,
&comp_method_zlib_openssh,
#endif /* LIBSSH2_HAVE_ZLIB */
&comp_method_none,
NULL
};
/* If compression is disabled by the API, then this array is used */
static const LIBSSH2_COMP_METHOD *no_comp_methods[] = {
&comp_method_none,
NULL
};
const LIBSSH2_COMP_METHOD **
_libssh2_comp_methods(LIBSSH2_SESSION *session)
{
if(session->flag.compress)
return comp_methods;
else
return no_comp_methods;
}
+45
View File
@@ -0,0 +1,45 @@
#ifndef LIBSSH2_COMP_H
#define LIBSSH2_COMP_H
/* Copyright (C) Daniel Stenberg
*
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
#endif /* LIBSSH2_COMP_H */
+549
View File
@@ -0,0 +1,549 @@
/* Copyright (C) Simon Josefsson <simon@josefsson.org>
* Copyright (C) Sara Golemon <sarag@libssh2.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "cipher-chachapoly.h"
#include <assert.h>
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
/* crypt_none_crypt
* Minimalist cipher: no encryption. DO NOT USE.
*
* The SSH2 Transport allows for unencrypted data transmission using
* the "none" cipher. Because this is such a huge security hole, it is
* typically disabled on SSH2 implementations and is disabled in libssh2
* by default as well.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
crypt_none_crypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
/* Do nothing to the data! */
return 0;
}
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
"none",
"DEK-Info: NONE",
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
0, /* iv_len */
0, /* secret_len */
0, /* flags */
NULL,
crypt_none_crypt,
NULL
};
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE) */
struct crypt_ctx
{
int encrypt;
_libssh2_cipher_type(algo);
_libssh2_cipher_ctx h;
struct chachapoly_ctx chachapoly_ctx;
};
static int
crypt_init(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
if(!ctx)
return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
LIBSSH2_FREE(session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int
crypt_encrypt(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
(void) session;
(void) seqno;
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, buf,
buf_len, firstlast);
}
static int
crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if(cctx && *cctx) {
_libssh2_cipher_dtor(&(*cctx)->h);
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
#if LIBSSH2_AES_GCM
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_gcm = {
"aes256-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256gcm
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_gcm = {
"aes128-gcm@openssh.com",
"",
16, /* blocksize */
12, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
16, /* length of the authentication tag */
LIBSSH2_CRYPT_FLAG_INTEGRATED_MAC | LIBSSH2_CRYPT_FLAG_PKTLEN_AAD,
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128gcm
};
#endif
#if LIBSSH2_AES_CTR
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
"aes128-ctr",
"",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
"aes192-ctr",
"",
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192ctr
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
"aes256-ctr",
"",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256ctr
};
#endif
#if LIBSSH2_AES_CBC
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
"aes128-cbc",
"DEK-Info: AES-128-CBC",
16, /* blocksize */
16, /* initial value length */
16, /* secret length -- 16*8 == 128bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes128
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
"aes192-cbc",
"DEK-Info: AES-192-CBC",
16, /* blocksize */
16, /* initial value length */
24, /* secret length -- 24*8 == 192bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes192
};
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
"aes256-cbc",
"DEK-Info: AES-256-CBC",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
"rijndael-cbc@lysator.liu.se",
"DEK-Info: AES-256-CBC",
16, /* blocksize */
16, /* initial value length */
32, /* secret length -- 32*8 == 256bit */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_aes256
};
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
"blowfish-cbc",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_blowfish
};
#endif /* LIBSSH2_BLOWFISH */
#if LIBSSH2_RC4
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
"arcfour",
"DEK-Info: RC4",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
static int
crypt_init_arcfour128(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
int rc;
rc = crypt_init(session, method, iv, free_iv, secret, free_secret,
encrypt, abstract);
if(rc == 0) {
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
unsigned char block[8];
size_t discard = 1536;
for(; discard; discard -= 8)
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
method->blocksize, MIDDLE_BLOCK);
/* Not all middle, but here it doesn't matter */
}
return rc;
}
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
"arcfour128",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init_arcfour128,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_arcfour
};
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
"cast128-cbc",
"",
8, /* blocksize */
8, /* initial value length */
16, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_cast5
};
#endif /* LIBSSH2_CAST */
#if LIBSSH2_3DES
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
"3des-cbc",
"DEK-Info: DES-EDE3-CBC",
8, /* blocksize */
8, /* initial value length */
24, /* secret length */
0, /* length of the authentication tag */
0, /* flags */
&crypt_init,
NULL,
&crypt_encrypt,
&crypt_dtor,
_libssh2_cipher_3des
};
#endif
static int
crypt_init_chacha20_poly(LIBSSH2_SESSION * session,
const LIBSSH2_CRYPT_METHOD * method,
unsigned char *iv, int *free_iv,
unsigned char *secret, int *free_secret,
int encrypt, void **abstract)
{
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
sizeof(struct crypt_ctx));
(void)iv;
if(!ctx)
return LIBSSH2_ERROR_ALLOC;
ctx->encrypt = encrypt;
ctx->algo = method->algo;
if(chachapoly_init(&ctx->chachapoly_ctx, secret, method->secret_len)) {
LIBSSH2_FREE(session, ctx);
return -1;
}
*abstract = ctx;
*free_iv = 1;
*free_secret = 1;
return 0;
}
static int
crypt_encrypt_chacha20_poly_buffer(LIBSSH2_SESSION * session,
unsigned int seqno,
unsigned char *buf,
size_t buf_len,
void **abstract,
int firstlast)
{
int ret = 1;
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
(void)firstlast;
if(ctx) {
if(ctx->encrypt) {
/* requires out_buf to be large enough to hold encrypted output
plus auth tag (auth len)
buf is a full packet so we need to subtract packet length from
length
*/
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len) - 4, 4, ctx->encrypt);
}
else {
/* buf is full packet including size and auth tag but buf_len
doesn't include size */
ret = chachapoly_crypt(&ctx->chachapoly_ctx, seqno, buf, buf,
((u_int)buf_len), 4, ctx->encrypt);
/* the api expects the size field to already be removed
from the decrypted packet so we'll help it out */
if(ret == 0) {
memmove(buf, buf + 4, buf_len - 4);
}
}
}
return (ret == 0 ? 0 : 1);
}
static int
crypt_get_length_chacha20_poly(LIBSSH2_SESSION * session, unsigned int seqno,
unsigned char *data, size_t data_size,
unsigned int *len, void **abstract)
{
struct crypt_ctx *ctx = *(struct crypt_ctx **) abstract;
(void)session;
return chachapoly_get_length(&ctx->chachapoly_ctx, len, seqno, data,
(u_int)data_size);
}
static int
crypt_dtor_chacha20_poly(LIBSSH2_SESSION * session, void **abstract)
{
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
if(cctx && *cctx) {
LIBSSH2_FREE(session, *cctx);
*abstract = NULL;
}
return 0;
}
static const LIBSSH2_CRYPT_METHOD
libssh2_crypt_method_chacha20_poly1305_openssh = {
"chacha20-poly1305@openssh.com",
"",
8, /* blocksize */
0, /* initial value length */
64, /* secret length */
16, /* length of the auth_tag */
LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET, /* flags */
&crypt_init_chacha20_poly,
&crypt_get_length_chacha20_poly,
&crypt_encrypt_chacha20_poly_buffer,
&crypt_dtor_chacha20_poly,
_libssh2_cipher_chacha20 /* not actually used */
};
/* These are the crypt methods that are available to be negotiated. Methods
towards the start are chosen in preference to ones further down the list. */
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
&libssh2_crypt_method_chacha20_poly1305_openssh,
#if LIBSSH2_AES_GCM
&libssh2_crypt_method_aes256_gcm,
&libssh2_crypt_method_aes128_gcm,
#endif /* LIBSSH2_AES_GCM */
#if LIBSSH2_AES_CTR
&libssh2_crypt_method_aes256_ctr,
&libssh2_crypt_method_aes192_ctr,
&libssh2_crypt_method_aes128_ctr,
#endif /* LIBSSH2_AES_CTR */
#if LIBSSH2_AES_CBC
&libssh2_crypt_method_aes256_cbc,
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
&libssh2_crypt_method_aes192_cbc,
&libssh2_crypt_method_aes128_cbc,
#endif /* LIBSSH2_AES_CBC */
#if LIBSSH2_BLOWFISH
&libssh2_crypt_method_blowfish_cbc,
#endif /* LIBSSH2_BLOWFISH */
#if LIBSSH2_RC4
&libssh2_crypt_method_arcfour128,
&libssh2_crypt_method_arcfour,
#endif /* LIBSSH2_RC4 */
#if LIBSSH2_CAST
&libssh2_crypt_method_cast128_cbc,
#endif /* LIBSSH2_CAST */
#if LIBSSH2_3DES
&libssh2_crypt_method_3des_cbc,
#endif /* LIBSSH2_DES */
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_CRYPT_NONE_INSECURE)
&libssh2_crypt_method_none,
#endif
NULL
};
/* Expose to kex.c */
const LIBSSH2_CRYPT_METHOD **
libssh2_crypt_methods(void)
{
return _libssh2_crypt_methods;
}
+19
View File
@@ -0,0 +1,19 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_C
#include "libssh2_priv.h"
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.c"
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.c"
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.c"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.c"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.c"
#endif
+357
View File
@@ -0,0 +1,357 @@
#ifndef LIBSSH2_CRYPTO_H
#define LIBSSH2_CRYPTO_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
#include "openssl.h"
#elif defined(LIBSSH2_LIBGCRYPT)
#include "libgcrypt.h"
#elif defined(LIBSSH2_MBEDTLS)
#include "mbedtls.h"
#elif defined(LIBSSH2_OS400QC3)
#include "os400qc3.h"
#elif defined(LIBSSH2_WINCNG)
#include "wincng.h"
#else
#error "no cryptography backend selected"
#endif
/* return: success = 1, error = 0 */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx);
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen);
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen);
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data);
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
#define LIBSSH2_ED25519_KEY_LEN 32
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
#define LIBSSH2_ED25519_SIG_LEN 64
#if LIBSSH2_RSA
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata, unsigned long coefflen);
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
#if LIBSSH2_RSA_SHA1
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len);
#endif
#if LIBSSH2_RSA_SHA2
int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature,
size_t *signature_len);
int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
size_t hash_len,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len);
#endif
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif
#if LIBSSH2_DSA
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *gdata,
unsigned long glen,
const unsigned char *ydata,
unsigned long ylen,
const unsigned char *x, unsigned long x_len);
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, size_t m_len);
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
size_t hash_len, unsigned char *sig);
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif
#if LIBSSH2_ECDSA
int
_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx,
const unsigned char *k,
size_t k_len,
libssh2_curve_type type);
int
_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filename,
unsigned const char *passphrase);
int
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
const unsigned char *r, size_t r_len,
const unsigned char *s, size_t s_len,
const unsigned char *m, size_t m_len);
int
_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
_libssh2_ec_key **out_private_key,
unsigned char **out_public_key_octal,
size_t *out_public_key_octal_len,
libssh2_curve_type curve_type);
int
_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
const unsigned char *server_public_key,
size_t server_public_key_len);
int
_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx,
const unsigned char *hash, size_t hash_len,
unsigned char **signature, size_t *signature_len);
int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION * session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
libssh2_curve_type
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx);
int
_libssh2_ecdsa_curve_type_from_name(const char *name,
libssh2_curve_type *out_type);
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
int
_libssh2_curve25519_new(LIBSSH2_SESSION *session, uint8_t **out_public_key,
uint8_t **out_private_key);
int
_libssh2_curve25519_gen_k(_libssh2_bn **k,
uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]);
int
_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
size_t s_len, const uint8_t *m, size_t m_len);
int
_libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filename, const uint8_t *passphrase);
int
_libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filename,
const uint8_t *passphrase);
int
_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const unsigned char *raw_pub_key,
const size_t key_len);
int
_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
uint8_t **out_sig, size_t *out_sig_len,
const uint8_t *message, size_t message_len);
int
_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
int
_libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
LIBSSH2_SESSION *session,
const char *filedata,
size_t filedata_len,
unsigned const char *passphrase);
#endif /* LIBSSH2_ED25519 */
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv,
unsigned char *secret, int encrypt);
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blocksize,
int firstlast);
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase);
int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase);
/**
* @function _libssh2_supported_key_sign_algorithms
* @abstract Returns supported algorithms used for upgrading public
* key signing RFC 8332
* @discussion Based on the incoming key_method value, this function
* will return supported algorithms that can upgrade the key method
* @related _libssh2_key_sign_algorithm()
* @param key_method current key method, usually the default key sig method
* @param key_method_len length of the key method buffer
* @result comma separated list of supported upgrade options per RFC 8332, if
* there is no upgrade option return NULL
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len);
#endif /* LIBSSH2_CRYPTO_H */
+76
View File
@@ -0,0 +1,76 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_MD5_PEM LIBSSH2_MD5
#ifdef LIBSSH2_NO_MD5
#undef LIBSSH2_MD5
#define LIBSSH2_MD5 0
#endif
#ifdef LIBSSH2_NO_MD5_PEM
#undef LIBSSH2_MD5_PEM
#define LIBSSH2_MD5_PEM 0
#endif
#ifdef LIBSSH2_NO_HMAC_RIPEMD
#undef LIBSSH2_HMAC_RIPEMD
#define LIBSSH2_HMAC_RIPEMD 0
#endif
#if !defined(LIBSSH2_DSA_ENABLE)
#undef LIBSSH2_DSA
#define LIBSSH2_DSA 0
#endif
#ifdef LIBSSH2_NO_RSA
#undef LIBSSH2_RSA
#define LIBSSH2_RSA 0
#endif
#ifdef LIBSSH2_NO_RSA_SHA1
#undef LIBSSH2_RSA_SHA1
#define LIBSSH2_RSA_SHA1 0
#endif
#ifdef LIBSSH2_NO_ECDSA
#undef LIBSSH2_ECDSA
#define LIBSSH2_ECDSA 0
#endif
#ifdef LIBSSH2_NO_ED25519
#undef LIBSSH2_ED25519
#define LIBSSH2_ED25519 0
#endif
#ifdef LIBSSH2_NO_AES_CTR
#undef LIBSSH2_AES_CTR
#define LIBSSH2_AES_CTR 0
#endif
#ifdef LIBSSH2_NO_AES_CBC
#undef LIBSSH2_AES_CBC
#define LIBSSH2_AES_CBC 0
#endif
#ifdef LIBSSH2_NO_BLOWFISH
#undef LIBSSH2_BLOWFISH
#define LIBSSH2_BLOWFISH 0
#endif
#ifdef LIBSSH2_NO_RC4
#undef LIBSSH2_RC4
#define LIBSSH2_RC4 0
#endif
#ifdef LIBSSH2_NO_CAST
#undef LIBSSH2_CAST
#define LIBSSH2_CAST 0
#endif
#ifdef LIBSSH2_NO_3DES
#undef LIBSSH2_3DES
#define LIBSSH2_3DES 0
#endif
+80
View File
@@ -0,0 +1,80 @@
/* Copyright (C) Lars Nordin <Lars.Nordin@SDlabs.se>
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
static int _libssh2_initialized = 0;
static int _libssh2_init_flags = 0;
LIBSSH2_API int
libssh2_init(int flags)
{
if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_init();
}
_libssh2_initialized++;
_libssh2_init_flags |= flags;
return 0;
}
LIBSSH2_API void
libssh2_exit(void)
{
if(_libssh2_initialized == 0)
return;
_libssh2_initialized--;
if(_libssh2_initialized == 0 &&
!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
libssh2_crypto_exit();
}
return;
}
void
_libssh2_init_if_needed(void)
{
if(_libssh2_initialized == 0)
(void)libssh2_init(0);
}
File diff suppressed because it is too large. Load diff
+101
View File
@@ -0,0 +1,101 @@
/* Copyright (C) Simon Josefsson
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "transport.h" /* _libssh2_transport_write */
/* Keep-alive stuff. */
LIBSSH2_API void
libssh2_keepalive_config(LIBSSH2_SESSION *session,
int want_reply,
unsigned int interval)
{
if(interval == 1)
session->keepalive_interval = 2;
else
session->keepalive_interval = interval;
session->keepalive_want_reply = want_reply ? 1 : 0;
}
LIBSSH2_API int
libssh2_keepalive_send(LIBSSH2_SESSION *session,
int *seconds_to_next)
{
time_t now;
if(!session->keepalive_interval) {
if(seconds_to_next)
*seconds_to_next = 0;
return 0;
}
now = time(NULL);
if(session->keepalive_last_sent + session->keepalive_interval <= now) {
/* Format is
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
unsigned char keepalive_data[]
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
size_t len = sizeof(keepalive_data) - 1;
int rc;
keepalive_data[len - 1] =
(unsigned char)session->keepalive_want_reply;
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
already full, sending another keepalive is not useful. */
if(rc && rc != LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send keepalive message");
return rc;
}
session->keepalive_last_sent = now;
if(seconds_to_next)
*seconds_to_next = session->keepalive_interval;
}
else if(seconds_to_next) {
*seconds_to_next = (int) (session->keepalive_last_sent - now)
+ session->keepalive_interval;
}
return 0;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+863
View File
@@ -0,0 +1,863 @@
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifdef LIBSSH2_CRYPTO_C /* Compile this via crypto.c */
int _libssh2_hmac_ctx_init(libssh2_hmac_ctx *ctx)
{
*ctx = NULL;
return 1;
}
#if LIBSSH2_MD5
int _libssh2_hmac_md5_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
#if LIBSSH2_HMAC_RIPEMD
int _libssh2_hmac_ripemd160_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
#endif
int _libssh2_hmac_sha1_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha256_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_sha512_init(libssh2_hmac_ctx *ctx,
void *key, size_t keylen)
{
gcry_error_t err;
err = gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
err = gcry_md_setkey(*ctx, key, keylen);
if(gcry_err_code(err) != GPG_ERR_NO_ERROR)
return 0;
return 1;
}
int _libssh2_hmac_update(libssh2_hmac_ctx *ctx,
const void *data, size_t datalen)
{
gcry_md_write(*ctx, data, datalen);
return 1;
}
int _libssh2_hmac_final(libssh2_hmac_ctx *ctx, void *data)
{
unsigned char *res = gcry_md_read(*ctx, 0);
if(!res)
return 0;
memcpy(data, res, gcry_md_get_algo_dlen(gcry_md_get_algo(*ctx)));
return 1;
}
void _libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx)
{
gcry_md_close(*ctx);
}
#if LIBSSH2_RSA
int
_libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
const unsigned char *edata,
unsigned long elen,
const unsigned char *ndata,
unsigned long nlen,
const unsigned char *ddata,
unsigned long dlen,
const unsigned char *pdata,
unsigned long plen,
const unsigned char *qdata,
unsigned long qlen,
const unsigned char *e1data,
unsigned long e1len,
const unsigned char *e2data,
unsigned long e2len,
const unsigned char *coeffdata, unsigned long coefflen)
{
int rc;
(void)e1data;
(void)e1len;
(void)e2data;
(void)e2len;
if(ddata) {
rc = gcry_sexp_build(rsa, NULL,
"(private-key(rsa(n%b)(e%b)(d%b)(q%b)(p%b)(u%b)))",
nlen, ndata, elen, edata, dlen, ddata, plen, pdata,
qlen, qdata, coefflen, coeffdata);
}
else {
rc = gcry_sexp_build(rsa, NULL, "(public-key(rsa(n%b)(e%b)))",
nlen, ndata, elen, edata);
}
if(rc) {
*rsa = NULL;
return -1;
}
return 0;
}
#if LIBSSH2_RSA_SHA1
int
_libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
const unsigned char *sig,
size_t sig_len,
const unsigned char *m, size_t m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
if(libssh2_sha1(m, m_len, hash)) {
return -1;
}
rc = gcry_sexp_build(&s_hash, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
SHA_DIGEST_LENGTH, hash);
if(rc) {
return -1;
}
rc = gcry_sexp_build(&s_sig, NULL, "(sig-val(rsa(s %b)))", sig_len, sig);
if(rc) {
gcry_sexp_release(s_hash);
return -1;
}
rc = gcry_pk_verify(s_sig, s_hash, rsa);
gcry_sexp_release(s_sig);
gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new(libssh2_dsa_ctx ** dsactx,
const unsigned char *p,
unsigned long p_len,
const unsigned char *q,
unsigned long q_len,
const unsigned char *g,
unsigned long g_len,
const unsigned char *y,
unsigned long y_len,
const unsigned char *x, unsigned long x_len)
{
int rc;
if(x_len) {
rc = gcry_sexp_build(dsactx, NULL,
"(private-key(dsa(p%b)(q%b)(g%b)(y%b)(x%b)))",
p_len, p, q_len, q, g_len, g, y_len, y, x_len, x);
}
else {
rc = gcry_sexp_build(dsactx, NULL,
"(public-key(dsa(p%b)(q%b)(g%b)(y%b)))",
p_len, p, q_len, q, g_len, g, y_len, y);
}
if(rc) {
*dsactx = NULL;
return -1;
}
return 0;
}
#endif
#if LIBSSH2_RSA
int
_libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)rsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
LIBSSH2_SESSION * session,
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
size_t datalen;
int ret;
unsigned char *n, *e, *d, *p, *q, *e1, *e2, *coeff;
unsigned int nlen, elen, dlen, plen, qlen, e1len, e2len, coefflen;
fp = fopen(filename, FOPEN_READTEXT);
if(!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN RSA PRIVATE KEY-----",
"-----END RSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen);
fclose(fp);
if(ret) {
return -1;
}
save_data = data;
if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret || (nlen != 1 && *n != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &n, &nlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e, &elen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &d, &dlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e1, &e1len);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &e2, &e2len);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &coeff, &coefflen);
if(ret) {
ret = -1;
goto fail;
}
if(_libssh2_rsa_new(rsa, e, elen, n, nlen, d, dlen, p, plen,
q, qlen, e1, e1len, e2, e2len, coeff, coefflen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filedata, size_t filedata_len,
unsigned const char *passphrase)
{
(void)dsa;
(void)filedata;
(void)filedata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract private key from memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
LIBSSH2_SESSION * session,
const char *filename, unsigned const char *passphrase)
{
FILE *fp;
unsigned char *data, *save_data;
size_t datalen;
int ret;
unsigned char *p, *q, *g, *y, *x;
unsigned int plen, qlen, glen, ylen, xlen;
fp = fopen(filename, FOPEN_READTEXT);
if(!fp) {
return -1;
}
ret = _libssh2_pem_parse(session,
"-----BEGIN DSA PRIVATE KEY-----",
"-----END DSA PRIVATE KEY-----",
passphrase,
fp, &data, &datalen);
fclose(fp);
if(ret) {
return -1;
}
save_data = data;
if(_libssh2_pem_decode_sequence(&data, &datalen)) {
ret = -1;
goto fail;
}
/* First read Version field (should be 0). */
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret || (plen != 1 && *p != '\0')) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &p, &plen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &q, &qlen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &g, &glen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &y, &ylen);
if(ret) {
ret = -1;
goto fail;
}
ret = _libssh2_pem_decode_integer(&data, &datalen, &x, &xlen);
if(ret) {
ret = -1;
goto fail;
}
if(datalen) {
ret = -1;
goto fail;
}
if(_libssh2_dsa_new(dsa, p, plen, q, qlen, g, glen, y, ylen, x, xlen)) {
ret = -1;
goto fail;
}
ret = 0;
fail:
LIBSSH2_FREE(session, save_data);
return ret;
}
#endif
#if LIBSSH2_RSA
#if LIBSSH2_RSA_SHA1
int
_libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
libssh2_rsa_ctx * rsactx,
const unsigned char *hash,
size_t hash_len,
unsigned char **signature, size_t *signature_len)
{
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int rc;
const char *tmp;
size_t size;
if(hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
if(gcry_sexp_build(&data, NULL,
"(data (flags pkcs1) (hash sha1 %b))",
hash_len, hash)) {
return -1;
}
rc = gcry_pk_sign(&sig_sexp, data, rsactx);
gcry_sexp_release(data);
if(rc) {
return -1;
}
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if(!data) {
return -1;
}
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp) {
gcry_sexp_release(data);
return -1;
}
if(tmp[0] == '\0') {
tmp++;
size--;
}
*signature = LIBSSH2_ALLOC(session, size);
if(!*signature) {
gcry_sexp_release(data);
return -1;
}
memcpy(*signature, tmp, size);
*signature_len = size;
gcry_sexp_release(data);
return rc;
}
#endif
#endif
#if LIBSSH2_DSA
int
_libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
const unsigned char *hash,
size_t hash_len, unsigned char *sig)
{
unsigned char zhash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t sig_sexp;
gcry_sexp_t data;
int ret;
const char *tmp;
size_t size;
if(hash_len != SHA_DIGEST_LENGTH) {
return -1;
}
memcpy(zhash + 1, hash, hash_len);
zhash[0] = 0;
if(gcry_sexp_build(&data, NULL, "(data (value %b))",
(int)(hash_len + 1), zhash)) {
return -1;
}
ret = gcry_pk_sign(&sig_sexp, data, dsactx);
gcry_sexp_release(data);
if(ret) {
return -1;
}
memset(sig, 0, 40);
/* Extract R. */
data = gcry_sexp_find_token(sig_sexp, "r", 0);
if(!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp)
goto err;
if(tmp[0] == '\0') {
tmp++;
size--;
}
if(size < 1 || size > 20)
goto err;
memcpy(sig + (20 - size), tmp, size);
gcry_sexp_release(data);
/* Extract S. */
data = gcry_sexp_find_token(sig_sexp, "s", 0);
if(!data)
goto err;
tmp = gcry_sexp_nth_data(data, 1, &size);
if(!tmp)
goto err;
if(tmp[0] == '\0') {
tmp++;
size--;
}
if(size < 1 || size > 20)
goto err;
memcpy(sig + 20 + (20 - size), tmp, size);
goto out;
err:
ret = -1;
out:
if(sig_sexp) {
gcry_sexp_release(sig_sexp);
}
if(data) {
gcry_sexp_release(data);
}
return ret;
}
int
_libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
const unsigned char *sig,
const unsigned char *m, size_t m_len)
{
unsigned char hash[SHA_DIGEST_LENGTH + 1];
gcry_sexp_t s_sig, s_hash;
int rc = -1;
if(libssh2_sha1(m, m_len, hash + 1)) {
return -1;
}
hash[0] = 0;
if(gcry_sexp_build(&s_hash, NULL, "(data(flags raw)(value %b))",
SHA_DIGEST_LENGTH + 1, hash)) {
return -1;
}
if(gcry_sexp_build(&s_sig, NULL, "(sig-val(dsa(r %b)(s %b)))",
20, sig, 20, sig + 20)) {
gcry_sexp_release(s_hash);
return -1;
}
rc = gcry_pk_verify(s_sig, s_hash, dsactx);
gcry_sexp_release(s_sig);
gcry_sexp_release(s_hash);
return (rc == 0) ? 0 : -1;
}
#endif
int
_libssh2_cipher_init(_libssh2_cipher_ctx * h,
_libssh2_cipher_type(algo),
unsigned char *iv, unsigned char *secret, int encrypt)
{
int ret;
int cipher = _libssh2_gcry_cipher(algo);
int mode = _libssh2_gcry_mode(algo);
size_t keylen = gcry_cipher_get_algo_keylen(cipher);
(void)encrypt;
ret = gcry_cipher_open(h, cipher, mode, 0);
if(ret) {
return -1;
}
ret = gcry_cipher_setkey(*h, secret, keylen);
if(ret) {
gcry_cipher_close(*h);
return -1;
}
if(mode != GCRY_CIPHER_MODE_STREAM) {
size_t blklen = gcry_cipher_get_algo_blklen(cipher);
if(mode == GCRY_CIPHER_MODE_CTR)
ret = gcry_cipher_setctr(*h, iv, blklen);
else
ret = gcry_cipher_setiv(*h, iv, blklen);
if(ret) {
gcry_cipher_close(*h);
return -1;
}
}
return 0;
}
int
_libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
_libssh2_cipher_type(algo),
int encrypt, unsigned char *block, size_t blklen,
int firstlast)
{
int ret;
(void)algo;
(void)firstlast;
if(encrypt) {
ret = gcry_cipher_encrypt(*ctx, block, blklen, block, blklen);
}
else {
ret = gcry_cipher_decrypt(*ctx, block, blklen, block, blklen);
}
return ret;
}
int
_libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_METHOD_NOT_SUPPORTED,
"Unable to extract public key from private "
"key in memory: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
const char *privatekey,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)privatekey;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public key from private key file: "
"Method unimplemented in libgcrypt backend");
}
int
_libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
unsigned char **method,
size_t *method_len,
unsigned char **pubkeydata,
size_t *pubkeydata_len,
int *algorithm,
unsigned char *flags,
const char **application,
const unsigned char **key_handle,
size_t *handle_len,
const char *privatekeydata,
size_t privatekeydata_len,
const char *passphrase)
{
(void)method;
(void)method_len;
(void)pubkeydata;
(void)pubkeydata_len;
(void)algorithm;
(void)flags;
(void)application;
(void)key_handle;
(void)handle_len;
(void)privatekeydata;
(void)privatekeydata_len;
(void)passphrase;
return _libssh2_error(session, LIBSSH2_ERROR_FILE,
"Unable to extract public SK key from private key file: "
"Method unimplemented in libgcrypt backend");
}
void _libssh2_init_aes_ctr(void)
{
/* no implementation */
}
void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx)
{
*dhctx = gcry_mpi_new(0); /* Random from client */
}
int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order)
{
/* Generate x and e */
gcry_mpi_randomize(*dhctx, group_order * 8 - 1, GCRY_WEAK_RANDOM);
gcry_mpi_powm(public, g, *dhctx, p);
return 0;
}
int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p)
{
/* Compute the shared secret */
gcry_mpi_powm(secret, f, *dhctx, p);
return 0;
}
void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx)
{
gcry_mpi_release(*dhctx);
*dhctx = NULL;
}
/* _libssh2_supported_key_sign_algorithms
*
* Return supported key hash algo upgrades, see crypto.h
*
*/
const char *
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
unsigned char *key_method,
size_t key_method_len)
{
(void)session;
(void)key_method;
(void)key_method_len;
return NULL;
}
#endif /* LIBSSH2_CRYPTO_C */
+235
View File
@@ -0,0 +1,235 @@
#ifndef LIBSSH2_LIBGCRYPT_H
#define LIBSSH2_LIBGCRYPT_H
/*
* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_gcrypt
#include <gcrypt.h>
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 1
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 1
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 0
#define LIBSSH2_DSA 1
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
(gcry_randomize((buf), (len), GCRY_STRONG_RANDOM), 0)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
#define libssh2_sha1_ctx gcry_md_hd_t
/* returns 0 in case of failure */
#define libssh2_sha1_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
#define libssh2_sha1_update(ctx, data, len) \
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha1_final(ctx, out) \
(memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha1(message, len, out) \
(gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len), 0)
#define libssh2_sha256_ctx gcry_md_hd_t
#define libssh2_sha256_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
#define libssh2_sha256_update(ctx, data, len) \
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha256_final(ctx, out) \
(memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha256(message, len, out) \
(gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len), 0)
#define libssh2_sha384_ctx gcry_md_hd_t
#define libssh2_sha384_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
#define libssh2_sha384_update(ctx, data, len) \
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha384_final(ctx, out) \
(memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha384(message, len, out) \
(gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len), 0)
#define libssh2_sha512_ctx gcry_md_hd_t
#define libssh2_sha512_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
#define libssh2_sha512_update(ctx, data, len) \
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_sha512_final(ctx, out) \
(memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#define libssh2_sha512(message, len, out) \
(gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len), 0)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx gcry_md_hd_t
#define libssh2_md5_init(ctx) \
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
#define libssh2_md5_update(ctx, data, len) \
(gcry_md_write(ctx, (unsigned char *) data, len), 1)
#define libssh2_md5_final(ctx, out) \
(memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), \
gcry_md_close(ctx), 1)
#endif
#define libssh2_hmac_ctx gcry_md_hd_t
#define libssh2_crypto_init() gcry_control(GCRYCTL_DISABLE_SECMEM)
#define libssh2_crypto_exit()
#define libssh2_rsa_ctx struct gcry_sexp
#define _libssh2_rsa_free(rsactx) gcry_sexp_release(rsactx)
#define libssh2_dsa_ctx struct gcry_sexp
#define _libssh2_dsa_free(dsactx) gcry_sexp_release(dsactx)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
#define _libssh2_cipher_type(name) int name
#define _libssh2_cipher_ctx gcry_cipher_hd_t
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
#define _libssh2_gcry_cipher(c) (c >> 8)
#define _libssh2_gcry_mode(m) (m & 0xFF)
#define _libssh2_cipher_aes256ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes192ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes128ctr \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
#define _libssh2_cipher_aes256 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes192 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_aes128 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_blowfish \
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_arcfour \
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_cast5 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_3des \
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
#define _libssh2_cipher_chacha20 \
_libssh2_gcry_ciphermode(GCRY_CIPHER_CHACHA20, GCRY_CIPHER_MODE_STREAM)
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
#define _libssh2_bn struct gcry_mpi
#define _libssh2_bn_ctx int
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
#define _libssh2_bn_init() gcry_mpi_new(0)
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
new bignum */
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
#define _libssh2_bn_from_bin(bn, len, val) \
gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
#define _libssh2_bn_to_bin(bn, val) \
gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
#define _libssh2_bn_bytes(bn) \
(gcry_mpi_get_nbits(bn) / 8 + \
((gcry_mpi_get_nbits(bn) % 8 == 0) ? 0 : 1))
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits(bn)
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx struct gcry_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_init_aes_ctr(void);
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order);
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_LIBGCRYPT_H */
+48
View File
@@ -0,0 +1,48 @@
/***************************************************************************
* libssh2 Windows resource file
* Copyright (C) The libssh2 project and its contributors.
*
* SPDX-License-Identifier: BSD-3-Clause
***************************************************************************/
#include <winver.h>
#include "libssh2.h"
LANGUAGE 0, 0
#define RC_VERSION LIBSSH2_VERSION_MAJOR, LIBSSH2_VERSION_MINOR, LIBSSH2_VERSION_PATCH, 0
VS_VERSION_INFO VERSIONINFO
FILEVERSION RC_VERSION
PRODUCTVERSION RC_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#if defined(LIBSSH2DEBUG) || defined(_DEBUG)
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0
#endif
FILEOS VOS__WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
BEGIN
VALUE "CompanyName", "The libssh2 library, https://libssh2.org/\0"
VALUE "FileDescription", "libssh2 Shared Library\0"
VALUE "FileVersion", LIBSSH2_VERSION "\0"
VALUE "InternalName", "libssh2\0"
VALUE "OriginalFilename", "libssh2.dll\0"
VALUE "ProductName", "The libssh2 library\0"
VALUE "ProductVersion", LIBSSH2_VERSION "\0"
VALUE "LegalCopyright", "Copyright (C) " LIBSSH2_COPYRIGHT "\0"
VALUE "License", "https://libssh2.org/license.html\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0409, 0x04b0 /* 0x0409: en-US, 1200/0x04b0: UTF-16LE */
END
END
@@ -0,0 +1,76 @@
/* Copyright (C) Alexander Lamaison <alexander.lamaison@gmail.com>
* Copyright (C) Douglas Gilbert
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Headers */
#cmakedefine HAVE_UNISTD_H
#cmakedefine HAVE_INTTYPES_H
#cmakedefine HAVE_SYS_SELECT_H
#cmakedefine HAVE_SYS_UIO_H
#cmakedefine HAVE_SYS_SOCKET_H
#cmakedefine HAVE_SYS_IOCTL_H
#cmakedefine HAVE_SYS_TIME_H
#cmakedefine HAVE_SYS_UN_H
/* for example and tests */
#cmakedefine HAVE_ARPA_INET_H
#cmakedefine HAVE_NETINET_IN_H
/* Functions */
#cmakedefine HAVE_GETTIMEOFDAY
#cmakedefine HAVE_STRTOLL
#cmakedefine HAVE_STRTOI64
#cmakedefine HAVE_SNPRINTF
#cmakedefine HAVE_EXPLICIT_BZERO
#cmakedefine HAVE_EXPLICIT_MEMSET
#cmakedefine HAVE_MEMSET_S
#cmakedefine HAVE_POLL
#cmakedefine HAVE_SELECT
/* Socket non-blocking support */
#cmakedefine HAVE_O_NONBLOCK
#cmakedefine HAVE_FIONBIO
#cmakedefine HAVE_IOCTLSOCKET_CASE
#cmakedefine HAVE_SO_NONBLOCK
/* attribute to export symbol */
#if defined(LIBSSH2_EXPORTS) && defined(LIBSSH2_LIBRARY)
#cmakedefine LIBSSH2_API ${LIBSSH2_API}
#endif
File diff suppressed because it is too large. Load diff
+103
View File
@@ -0,0 +1,103 @@
/* Copyright (C) Viktor Szakats
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_SETUP_H
#define LIBSSH2_SETUP_H
/* Header for platform/compiler-specific initialization.
Used by 'src', 'example', 'tests' */
/* Define mingw-w64 version macros, eg __MINGW{32,64}_{MINOR,MAJOR}_VERSION */
#ifdef __MINGW32__
#include <_mingw.h>
#endif
/* Configuration provided by build tools (autotools and CMake),
and via platform-specific directories for os400 and vms */
#if defined(HAVE_CONFIG_H) || defined(__OS400__) || defined(__VMS)
#include "libssh2_config.h"
/* Hand-crafted configuration for platforms which lack config tool.
Keep this synced with root CMakeLists.txt */
#elif defined(_WIN32)
#define HAVE_SELECT
#define HAVE_SNPRINTF
#ifdef __MINGW32__
# define HAVE_UNISTD_H
# define HAVE_INTTYPES_H
# define HAVE_SYS_TIME_H
# define HAVE_GETTIMEOFDAY
# define HAVE_STRTOLL
#elif defined(_MSC_VER)
# if _MSC_VER >= 1800
# define HAVE_INTTYPES_H
# define HAVE_STRTOLL
# else
# define HAVE_STRTOI64
# endif
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# endif
#endif
#endif /* defined(HAVE_CONFIG_H) */
/* Below applies to both auto-detected and hand-crafted configs */
#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#ifndef NOGDI
#define NOGDI
#endif
#ifndef NONLS
#define NONLS
#endif
#ifdef __MINGW32__
# ifdef __MINGW64_VERSION_MAJOR
/* Number of bits in a file offset, on hosts where this is settable. */
# ifndef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 64
# endif
# endif
#elif defined(_MSC_VER)
# ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS /* for fopen(), getenv() */
# endif
# if !defined(LIBSSH2_LIBRARY) || defined(LIBSSH2_TESTS)
/* apply to examples and tests only */
# ifndef _CRT_NONSTDC_NO_DEPRECATE
# define _CRT_NONSTDC_NO_DEPRECATE /* for strdup(), write() */
# endif
# ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
# define _WINSOCK_DEPRECATED_NO_WARNINGS /* for inet_addr() */
# endif
/* we cannot access our internal snprintf() implementation in examples and
tests when linking to a shared libssh2. */
# if _MSC_VER < 1900
# undef HAVE_SNPRINTF
# define HAVE_SNPRINTF
# define snprintf _snprintf
# endif
# endif
# if _MSC_VER < 1500
# define vsnprintf _vsnprintf
# endif
# if _MSC_VER < 1900
# define strdup _strdup
/* Silence bogus warning C4127: conditional expression is constant */
# pragma warning(disable:4127)
# endif
#endif
#endif /* _WIN32 */
#endif /* LIBSSH2_SETUP_H */
+553
View File
@@ -0,0 +1,553 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "mac.h"
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
/* mac_none_MAC
*
* Minimalist MAC: No MAC. DO NOT USE.
*
* The SSH2 Transport allows implementations to forego a message
* authentication code. While this is less of a security risk than using
* a "none" cipher, it is still not recommended as disabling MAC hashes
* removes a layer of security.
*
* Enabling this option will allow for "none" as a negotiable method,
* however it still requires that the method be advertised by the remote
* end and that no more-preferable methods are available.
*
*/
static int
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
return 0;
}
static LIBSSH2_MAC_METHOD mac_method_none = {
"none",
0,
0,
NULL,
mac_none_MAC,
NULL,
0
};
#endif /* defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE) */
/* mac_method_common_init
* Initialize simple mac methods
*/
static int
mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
*abstract = key;
*free_key = 0;
(void)session;
return 0;
}
/* mac_method_common_dtor
* Cleanup simple mac methods
*/
static int
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
{
if(*abstract) {
LIBSSH2_FREE(session, *abstract);
}
*abstract = NULL;
return 0;
}
#if LIBSSH2_HMAC_SHA512
/* mac_method_hmac_sha512_hash
* Calculate hash using full sha512 value
*/
static int
mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha512_init(&ctx, *abstract, 64) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return !res;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
"hmac-sha2-512",
64,
64,
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512_etm = {
"hmac-sha2-512-etm@openssh.com",
64,
64,
mac_method_common_init,
mac_method_hmac_sha2_512_hash,
mac_method_common_dtor,
1
};
#endif
#if LIBSSH2_HMAC_SHA256
/* mac_method_hmac_sha256_hash
* Calculate hash using full sha256 value
*/
static int
mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha256_init(&ctx, *abstract, 32) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return !res;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = {
"hmac-sha2-256",
32,
32,
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256_etm = {
"hmac-sha2-256-etm@openssh.com",
32,
32,
mac_method_common_init,
mac_method_hmac_sha2_256_hash,
mac_method_common_dtor,
1
};
#endif
/* mac_method_hmac_sha1_hash
* Calculate hash using full sha1 value
*/
static int
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_sha1_init(&ctx, *abstract, 20) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return !res;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
"hmac-sha1",
20,
20,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_etm = {
"hmac-sha1-etm@openssh.com",
20,
20,
mac_method_common_init,
mac_method_hmac_sha1_hash,
mac_method_common_dtor,
1
};
/* mac_method_hmac_sha1_96_hash
* Calculate hash using first 96 bits of sha1 value
*/
static int
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
unsigned char temp[SHA_DIGEST_LENGTH];
if(mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract))
return 1;
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
"hmac-sha1-96",
12,
20,
mac_method_common_init,
mac_method_hmac_sha1_96_hash,
mac_method_common_dtor,
0
};
#if LIBSSH2_MD5
/* mac_method_hmac_md5_hash
* Calculate hash using full md5 value
*/
static int
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_md5_init(&ctx, *abstract, 16) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return !res;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
"hmac-md5",
16,
16,
mac_method_common_init,
mac_method_hmac_md5_hash,
mac_method_common_dtor,
0
};
/* mac_method_hmac_md5_96_hash
* Calculate hash using first 96 bits of md5 value
*/
static int
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
unsigned char temp[MD5_DIGEST_LENGTH];
if(mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
addtl, addtl_len, abstract))
return 1;
memcpy(buf, (char *) temp, 96 / 8);
return 0;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
"hmac-md5-96",
12,
16,
mac_method_common_init,
mac_method_hmac_md5_96_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_MD5 */
#if LIBSSH2_HMAC_RIPEMD
/* mac_method_hmac_ripemd160_hash
* Calculate hash using ripemd160 value
*/
static int
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len,
void **abstract)
{
libssh2_hmac_ctx ctx;
unsigned char seqno_buf[4];
int res;
(void)session;
_libssh2_htonu32(seqno_buf, seqno);
if(!_libssh2_hmac_ctx_init(&ctx))
return 1;
res = _libssh2_hmac_ripemd160_init(&ctx, *abstract, 20) &&
_libssh2_hmac_update(&ctx, seqno_buf, 4) &&
_libssh2_hmac_update(&ctx, packet, packet_len);
if(res && addtl && addtl_len)
res = _libssh2_hmac_update(&ctx, addtl, addtl_len);
if(res)
res = _libssh2_hmac_final(&ctx, buf);
_libssh2_hmac_cleanup(&ctx);
return !res;
}
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
"hmac-ripemd160",
20,
20,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
"hmac-ripemd160@openssh.com",
20,
20,
mac_method_common_init,
mac_method_hmac_ripemd160_hash,
mac_method_common_dtor,
0
};
#endif /* LIBSSH2_HMAC_RIPEMD */
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
#if LIBSSH2_HMAC_SHA256
&mac_method_hmac_sha2_256,
&mac_method_hmac_sha2_256_etm,
#endif
#if LIBSSH2_HMAC_SHA512
&mac_method_hmac_sha2_512,
&mac_method_hmac_sha2_512_etm,
#endif
&mac_method_hmac_sha1,
&mac_method_hmac_sha1_etm,
&mac_method_hmac_sha1_96,
#if LIBSSH2_MD5
&mac_method_hmac_md5,
&mac_method_hmac_md5_96,
#endif
#if LIBSSH2_HMAC_RIPEMD
&mac_method_hmac_ripemd160,
&mac_method_hmac_ripemd160_openssh_com,
#endif /* LIBSSH2_HMAC_RIPEMD */
#if defined(LIBSSH2DEBUG) && defined(LIBSSH2_MAC_NONE_INSECURE)
&mac_method_none,
#endif
NULL
};
const LIBSSH2_MAC_METHOD **
_libssh2_mac_methods(void)
{
return mac_methods;
}
#if LIBSSH2_AES_GCM
static int
mac_method_none_init(LIBSSH2_SESSION * session, unsigned char *key,
int *free_key, void **abstract)
{
(void)session;
(void)key;
(void)free_key;
(void)abstract;
return 0;
}
static int
mac_method_hmac_none_hash(LIBSSH2_SESSION * session,
unsigned char *buf, uint32_t seqno,
const unsigned char *packet,
size_t packet_len,
const unsigned char *addtl,
size_t addtl_len, void **abstract)
{
(void)session;
(void)buf;
(void)seqno;
(void)packet;
(void)packet_len;
(void)addtl;
(void)addtl_len;
(void)abstract;
return 0;
}
static int
mac_method_none_dtor(LIBSSH2_SESSION * session, void **abstract)
{
(void)session;
(void)abstract;
return 0;
}
/* Stub for aes256-gcm@openssh.com crypto type, which has an integrated
HMAC method. This must not be added to mac_methods[] since it cannot be
negotiated separately. */
static const LIBSSH2_MAC_METHOD mac_method_hmac_aesgcm = {
"INTEGRATED-AES-GCM", /* made up name for display only */
16,
16,
mac_method_none_init,
mac_method_hmac_none_hash,
mac_method_none_dtor,
0
};
#endif /* LIBSSH2_AES_GCM */
/* See if the negotiated crypto method has its own authentication scheme that
* obviates the need for a separate negotiated hmac method */
const LIBSSH2_MAC_METHOD *
_libssh2_mac_override(const LIBSSH2_CRYPT_METHOD *crypt)
{
#if LIBSSH2_AES_GCM
if(!strcmp(crypt->name, "aes256-gcm@openssh.com") ||
!strcmp(crypt->name, "aes128-gcm@openssh.com"))
return &mac_method_hmac_aesgcm;
#else
(void) crypt;
#endif /* LIBSSH2_AES_GCM */
return NULL;
}
+72
View File
@@ -0,0 +1,72 @@
#ifndef LIBSSH2_MAC_H
#define LIBSSH2_MAC_H
/* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
struct _LIBSSH2_MAC_METHOD
{
const char *name;
/* The length of a given MAC packet */
int mac_len;
/* integrity key length */
int key_len;
/* Message Authentication Code Hashing algo */
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
void **abstract);
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
uint32_t seqno, const unsigned char *packet,
size_t packet_len, const unsigned char *addtl,
size_t addtl_len, void **abstract);
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
int etm; /* encrypt-then-mac */
};
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
const LIBSSH2_MAC_METHOD *_libssh2_mac_override(
const LIBSSH2_CRYPT_METHOD *crypt);
#endif /* LIBSSH2_MAC_H */
File diff suppressed because it is too large. Load diff
+514
View File
@@ -0,0 +1,514 @@
#ifndef LIBSSH2_MBEDTLS_H
#define LIBSSH2_MBEDTLS_H
/* Copyright (C) Art <https://github.com/wildart>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_mbedtls
#ifdef __GNUC__
#pragma GCC diagnostic push
/* mbedTLS (as of v3.5.1) has a `[-Werror=arith-conversion]`
warning in its public headers. */
#if !defined(__clang__) && __GNUC__ >= 10
#pragma GCC diagnostic ignored "-Warith-conversion"
#endif
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wsign-conversion"
#endif
/* mbedTLS (as of v3.5.1) has a duplicate function declaration
in its public headers. Disable the warning that detects it. */
#pragma GCC diagnostic ignored "-Wredundant-decls"
#endif
#include <mbedtls/version.h>
#include <mbedtls/platform.h>
#include <mbedtls/md.h>
#include <mbedtls/rsa.h>
#include <mbedtls/bignum.h>
#include <mbedtls/cipher.h>
#ifdef MBEDTLS_ECDH_C
# include <mbedtls/ecdh.h>
#endif
#ifdef MBEDTLS_ECDSA_C
# include <mbedtls/ecdsa.h>
#endif
#include <mbedtls/entropy.h>
#include <mbedtls/ctr_drbg.h>
#include <mbedtls/pk.h>
#include <mbedtls/error.h>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
/* Define which features are supported. */
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 1
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
# define LIBSSH2_BLOWFISH 1
#else
# define LIBSSH2_BLOWFISH 0
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
# define LIBSSH2_RC4 1
#else
# define LIBSSH2_RC4 0
#endif
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#ifdef MBEDTLS_ECDSA_C
# define LIBSSH2_ECDSA 1
#else
# define LIBSSH2_ECDSA 0
#endif
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
/*******************************************************************/
/*
* mbedTLS backend: Generic functions
*/
#define libssh2_crypto_init() \
_libssh2_mbedtls_init()
#define libssh2_crypto_exit() \
_libssh2_mbedtls_free()
#define _libssh2_random(buf, len) \
_libssh2_mbedtls_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
/*******************************************************************/
/*
* mbedTLS backend: HMAC functions
*/
#define libssh2_hmac_ctx mbedtls_md_context_t
/*******************************************************************/
/*
* mbedTLS backend: SHA1 functions
*/
#define libssh2_sha1_ctx mbedtls_md_context_t
#define libssh2_sha1_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0)
#define libssh2_sha1_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA256 functions
*/
#define libssh2_sha256_ctx mbedtls_md_context_t
#define libssh2_sha256_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0)
#define libssh2_sha256_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA384 functions
*/
#define libssh2_sha384_ctx mbedtls_md_context_t
#define libssh2_sha384_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
#define libssh2_sha384_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
/*******************************************************************/
/*
* mbedTLS backend: SHA512 functions
*/
#define libssh2_sha512_ctx mbedtls_md_context_t
#define libssh2_sha512_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0)
#define libssh2_sha512_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash)
/*******************************************************************/
/*
* mbedTLS backend: MD5 functions
*/
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx mbedtls_md_context_t
#define libssh2_md5_init(pctx) \
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0)
#define libssh2_md5_update(ctx, data, datalen) \
(mbedtls_md_update(&ctx, (const unsigned char *) data, datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
_libssh2_mbedtls_hash_final(&ctx, hash)
#endif
/*******************************************************************/
/*
* mbedTLS backend: RSA functions
*/
#define libssh2_rsa_ctx mbedtls_rsa_context
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_mbedtls_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_mbedtls_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_mbedtls_rsa_free(rsactx)
/*******************************************************************/
/*
* mbedTLS backend: ECDSA structures
*/
#if LIBSSH2_ECDSA
typedef enum {
#ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_SECP256R1,
#else
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_NONE,
#endif
#ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_SECP384R1,
#else
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_NONE,
#endif
#ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_SECP521R1
#else
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_NONE,
#endif
} libssh2_curve_type;
# define _libssh2_ec_key mbedtls_ecp_keypair
#else
# define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
/*******************************************************************/
/*
* mbedTLS backend: ECDSA functions
*/
#if LIBSSH2_ECDSA
#define libssh2_ecdsa_ctx mbedtls_ecdsa_context
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve) \
_libssh2_mbedtls_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve)
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
_libssh2_mbedtls_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
_libssh2_mbedtls_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
_libssh2_mbedtls_ecdsa_new_private(ctx, session, filename, passphrase)
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase) \
_libssh2_mbedtls_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase)
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
_libssh2_mbedtls_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
#define _libssh2_ecdsa_get_curve_type(ctx) \
_libssh2_mbedtls_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ctx) \
_libssh2_mbedtls_ecdsa_free(ctx)
#endif /* LIBSSH2_ECDSA */
/*******************************************************************/
/*
* mbedTLS backend: Key functions
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_mbedtls_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
/*
* mbedTLS backend: Cipher Context structure
*/
#define _libssh2_cipher_ctx mbedtls_cipher_context_t
#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo
#define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR
#define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR
#define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR
#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC
#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC
#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC
#endif
#ifdef MBEDTLS_CIPHER_ARC4_128
#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128
#endif
#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC
#define _libssh2_cipher_chacha20 MBEDTLS_CIPHER_CHACHA20_POLY1305
/*******************************************************************/
/*
* mbedTLS backend: Cipher functions
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_mbedtls_cipher_dtor(ctx)
/*******************************************************************/
/*
* mbedTLS backend: BigNumber Support
*/
#define _libssh2_bn_ctx int /* not used */
#define _libssh2_bn_ctx_new() 0 /* not used */
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
#define _libssh2_bn mbedtls_mpi
#define _libssh2_bn_init() \
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_mbedtls_bignum_init()
#define _libssh2_bn_set_word(bn, word) \
mbedtls_mpi_lset(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
mbedtls_mpi_read_binary(bn, bin, len)
#define _libssh2_bn_to_bin(bn, bin) \
mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn))
#define _libssh2_bn_bytes(bn) \
mbedtls_mpi_size(bn)
#define _libssh2_bn_bits(bn) \
mbedtls_mpi_bitlen(bn)
#define _libssh2_bn_free(bn) \
_libssh2_mbedtls_bignum_free(bn)
/*******************************************************************/
/*
* mbedTLS backend: Diffie-Hellman support.
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx mbedtls_mpi *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/
/*
* mbedTLS backend: forward declarations
*/
void
_libssh2_mbedtls_init(void);
void
_libssh2_mbedtls_free(void);
int
_libssh2_mbedtls_random(unsigned char *buf, size_t len);
void
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx);
int
_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
mbedtls_md_type_t mdtype,
const unsigned char *key, size_t keylen);
int
_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash);
int
_libssh2_mbedtls_hash(const unsigned char *data, size_t datalen,
mbedtls_md_type_t mdtype, unsigned char *hash);
_libssh2_bn *
_libssh2_mbedtls_bignum_init(void);
void
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn);
void
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa);
#if LIBSSH2_ECDSA
libssh2_curve_type
_libssh2_mbedtls_ecdsa_key_get_curve_type(libssh2_ecdsa_ctx *ctx);
int
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
libssh2_curve_type *type);
void
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx);
#endif /* LIBSSH2_ECDSA */
extern void
_libssh2_init_aes_ctr(void);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
extern int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_MBEDTLS_H */
+989
View File
@@ -0,0 +1,989 @@
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h>
#include <assert.h>
#ifdef _WIN32
/* Force parameter type. */
#define recv(s, b, l, f) recv((s), (b), (int)(l), (f))
#define send(s, b, l, f) send((s), (b), (int)(l), (f))
#endif
/* snprintf not in Visual Studio CRT and _snprintf dangerously incompatible.
We provide a safe wrapper if snprintf not found */
#ifdef LIBSSH2_SNPRINTF
#include <stdarg.h>
/* Want safe, 'n += snprintf(b + n ...)' like function. If cp_max_len is 1
* then assume cp is pointing to a null char and do nothing. Returns number
* number of chars placed in cp excluding the trailing null char. So for
* cp_max_len > 0 the return value is always < cp_max_len; for cp_max_len
* <= 0 the return value is 0 (and no chars are written to cp). */
int _libssh2_snprintf(char *cp, size_t cp_max_len, const char *fmt, ...)
{
va_list args;
int n;
if(cp_max_len < 2)
return 0;
va_start(args, fmt);
n = vsnprintf(cp, cp_max_len, fmt, args);
va_end(args);
return (n < (int)cp_max_len) ? n : (int)(cp_max_len - 1);
}
#endif
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags)
{
if(!session) {
if(errmsg)
fprintf(stderr, "Session is NULL, error: %s\n", errmsg);
return errcode;
}
if(session->err_flags & LIBSSH2_ERR_FLAG_DUP)
LIBSSH2_FREE(session, (char *)session->err_msg);
session->err_code = errcode;
session->err_flags = 0;
if(errmsg && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
size_t len = strlen(errmsg);
char *copy = LIBSSH2_ALLOC(session, len + 1);
if(copy) {
memcpy(copy, errmsg, len + 1);
session->err_flags = LIBSSH2_ERR_FLAG_DUP;
session->err_msg = copy;
}
else
/* Out of memory: this code path is very unlikely */
session->err_msg = "former error forgotten (OOM)";
}
else
session->err_msg = errmsg;
#ifdef LIBSSH2DEBUG
if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode)
/* if this is EAGAIN and we're in non-blocking mode, don't generate
a debug output for this */
return errcode;
_libssh2_debug((session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
session->err_msg));
#endif
return errcode;
}
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
{
return _libssh2_error_flags(session, errcode, errmsg, 0);
}
#ifdef _WIN32
int _libssh2_wsa2errno(void)
{
switch(WSAGetLastError()) {
case WSAEWOULDBLOCK:
return EAGAIN;
case WSAENOTSOCK:
return EBADF;
case WSAEINTR:
return EINTR;
default:
/* It is most important to ensure errno does not stay at EAGAIN
* when a different error occurs so just set errno to a generic
* error */
return EIO;
}
}
#endif
/* _libssh2_recv
*
* Replacement for the standard recv, return -errno on failure.
*/
ssize_t
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc;
(void)abstract;
rc = recv(sock, buffer, length, flags);
if(rc < 0) {
int err;
#ifdef _WIN32
err = _libssh2_wsa2errno();
#else
err = errno;
#endif
/* Profiling tools that use SIGPROF can cause EINTR responses.
recv() does not modify its arguments when it returns EINTR,
but there may be data waiting, so the caller should try again */
if(err == EINTR)
return -EAGAIN;
/* Sometimes the first recv() function call sets errno to ENOENT on
Solaris and HP-UX */
if(err == ENOENT)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
else if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
else
return -err;
}
return rc;
}
/* _libssh2_send
*
* Replacement for the standard send, return -errno on failure.
*/
ssize_t
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
int flags, void **abstract)
{
ssize_t rc;
(void)abstract;
rc = send(sock, buffer, length, flags);
if(rc < 0) {
int err;
#ifdef _WIN32
err = _libssh2_wsa2errno();
#else
err = errno;
#endif
/* Profiling tools that use SIGPROF can cause EINTR responses.
send() is defined as not yet sending any data when it returns EINTR,
so the caller should try again */
if(err == EINTR)
return -EAGAIN;
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
if(err == EWOULDBLOCK)
return -EAGAIN;
#endif
return -err;
}
return rc;
}
/* libssh2_ntohu32
*/
uint32_t
_libssh2_ntohu32(const unsigned char *buf)
{
return ((uint32_t)buf[0] << 24)
| ((uint32_t)buf[1] << 16)
| ((uint32_t)buf[2] << 8)
| ((uint32_t)buf[3]);
}
/* _libssh2_ntohu64
*/
libssh2_uint64_t
_libssh2_ntohu64(const unsigned char *buf)
{
return ((libssh2_uint64_t)buf[0] << 56)
| ((libssh2_uint64_t)buf[1] << 48)
| ((libssh2_uint64_t)buf[2] << 40)
| ((libssh2_uint64_t)buf[3] << 32)
| ((libssh2_uint64_t)buf[4] << 24)
| ((libssh2_uint64_t)buf[5] << 16)
| ((libssh2_uint64_t)buf[6] << 8)
| ((libssh2_uint64_t)buf[7]);
}
/* _libssh2_htonu32
*/
void
_libssh2_htonu32(unsigned char *buf, uint32_t value)
{
buf[0] = (unsigned char)((value >> 24) & 0xFF);
buf[1] = (value >> 16) & 0xFF;
buf[2] = (value >> 8) & 0xFF;
buf[3] = value & 0xFF;
}
/* _libssh2_store_u32
*/
void _libssh2_store_u32(unsigned char **buf, uint32_t value)
{
_libssh2_htonu32(*buf, value);
*buf += sizeof(uint32_t);
}
/* _libssh2_store_u64
*/
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value)
{
unsigned char *ptr = *buf;
ptr[0] = (unsigned char)((value >> 56) & 0xFF);
ptr[1] = (unsigned char)((value >> 48) & 0xFF);
ptr[2] = (unsigned char)((value >> 40) & 0xFF);
ptr[3] = (unsigned char)((value >> 32) & 0xFF);
ptr[4] = (unsigned char)((value >> 24) & 0xFF);
ptr[5] = (unsigned char)((value >> 16) & 0xFF);
ptr[6] = (unsigned char)((value >> 8) & 0xFF);
ptr[7] = (unsigned char)(value & 0xFF);
*buf += sizeof(libssh2_uint64_t);
}
/* _libssh2_store_str
*/
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
{
uint32_t len_stored = (uint32_t)len;
_libssh2_store_u32(buf, len_stored);
if(len_stored) {
memcpy(*buf, str, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* _libssh2_store_bignum2_bytes
*/
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len)
{
uint32_t len_stored;
uint32_t extraByte;
const unsigned char *p;
for(p = bytes; len > 0 && *p == 0; --len, ++p) {}
extraByte = (len > 0 && (p[0] & 0x80) != 0);
len_stored = (uint32_t)len;
if(extraByte && len_stored == UINT32_MAX)
len_stored--;
_libssh2_store_u32(buf, len_stored + extraByte);
if(extraByte) {
*buf[0] = 0;
*buf += 1;
}
if(len_stored) {
memcpy(*buf, p, len_stored);
*buf += len_stored;
}
assert(len_stored == len);
return len_stored == len;
}
/* Base64 Conversion */
static const short base64_reverse_table[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
/* libssh2_base64_decode
*
* Legacy public function. DEPRECATED.
*/
LIBSSH2_API int
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
unsigned int *datalen, const char *src,
unsigned int src_len)
{
int rc;
size_t dlen;
rc = _libssh2_base64_decode(session, data, &dlen, src, src_len);
if(datalen)
*datalen = (unsigned int)dlen;
return rc;
}
/* _libssh2_base64_decode
*
* Decode a base64 chunk and store it into a newly alloc'd buffer
*/
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len)
{
unsigned char *d;
const char *s;
short v;
ssize_t i = 0, len = 0;
*data = LIBSSH2_ALLOC(session, ((src_len / 4) * 3) + 1);
d = (unsigned char *) *data;
if(!d) {
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for base64 decoding");
}
for(s = src; s < (src + src_len); s++) {
v = base64_reverse_table[(unsigned char)*s];
if(v < 0)
continue;
switch(i % 4) {
case 0:
d[len] = (unsigned char)(v << 2);
break;
case 1:
d[len++] |= (unsigned char)(v >> 4);
d[len] = (unsigned char)(v << 4);
break;
case 2:
d[len++] |= (unsigned char)(v >> 2);
d[len] = (unsigned char)(v << 6);
break;
case 3:
d[len++] |= (unsigned char)v;
break;
}
i++;
}
if((i % 4) == 1) {
/* Invalid -- We have a byte which belongs exclusively to a partial
octet */
LIBSSH2_FREE(session, *data);
*data = NULL;
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64");
}
*datalen = len;
return 0;
}
/* ---- Base64 Encoding/Decoding Table --- */
static const char table64[]=
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* _libssh2_base64_encode
*
* Returns the length of the newly created base64 string. The third argument
* is a pointer to an allocated area holding the base64 data. If something
* went wrong, 0 is returned.
*
*/
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr)
{
unsigned char ibuf[3];
unsigned char obuf[4];
int i;
int inputparts;
char *output;
char *base64data;
const char *indata = inp;
*outptr = NULL; /* set to NULL in case of failure before we reach the
end */
if(insize == 0)
insize = strlen(indata);
base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4);
if(!output)
return 0;
while(insize > 0) {
for(i = inputparts = 0; i < 3; i++) {
if(insize > 0) {
inputparts++;
ibuf[i] = *indata;
indata++;
insize--;
}
else
ibuf[i] = 0;
}
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
((ibuf[1] & 0xF0) >> 4));
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
((ibuf[2] & 0xC0) >> 6));
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
switch(inputparts) {
case 1: /* only one byte read */
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = '=';
output[3] = '=';
break;
case 2: /* two bytes read */
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = '=';
break;
default:
output[0] = table64[obuf[0]];
output[1] = table64[obuf[1]];
output[2] = table64[obuf[2]];
output[3] = table64[obuf[3]];
break;
}
output += 4;
}
*output = 0;
*outptr = base64data; /* make it return the actual data memory */
return strlen(base64data); /* return the length of the new data */
}
/* ---- End of Base64 Encoding ---- */
LIBSSH2_API void
libssh2_free(LIBSSH2_SESSION *session, void *ptr)
{
LIBSSH2_FREE(session, ptr);
}
#ifdef LIBSSH2DEBUG
#include <stdarg.h>
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
session->showmask = bitmask;
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback)
{
session->tracehandler = callback;
session->tracehandler_context = handler_context;
return 0;
}
void
_libssh2_debug_low(LIBSSH2_SESSION * session, int context, const char *format,
...)
{
char buffer[1536];
int len, msglen, buflen = sizeof(buffer);
va_list vargs;
struct timeval now;
static long firstsec;
static const char *const contexts[] = {
"Unknown",
"Transport",
"Key Ex",
"Userauth",
"Conn",
"SCP",
"SFTP",
"Failure Event",
"Publickey",
"Socket",
};
const char *contexttext = contexts[0];
unsigned int contextindex;
if(!(session->showmask & context)) {
/* no such output asked for */
return;
}
/* Find the first matching context string for this message */
for(contextindex = 0; contextindex < ARRAY_SIZE(contexts);
contextindex++) {
if((context & (1 << contextindex)) != 0) {
contexttext = contexts[contextindex];
break;
}
}
gettimeofday(&now, NULL);
if(!firstsec) {
firstsec = now.tv_sec;
}
now.tv_sec -= firstsec;
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
(int)now.tv_sec, (int)now.tv_usec, contexttext);
if(len >= buflen)
msglen = buflen - 1;
else {
buflen -= len;
msglen = len;
va_start(vargs, format);
len = vsnprintf(buffer + msglen, buflen, format, vargs);
va_end(vargs);
msglen += len < buflen ? len : buflen - 1;
}
if(session->tracehandler)
(session->tracehandler)(session, session->tracehandler_context, buffer,
msglen);
else
fprintf(stderr, "%s\n", buffer);
}
#else
LIBSSH2_API int
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
{
(void)session;
(void)bitmask;
return 0;
}
LIBSSH2_API int
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
libssh2_trace_handler_func callback)
{
(void)session;
(void)handler_context;
(void)callback;
return 0;
}
#endif
/* init the list head */
void _libssh2_list_init(struct list_head *head)
{
head->first = head->last = NULL;
}
/* add a node to the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry)
{
/* store a pointer to the head */
entry->head = head;
/* we add this entry at the "top" so it has no next */
entry->next = NULL;
/* make our prev point to what the head thinks is last */
entry->prev = head->last;
/* and make head's last be us now */
head->last = entry;
/* make sure our 'prev' node points to us next */
if(entry->prev)
entry->prev->next = entry;
else
head->first = entry;
}
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head)
{
return head->first;
}
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node)
{
return node->next;
}
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node)
{
return node->prev;
}
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry)
{
if(entry->prev)
entry->prev->next = entry->next;
else
entry->head->first = entry->next;
if(entry->next)
entry->next->prev = entry->prev;
else
entry->head->last = entry->prev;
}
#if 0
/* insert a node before the given 'after' entry */
void _libssh2_list_insert(struct list_node *after, /* insert before this */
struct list_node *entry)
{
/* 'after' is next to 'entry' */
bentry->next = after;
/* entry's prev is then made to be the prev after current has */
entry->prev = after->prev;
/* the node that is now before 'entry' was previously before 'after'
and must be made to point to 'entry' correctly */
if(entry->prev)
entry->prev->next = entry;
else
/* there was no node before this, so we make sure we point the head
pointer to this node */
after->head->first = entry;
/* after's prev entry points back to entry */
after->prev = entry;
/* after's next entry is still the same as before */
/* entry's head is the same as after's */
entry->head = after->head;
}
#endif
/* Defined in libssh2_priv.h for the correct platforms */
#ifdef LIBSSH2_GETTIMEOFDAY
/*
* _libssh2_gettimeofday
* Implementation according to:
* The Open Group Base Specifications Issue 6
* IEEE Std 1003.1, 2004 Edition
*/
/*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* Contributed by:
* Danny Smith <dannysmith@users.sourceforge.net>
*/
int _libssh2_gettimeofday(struct timeval *tp, void *tzp)
{
(void)tzp;
if(tp) {
#ifdef _WIN32
/* Offset between 1601-01-01 and 1970-01-01 in 100 nanosec units */
#define _WIN32_FT_OFFSET (116444736000000000)
union {
libssh2_uint64_t ns100; /* time since 1 Jan 1601 in 100ns units */
FILETIME ft;
} _now;
GetSystemTimeAsFileTime(&_now.ft);
tp->tv_usec = (long)((_now.ns100 / 10) % 1000000);
tp->tv_sec = (long)((_now.ns100 - _WIN32_FT_OFFSET) / 10000000);
#else
/* Platforms without a native implementation or local replacement */
tp->tv_usec = 0;
tp->tv_sec = 0;
#endif
}
/* Always return 0 as per Open Group Base Specifications Issue 6.
Do not set errno on error. */
return 0;
}
#endif
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
{
void *p = LIBSSH2_ALLOC(session, size);
if(p) {
memset(p, 0, size);
}
return p;
}
/* XOR operation on buffers input1 and input2, result in output.
It is safe to use an input buffer as the output buffer. */
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length)
{
size_t i;
for(i = 0; i < length; i++)
*output++ = *input1++ ^ *input2++;
}
/* Increments an AES CTR buffer to prepare it for use with the
next AES block. */
void _libssh2_aes_ctr_increment(unsigned char *ctr,
size_t length)
{
unsigned char *pc;
unsigned int val, carry;
pc = ctr + length - 1;
carry = 1;
while(pc >= ctr) {
val = (unsigned int)*pc + carry;
*pc-- = val & 0xFF;
carry = val >> 8;
}
}
#ifdef LIBSSH2_MEMZERO
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
void _libssh2_memzero(void *buf, size_t size)
{
memset_libssh(buf, 0, size);
}
#endif
/* String buffer */
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session)
{
struct string_buf *ret;
ret = _libssh2_calloc(session, sizeof(*ret));
if(!ret)
return NULL;
return ret;
}
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf)
{
if(!buf)
return;
if(buf->data)
LIBSSH2_FREE(session, buf->data);
LIBSSH2_FREE(session, buf);
buf = NULL;
}
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0];
buf->dataptr += 1;
return 0;
}
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out)
{
if(!_libssh2_check_length(buf, 1)) {
return -1;
}
*out = buf->dataptr[0] == 0 ? 0 : 1;
buf->dataptr += 1;
return 0;
}
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out)
{
if(!_libssh2_check_length(buf, 4)) {
return -1;
}
*out = _libssh2_ntohu32(buf->dataptr);
buf->dataptr += 4;
return 0;
}
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out)
{
if(!_libssh2_check_length(buf, 8)) {
return -1;
}
*out = _libssh2_ntohu64(buf->dataptr);
buf->dataptr += 8;
return 0;
}
int _libssh2_match_string(struct string_buf *buf, const char *match)
{
unsigned char *out;
size_t len = 0;
if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) ||
strncmp((char *)out, match, strlen(match)) != 0) {
return -1;
}
return 0;
}
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
if(!buf || _libssh2_get_u32(buf, &data_len) != 0) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
*outbuf = buf->dataptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)data_len;
return 0;
}
int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen)
{
size_t str_len;
unsigned char *str;
if(_libssh2_get_string(buf, &str, &str_len)) {
return -1;
}
if(str_len) {
*outbuf = LIBSSH2_ALLOC(session, str_len);
if(*outbuf) {
memcpy(*outbuf, str, str_len);
}
else {
return -1;
}
}
else {
*outbuf = NULL;
}
if(outlen)
*outlen = str_len;
return 0;
}
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen)
{
uint32_t data_len;
uint32_t bn_len;
unsigned char *bnptr;
if(_libssh2_get_u32(buf, &data_len)) {
return -1;
}
if(!_libssh2_check_length(buf, data_len)) {
return -1;
}
bn_len = data_len;
bnptr = buf->dataptr;
/* trim leading zeros */
while(bn_len > 0 && *bnptr == 0x00) {
bn_len--;
bnptr++;
}
*outbuf = bnptr;
buf->dataptr += data_len;
if(outlen)
*outlen = (size_t)bn_len;
return 0;
}
/* Given the current location in buf, _libssh2_check_length ensures
callers can read the next len number of bytes out of the buffer
before reading the buffer content */
int _libssh2_check_length(struct string_buf *buf, size_t len)
{
unsigned char *endp = &buf->data[buf->len];
size_t left = endp - buf->dataptr;
return (len <= left) && (left <= buf->len);
}
int _libssh2_eob(struct string_buf *buf)
{
unsigned char *endp = &buf->data[buf->len];
return buf->dataptr >= endp;
}
+146
View File
@@ -0,0 +1,146 @@
#ifndef LIBSSH2_MISC_H
#define LIBSSH2_MISC_H
/* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifdef LIBSSH2_NO_CLEAR_MEMORY
#define _libssh2_explicit_zero(buf, size) do { \
(void)(buf); \
(void)(size); \
} while(0)
#elif defined(_WIN32)
#define _libssh2_explicit_zero(buf, size) SecureZeroMemory(buf, size)
#elif defined(HAVE_EXPLICIT_BZERO)
#define _libssh2_explicit_zero(buf, size) explicit_bzero(buf, size)
#elif defined(HAVE_EXPLICIT_MEMSET)
#define _libssh2_explicit_zero(buf, size) (void)explicit_memset(buf, 0, size)
#elif defined(HAVE_MEMSET_S)
#define _libssh2_explicit_zero(buf, size) (void)memset_s(buf, size, 0, size)
#else
#define LIBSSH2_MEMZERO
void _libssh2_memzero(void *buf, size_t size);
#define _libssh2_explicit_zero(buf, size) _libssh2_memzero(buf, size)
#endif
struct list_head {
struct list_node *last;
struct list_node *first;
};
struct list_node {
struct list_node *next;
struct list_node *prev;
struct list_head *head;
};
struct string_buf {
unsigned char *data;
unsigned char *dataptr;
size_t len;
};
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
const char *errmsg, int errflags);
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg);
#ifdef _WIN32
/* Convert Win32 WSAGetLastError to errno equivalent */
int _libssh2_wsa2errno(void);
#endif
void _libssh2_list_init(struct list_head *head);
/* add a node last in the list */
void _libssh2_list_add(struct list_head *head,
struct list_node *entry);
/* return the "first" node in the list this head points to */
void *_libssh2_list_first(struct list_head *head);
/* return the next node in the list */
void *_libssh2_list_next(struct list_node *node);
/* return the prev node in the list */
void *_libssh2_list_prev(struct list_node *node);
/* remove this node from the list */
void _libssh2_list_remove(struct list_node *entry);
int _libssh2_base64_decode(LIBSSH2_SESSION *session,
char **data, size_t *datalen,
const char *src, size_t src_len);
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
const char *inp, size_t insize, char **outptr);
uint32_t _libssh2_ntohu32(const unsigned char *buf);
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
void _libssh2_store_u64(unsigned char **buf, libssh2_uint64_t value);
int _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
int _libssh2_store_bignum2_bytes(unsigned char **buf,
const unsigned char *bytes,
size_t len);
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
struct string_buf *_libssh2_string_buf_new(LIBSSH2_SESSION *session);
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
struct string_buf *buf);
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out);
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out);
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
int _libssh2_match_string(struct string_buf *buf, const char *match);
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf,
unsigned char **outbuf, size_t *outlen);
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
size_t *outlen);
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
int _libssh2_eob(struct string_buf *buf);
void _libssh2_xor_data(unsigned char *output,
const unsigned char *input1,
const unsigned char *input2,
size_t length);
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
#endif /* LIBSSH2_MISC_H */
File diff suppressed because it is too large. Load diff
+463
View File
@@ -0,0 +1,463 @@
#ifndef LIBSSH2_OPENSSL_H
#define LIBSSH2_OPENSSL_H
/* Copyright (C) Simon Josefsson
* Copyright (C) The Written Word, Inc.
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_openssl
/* disable deprecated warnings in OpenSSL 3 */
#define OPENSSL_SUPPRESS_DEPRECATED
#ifdef LIBSSH2_WOLFSSL
#include <wolfssl/options.h>
#include <wolfssl/openssl/ecdh.h>
#if defined(NO_DSA) || defined(HAVE_FIPS)
#define OPENSSL_NO_DSA
#endif
#if defined(NO_MD5) || defined(HAVE_FIPS)
#define OPENSSL_NO_MD5
#endif
#if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS)
#define OPENSSL_NO_RIPEMD
#endif
#if defined(NO_RC4) || defined(HAVE_FIPS)
#define OPENSSL_NO_RC4
#endif
#ifdef NO_DES3
#define OPENSSL_NO_DES
#endif
/* wolfSSL doesn't support Blowfish or CAST. */
#define OPENSSL_NO_BF
#define OPENSSL_NO_CAST
/* wolfSSL has no engine framework. */
#define OPENSSL_NO_ENGINE
#include <wolfssl/openssl/opensslconf.h>
#include <wolfssl/openssl/sha.h>
#include <wolfssl/openssl/rsa.h>
#ifndef OPENSSL_NO_DSA
#include <wolfssl/openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <wolfssl/openssl/md5.h>
#endif
#include <wolfssl/openssl/err.h>
#include <wolfssl/openssl/evp.h>
#include <wolfssl/openssl/hmac.h>
#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/pem.h>
#include <wolfssl/openssl/rand.h>
#else /* !LIBSSH2_WOLFSSL */
#include <openssl/opensslconf.h>
#include <openssl/sha.h>
#include <openssl/rsa.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_MD5
#include <openssl/md5.h>
#endif
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/bn.h>
#include <openssl/pem.h>
#include <openssl/rand.h>
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
#define USE_OPENSSL_3 1
#include <openssl/core_names.h>
#endif
#endif /* LIBSSH2_WOLFSSL */
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3050000fL)
/* For wolfSSL, whether the structs are truly opaque or not, it's best to not
* rely on their internal data members being exposed publicly. */
# define HAVE_OPAQUE_STRUCTS 1
#endif
#ifdef OPENSSL_NO_RSA
# define LIBSSH2_RSA 0
# define LIBSSH2_RSA_SHA1 0
# define LIBSSH2_RSA_SHA2 0
#else
# define LIBSSH2_RSA 1
# define LIBSSH2_RSA_SHA1 1
# define LIBSSH2_RSA_SHA2 1
#endif
#ifdef OPENSSL_NO_DSA
# define LIBSSH2_DSA 0
#else
# define LIBSSH2_DSA 1
#endif
#if defined(OPENSSL_NO_ECDSA) || defined(OPENSSL_NO_EC)
# define LIBSSH2_ECDSA 0
#else
# define LIBSSH2_ECDSA 1
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
!defined(LIBRESSL_VERSION_NUMBER)) || \
(defined(LIBRESSL_VERSION_NUMBER) && \
LIBRESSL_VERSION_NUMBER >= 0x3070000fL)
# define LIBSSH2_ED25519 1
#else
# define LIBSSH2_ED25519 0
#endif
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160)
# define LIBSSH2_HMAC_RIPEMD 0
#else
# define LIBSSH2_HMAC_RIPEMD 1
#endif
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER))
# define LIBSSH2_AES_CTR 1
# define LIBSSH2_AES_CBC 1
#else
# define LIBSSH2_AES_CTR 0
# define LIBSSH2_AES_CBC 0
#endif
/* wolfSSL v5.4.0 is required due to possibly this bug:
https://github.com/wolfSSL/wolfssl/pull/5205
Before this release, all libssh2 tests crash with AES-GCM enabled */
#if (OPENSSL_VERSION_NUMBER >= 0x01010100fL && !defined(OPENSSL_NO_AES)) || \
(defined(LIBSSH2_WOLFSSL) && LIBWOLFSSL_VERSION_HEX >= 0x05004000 && \
defined(HAVE_AESGCM) && defined(WOLFSSL_AESGCM_STREAM))
# define LIBSSH2_AES_GCM 1
#else
# define LIBSSH2_AES_GCM 0
#endif
#ifdef OPENSSL_NO_BF
# define LIBSSH2_BLOWFISH 0
#else
# define LIBSSH2_BLOWFISH 1
#endif
#ifdef OPENSSL_NO_RC4
# define LIBSSH2_RC4 0
#else
# define LIBSSH2_RC4 1
#endif
#ifdef OPENSSL_NO_CAST
# define LIBSSH2_CAST 0
#else
# define LIBSSH2_CAST 1
#endif
#ifdef OPENSSL_NO_DES
# define LIBSSH2_3DES 0
#else
# define LIBSSH2_3DES 1
#endif
#include "crypto_config.h"
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#define _libssh2_random(buf, len) \
_libssh2_openssl_random((buf), (len))
#define libssh2_prepare_iovec(vec, len) /* Empty. */
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha1_ctx EVP_MD_CTX *
#else
#define libssh2_sha1_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha1_init(libssh2_sha1_ctx *ctx);
int _libssh2_sha1_update(libssh2_sha1_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha1_final(libssh2_sha1_ctx *ctx, unsigned char *out);
int _libssh2_sha1(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
#define libssh2_sha1_update(ctx, data, len) \
_libssh2_sha1_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) _libssh2_sha1_final(&(ctx), out)
#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha256_ctx EVP_MD_CTX *
#else
#define libssh2_sha256_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
int _libssh2_sha256_update(libssh2_sha256_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha256_final(libssh2_sha256_ctx *ctx, unsigned char *out);
int _libssh2_sha256(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha256_init(x) _libssh2_sha256_init(x)
#define libssh2_sha256_update(ctx, data, len) \
_libssh2_sha256_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) _libssh2_sha256_final(&(ctx), out)
#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha384_ctx EVP_MD_CTX *
#else
#define libssh2_sha384_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
int _libssh2_sha384_update(libssh2_sha384_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha384_final(libssh2_sha384_ctx *ctx, unsigned char *out);
int _libssh2_sha384(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
#define libssh2_sha384_update(ctx, data, len) \
_libssh2_sha384_update(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) _libssh2_sha384_final(&(ctx), out)
#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z)
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_sha512_ctx EVP_MD_CTX *
#else
#define libssh2_sha512_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
int _libssh2_sha512_update(libssh2_sha512_ctx *ctx,
const void *data, size_t len);
int _libssh2_sha512_final(libssh2_sha512_ctx *ctx, unsigned char *out);
int _libssh2_sha512(const unsigned char *message, size_t len,
unsigned char *out);
#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
#define libssh2_sha512_update(ctx, data, len) \
_libssh2_sha512_update(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) _libssh2_sha512_final(&(ctx), out)
#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#ifdef HAVE_OPAQUE_STRUCTS
#define libssh2_md5_ctx EVP_MD_CTX *
#else
#define libssh2_md5_ctx EVP_MD_CTX
#endif
/* returns 0 in case of failure */
int _libssh2_md5_init(libssh2_md5_ctx *ctx);
int _libssh2_md5_update(libssh2_md5_ctx *ctx,
const void *data, size_t len);
int _libssh2_md5_final(libssh2_md5_ctx *ctx, unsigned char *out);
#define libssh2_md5_init(x) _libssh2_md5_init(x)
#define libssh2_md5_update(ctx, data, len) \
_libssh2_md5_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) _libssh2_md5_final(&(ctx), out)
#endif /* LIBSSH2_MD5 || LIBSSH2_MD5_PEM */
#ifdef USE_OPENSSL_3
#define libssh2_hmac_ctx EVP_MAC_CTX *
#elif defined(HAVE_OPAQUE_STRUCTS)
#define libssh2_hmac_ctx HMAC_CTX *
#else /* !HAVE_OPAQUE_STRUCTS */
#define libssh2_hmac_ctx HMAC_CTX
#endif /* USE_OPENSSL_3 */
extern void _libssh2_openssl_crypto_init(void);
extern void _libssh2_openssl_crypto_exit(void);
#define libssh2_crypto_init() _libssh2_openssl_crypto_init()
#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
#if LIBSSH2_RSA
#ifdef USE_OPENSSL_3
#define libssh2_rsa_ctx EVP_PKEY
#define _libssh2_rsa_free(rsactx) EVP_PKEY_free(rsactx)
#else
#define libssh2_rsa_ctx RSA
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
#endif
#endif /* LIBSSH2_RSA */
#if LIBSSH2_DSA
#ifdef USE_OPENSSL_3
#define libssh2_dsa_ctx EVP_PKEY
#define _libssh2_dsa_free(rsactx) EVP_PKEY_free(rsactx)
#else
#define libssh2_dsa_ctx DSA
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
#endif
#endif /* LIBSSH2_DSA */
#if LIBSSH2_ECDSA
#ifdef USE_OPENSSL_3
#define libssh2_ecdsa_ctx EVP_PKEY
#define _libssh2_ecdsa_free(ecdsactx) EVP_PKEY_free(ecdsactx)
#define _libssh2_ec_key EVP_PKEY
#else
#define libssh2_ecdsa_ctx EC_KEY
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
#define _libssh2_ec_key EC_KEY
#endif
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1,
LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1,
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
}
libssh2_curve_type;
#else /* !LIBSSH2_ECDSA */
#define _libssh2_ec_key void
#endif /* LIBSSH2_ECDSA */
#if LIBSSH2_ED25519
#define libssh2_ed25519_ctx EVP_PKEY
#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx)
#endif /* LIBSSH2_ED25519 */
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
#ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_ctx EVP_CIPHER_CTX *
#else
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
#endif
#define _libssh2_cipher_aes256gcm EVP_aes_256_gcm
#define _libssh2_cipher_aes128gcm EVP_aes_128_gcm
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
#define _libssh2_cipher_blowfish EVP_bf_cbc
#define _libssh2_cipher_arcfour EVP_rc4
#define _libssh2_cipher_cast5 EVP_cast5_cbc
#define _libssh2_cipher_3des EVP_des_ede3_cbc
#define _libssh2_cipher_chacha20 NULL
#ifdef HAVE_OPAQUE_STRUCTS
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx))
#else
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
#endif
#define _libssh2_bn BIGNUM
#define _libssh2_bn_ctx BN_CTX
#define _libssh2_bn_ctx_new() BN_CTX_new()
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
#define _libssh2_bn_init() BN_new()
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_set_word(bn, val) !BN_set_word(bn, val)
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
#define _libssh2_bn_to_bin(bn, val) (BN_bn2bin(bn, val) <= 0)
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
#define _libssh2_bn_free(bn) BN_clear_free(bn)
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 8192
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
#define _libssh2_dh_ctx BIGNUM *
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p,
int group_order,
_libssh2_bn_ctx *bnctx);
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p,
_libssh2_bn_ctx *bnctx);
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
extern int _libssh2_openssl_random(void *buf, size_t len);
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
#endif /* LIBSSH2_OPENSSL_H */
File diff suppressed because it is too large. Load diff
+397
View File
@@ -0,0 +1,397 @@
#ifndef LIBSSH2_OS400QC3_H
#define LIBSSH2_OS400QC3_H
/*
* Copyright (C) Patrick Monnerat <patrick@monnerat.net>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_os400qc3
#include <stdlib.h>
#include <string.h>
#include <qc3cci.h>
/* Redefine character/string literals as always EBCDIC. */
#undef Qc3_Alg_Token
#define Qc3_Alg_Token "\xC1\xD3\xC7\xC4\xF0\xF1\xF0\xF0" /* ALGD0100 */
#undef Qc3_Alg_Block_Cipher
#define Qc3_Alg_Block_Cipher "\xC1\xD3\xC7\xC4\xF0\xF2\xF0\xF0" /* ALGD0200 */
#undef Qc3_Alg_Block_CipherAuth
#define Qc3_Alg_Block_CipherAuth \
"\xC1\xD3\xC7\xC4\xF0\xF2\xF1\xF0" /* ALGD0210 */
#undef Qc3_Alg_Stream_Cipher
#define Qc3_Alg_Stream_Cipher \
"\xC1\xD3\xC7\xC4\xF0\xF3\xF0\xF0" /* ALGD0300 */
#undef Qc3_Alg_Public_Key
#define Qc3_Alg_Public_Key "\xC1\xD3\xC7\xC4\xF0\xF4\xF0\xF0" /* ALGD0400 */
#undef Qc3_Alg_Hash
#define Qc3_Alg_Hash "\xC1\xD3\xC7\xC4\xF0\xF5\xF0\xF0" /* ALGD0500 */
#undef Qc3_Data
#define Qc3_Data "\xC4\xC1\xE3\xC1\xF0\xF1\xF0\xF0" /* DATA0100 */
#undef Qc3_Array
#define Qc3_Array "\xC4\xC1\xE3\xC1\xF0\xF2\xF0\xF0" /* DATA0200 */
#undef Qc3_Key_Token
#define Qc3_Key_Token "\xD2\xC5\xE8\xC4\xF0\xF1\xF0\xF0" /* KEYD0100 */
#undef Qc3_Key_Parms
#define Qc3_Key_Parms "\xD2\xC5\xE8\xC4\xF0\xF2\xF0\xF0" /* KEYD0200 */
#undef Qc3_Key_KSLabel
#define Qc3_Key_KSLabel "\xD2\xC5\xE8\xC4\xF0\xF4\xF0\xF0" /* KEYD0400 */
#undef Qc3_Key_PKCS5
#define Qc3_Key_PKCS5 "\xD2\xC5\xE8\xC4\xF0\xF5\xF0\xF0" /* KEYD0500 */
#undef Qc3_Key_PEMCert
#define Qc3_Key_PEMCert "\xD2\xC5\xE8\xC4\xF0\xF6\xF0\xF0" /* KEYD0600 */
#undef Qc3_Key_CSLabel
#define Qc3_Key_CSLabel "\xD2\xC5\xE8\xC4\xF0\xF7\xF0\xF0" /* KEYD0700 */
#undef Qc3_Key_CSDN
#define Qc3_Key_CSDN "\xD2\xC5\xE8\xC4\xF0\xF8\xF0\xF0" /* KEYD0800 */
#undef Qc3_Key_AppID
#define Qc3_Key_AppID "\xD2\xC5\xE8\xC4\xF0\xF9\xF0\xF0" /* KEYD0900 */
#undef Qc3_ECB
#define Qc3_ECB '\xF0' /* '0' */
#undef Qc3_CBC
#define Qc3_CBC '\xF1' /* '1' */
#undef Qc3_OFB
#define Qc3_OFB '\xF2' /* '2' */
#undef Qc3_CFB1Bit
#define Qc3_CFB1Bit '\xF3' /* '3' */
#undef Qc3_CFB8Bit
#define Qc3_CFB8Bit '\xF4' /* '4' */
#undef Qc3_CFB64Bit
#define Qc3_CFB64Bit '\xF5' /* '5' */
#undef Qc3_CUSP
#define Qc3_CUSP '\xF6' /* '6' */
#undef Qc3_CTR
#define Qc3_CTR '\xF7' /* '7' */
#undef Qc3_CCM
#define Qc3_CCM '\xF8' /* '8' */
#undef Qc3_No_Pad
#define Qc3_No_Pad '\xF0' /* '0' */
#undef Qc3_Pad_Char
#define Qc3_Pad_Char '\xF1' /* '1' */
#undef Qc3_Pad_Counter
#define Qc3_Pad_Counter '\xF2' /* '2' */
#undef Qc3_PKCS1_00
#define Qc3_PKCS1_00 '\xF0' /* '0' */
#undef Qc3_PKCS1_01
#define Qc3_PKCS1_01 '\xF1' /* '1' */
#undef Qc3_PKCS1_02
#define Qc3_PKCS1_02 '\xF2' /* '2' */
#undef Qc3_ISO9796
#define Qc3_ISO9796 '\xF3' /* '3' */
#undef Qc3_Zero_Pad
#define Qc3_Zero_Pad '\xF4' /* '4' */
#undef Qc3_ANSI_X931
#define Qc3_ANSI_X931 '\xF5' /* '5' */
#undef Qc3_OAEP
#define Qc3_OAEP '\xF6' /* '6' */
#undef Qc3_Bin_String
#define Qc3_Bin_String '\xF0' /* '0' */
#undef Qc3_BER_String
#define Qc3_BER_String '\xF1' /* '1' */
#undef Qc3_MK_Struct
#define Qc3_MK_Struct '\xF3' /* '3' */
#undef Qc3_KSLabel_Struct
#define Qc3_KSLabel_Struct '\xF4' /* '4' */
#undef Qc3_PKCS5_Struct
#define Qc3_PKCS5_Struct '\xF5' /* '5' */
#undef Qc3_PEMCert_String
#define Qc3_PEMCert_String '\xF6' /* '6' */
#undef Qc3_CSLabel_String
#define Qc3_CSLabel_String '\xF7' /* '7' */
#undef Qc3_CSDN_String
#define Qc3_CSDN_String '\xF8' /* '8' */
#undef Qc3_Clear
#define Qc3_Clear '\xF0' /* '0' */
#undef Qc3_Encrypted
#define Qc3_Encrypted '\xF1' /* '1' */
#undef Qc3_MK_Encrypted
#define Qc3_MK_Encrypted '\xF2' /* '2' */
#undef Qc3_Any_CSP
#define Qc3_Any_CSP '\xF0' /* '0' */
#undef Qc3_Sfw_CSP
#define Qc3_Sfw_CSP '\xF1' /* '1' */
#undef Qc3_Hdw_CSP
#define Qc3_Hdw_CSP '\xF2' /* '2' */
#undef Qc3_Continue
#define Qc3_Continue '\xF0' /* '0' */
#undef Qc3_Final
#define Qc3_Final '\xF1' /* '1' */
#undef Qc3_MK_New
#define Qc3_MK_New '\xF0' /* '0' */
#undef Qc3_MK_Current
#define Qc3_MK_Current '\xF1' /* '1' */
#undef Qc3_MK_Old
#define Qc3_MK_Old '\xF2' /* '2' */
#undef Qc3_MK_Pending
#define Qc3_MK_Pending '\xF3' /* '3' */
/* Define which features are supported. */
#ifdef OPENSSL_NO_MD5
# define LIBSSH2_MD5 0
#else
# define LIBSSH2_MD5 1
#endif
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 0
#define LIBSSH2_ECDSA 0
#define LIBSSH2_ED25519 0
#include "crypto_config.h"
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: global handles structures.
*
*******************************************************************/
/* HMAC & private key algorithms support structure. */
typedef struct _libssh2_os400qc3_crypto_ctx _libssh2_os400qc3_crypto_ctx;
struct _libssh2_os400qc3_crypto_ctx {
Qc3_Format_ALGD0100_T hash; /* Hash algorithm. */
Qc3_Format_KEYD0100_T key; /* Key. */
_libssh2_os400qc3_crypto_ctx * kek; /* Key encryption. */
};
typedef struct { /* Big number. */
unsigned char * bignum; /* Number bits, little-endian. */
unsigned int length; /* Length of bignum (# bytes). */
} _libssh2_bn;
typedef struct { /* Algorithm description. */
char * fmt; /* Format of Qc3 structure. */
int algo; /* Algorithm identifier. */
unsigned char size; /* Block length. */
unsigned char mode; /* Block mode. */
int keylen; /* Key length. */
} _libssh2_os400qc3_cipher_t;
typedef struct { /* Diffie-Hellman context. */
char token[8]; /* Context token. */
} _libssh2_os400qc3_dh_ctx;
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Define global types/codes.
*
*******************************************************************/
#define libssh2_crypto_init()
#define libssh2_crypto_exit()
#define libssh2_sha1_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha256_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha384_ctx Qc3_Format_ALGD0100_T
#define libssh2_sha512_ctx Qc3_Format_ALGD0100_T
#define libssh2_hmac_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_cipher_ctx _libssh2_os400qc3_crypto_ctx
#define libssh2_sha1_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA1)
#define libssh2_sha1_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha1_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA256)
#define libssh2_sha256_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha256_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha256(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA256)
#define libssh2_sha384_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA384)
#define libssh2_sha384_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha384_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha384(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA384)
#define libssh2_sha512_init(x) _libssh2_os400qc3_hash_init(x, Qc3_SHA512)
#define libssh2_sha512_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_sha512_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#define libssh2_sha512(message, len, out) \
_libssh2_os400qc3_hash(message, len, out, \
Qc3_SHA512)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#define libssh2_md5_ctx Qc3_Format_ALGD0100_T
#define libssh2_md5_init(x) _libssh2_os400qc3_hash_init(x, Qc3_MD5)
#define libssh2_md5_update(ctx, data, len) \
_libssh2_os400qc3_hash_update(&(ctx), data, len)
#define libssh2_md5_final(ctx, out) \
_libssh2_os400qc3_hash_final(&(ctx), out)
#endif
#define _libssh2_bn_ctx int /* Not used. */
#define _libssh2_bn_ctx_new() 0
#define _libssh2_bn_ctx_free(bnctx) ((void) 0)
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
#define _libssh2_bn_bytes(bn) ((bn)->length)
#define _libssh2_cipher_type(name) _libssh2_os400qc3_cipher_t name
#define _libssh2_cipher_aes128 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 16}
#define _libssh2_cipher_aes192 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 24}
#define _libssh2_cipher_aes256 {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CBC, 32}
#define _libssh2_cipher_aes128ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 16}
#define _libssh2_cipher_aes192ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 24}
#define _libssh2_cipher_aes256ctr {Qc3_Alg_Block_Cipher, Qc3_AES, 16, \
Qc3_CTR, 32}
#define _libssh2_cipher_3des {Qc3_Alg_Block_Cipher, Qc3_TDES, 8, \
Qc3_CBC, 24}
/* Nonsense values for chacha20-poly1305 */
#define _libssh2_cipher_chacha20 {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_arcfour {Qc3_Alg_Stream_Cipher, Qc3_RC4, 8, 0, 16}
#define _libssh2_cipher_dtor(ctx) _libssh2_os400qc3_crypto_dtor(ctx)
#define libssh2_rsa_ctx _libssh2_os400qc3_crypto_ctx
#define _libssh2_rsa_free(ctx) (_libssh2_os400qc3_crypto_dtor(ctx), \
free((char *) ctx))
#define libssh2_prepare_iovec(vec, len) memset((char *) (vec), 0, \
(len) * sizeof(struct iovec))
#define _libssh2_rsa_sha1_signv(session, sig, siglen, count, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA1, sig, siglen, \
count, vector, ctx)
#define _libssh2_rsa_sha2_256_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA256, sig, siglen, \
cnt, vector, ctx)
#define _libssh2_rsa_sha2_512_signv(session, sig, siglen, cnt, vector, ctx) \
_libssh2_os400qc3_rsa_signv(session, Qc3_SHA512, sig, siglen, \
cnt, vector, ctx)
/* Default generate and safe prime sizes for diffie-hellman-group-exchange-sha1
Qc3 is limited to a maximum 2048-bit modulus/key size. */
#define LIBSSH2_DH_GEX_MINGROUP 1024
#define LIBSSH2_DH_GEX_OPTGROUP 1536
#define LIBSSH2_DH_GEX_MAXGROUP 2048
#define LIBSSH2_DH_MAX_MODULUS_BITS 2048
#define _libssh2_dh_ctx _libssh2_os400qc3_dh_ctx
#define libssh2_dh_init(dhctx) _libssh2_os400qc3_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_os400qc3_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_os400qc3_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_os400qc3_dh_dtor(dhctx)
/*******************************************************************
*
* OS/400 QC3 crypto-library backend: Support procedure prototypes.
*
*******************************************************************/
extern _libssh2_bn * _libssh2_bn_init(void);
extern void _libssh2_bn_free(_libssh2_bn *bn);
extern unsigned long _libssh2_bn_bits(_libssh2_bn *bn);
extern int _libssh2_bn_from_bin(_libssh2_bn *bn, size_t len,
const unsigned char *v);
extern int _libssh2_bn_set_word(_libssh2_bn *bn, unsigned long val);
extern int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val);
extern int _libssh2_random(unsigned char *buf, size_t len);
extern void _libssh2_os400qc3_crypto_dtor(_libssh2_os400qc3_crypto_ctx *x);
extern int _libssh2_os400qc3_hash_init(Qc3_Format_ALGD0100_T *x,
unsigned int algo);
extern int _libssh2_os400qc3_hash_update(Qc3_Format_ALGD0100_T *ctx,
const unsigned char *data,
int len);
extern int _libssh2_os400qc3_hash_final(Qc3_Format_ALGD0100_T *ctx,
unsigned char *out);
extern int _libssh2_os400qc3_hash(const unsigned char *message,
unsigned long len, unsigned char *out,
unsigned int algo);
extern int _libssh2_os400qc3_rsa_signv(LIBSSH2_SESSION *session, int algo,
unsigned char **signature,
size_t *signature_len,
int veccount,
const struct iovec vector[],
libssh2_rsa_ctx *ctx);
extern void _libssh2_os400qc3_dh_init(_libssh2_dh_ctx *dhctx);
extern int _libssh2_os400qc3_dh_key_pair(_libssh2_dh_ctx *dhctx,
_libssh2_bn *public,
_libssh2_bn *g,
_libssh2_bn *p, int group_order);
extern int _libssh2_os400qc3_dh_secret(_libssh2_dh_ctx *dhctx,
_libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void _libssh2_os400qc3_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_OS400QC3_H */
/* vim: set expandtab ts=4 sw=4: */
File diff suppressed because it is too large. Load diff
+77
View File
@@ -0,0 +1,77 @@
#ifndef LIBSSH2_PACKET_H
#define LIBSSH2_PACKET_H
/*
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int _libssh2_packet_read(LIBSSH2_SESSION * session);
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len);
int _libssh2_packet_require(LIBSSH2_SESSION * session,
unsigned char packet_type, unsigned char **data,
size_t *data_len, int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_require_state_t * state);
int _libssh2_packet_requirev(LIBSSH2_SESSION *session,
const unsigned char *packet_types,
unsigned char **data, size_t *data_len,
int match_ofs,
const unsigned char *match_buf,
size_t match_len,
packet_requirev_state_t * state);
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
libssh2_nonblocking_states * state);
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
unsigned long data_len);
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
size_t datalen, int macstate, uint32_t seq);
#endif /* LIBSSH2_PACKET_H */
+975
View File
@@ -0,0 +1,975 @@
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Simon Josefsson
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
static int
readline(char *line, int line_size, FILE * fp)
{
size_t len;
if(!line) {
return -1;
}
if(!fgets(line, line_size, fp)) {
return -1;
}
if(*line) {
len = strlen(line);
if(len > 0 && line[len - 1] == '\n') {
line[len - 1] = '\0';
}
}
if(*line) {
len = strlen(line);
if(len > 0 && line[len - 1] == '\r') {
line[len - 1] = '\0';
}
}
return 0;
}
static int
readline_memory(char *line, size_t line_size,
const char *filedata, size_t filedata_len,
size_t *filedata_offset)
{
size_t off, len;
off = *filedata_offset;
for(len = 0; off + len < filedata_len && len < line_size - 1; len++) {
if(filedata[off + len] == '\n' ||
filedata[off + len] == '\r') {
break;
}
}
if(len) {
memcpy(line, filedata + off, len);
*filedata_offset += len;
}
line[len] = '\0';
*filedata_offset += 1;
return 0;
}
#define LINE_SIZE 128
static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED";
static unsigned char hex_decode(char digit)
{
return (unsigned char)
((digit >= 'A') ? (0xA + (digit - 'A')) : (digit - '0'));
}
int
_libssh2_pem_parse(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const unsigned char *passphrase,
FILE * fp, unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
unsigned char iv[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
int ret;
const LIBSSH2_CRYPT_METHOD *method = NULL;
do {
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
} while(strcmp(line, headerbegin) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
if(passphrase &&
memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
int i;
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
all_methods = libssh2_crypt_methods();
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->pem_annotation &&
memcmp(line, cur_method->pem_annotation,
strlen(cur_method->pem_annotation)) == 0) {
method = cur_method;
memcpy(iv, line + strlen(method->pem_annotation) + 1,
2*method->iv_len);
}
}
/* None of the available crypt methods were able to decrypt the key */
if(!method)
return -1;
/* Decode IV from hex */
for(i = 0; i < method->iv_len; ++i) {
iv[i] = (unsigned char)(hex_decode(iv[2*i]) << 4);
iv[i] |= hex_decode(iv[2*i + 1]);
}
/* skip to the next line */
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
}
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while(strcmp(line, headerend) != 0);
if(!b64data) {
return -1;
}
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
if(method) {
#if LIBSSH2_MD5_PEM
/* Set up decryption */
int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0;
int blocksize = method->blocksize;
void *abstract;
unsigned char secret[2*MD5_DIGEST_LENGTH];
libssh2_md5_ctx fingerprint_ctx;
/* Perform key derivation (PBKDF1/MD5) */
if(!libssh2_md5_init(&fingerprint_ctx) ||
!libssh2_md5_update(fingerprint_ctx, passphrase,
strlen((char *)passphrase)) ||
!libssh2_md5_update(fingerprint_ctx, iv, 8) ||
!libssh2_md5_final(fingerprint_ctx, secret)) {
ret = -1;
goto out;
}
if(method->secret_len > MD5_DIGEST_LENGTH) {
if(!libssh2_md5_init(&fingerprint_ctx) ||
!libssh2_md5_update(fingerprint_ctx,
secret, MD5_DIGEST_LENGTH) ||
!libssh2_md5_update(fingerprint_ctx,
passphrase, strlen((char *)passphrase)) ||
!libssh2_md5_update(fingerprint_ctx, iv, 8) ||
!libssh2_md5_final(fingerprint_ctx,
secret + MD5_DIGEST_LENGTH)) {
ret = -1;
goto out;
}
}
/* Initialize the decryption */
if(method->init(session, method, iv, &free_iv, secret,
&free_secret, 0, &abstract)) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
LIBSSH2_FREE(session, data);
ret = -1;
goto out;
}
if(free_secret) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
}
/* Do the actual decryption */
if((*datalen % blocksize) != 0) {
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
ret = -1;
goto out;
}
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, *data, *datalen, &abstract, 0)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
}
else {
while(len_decrypted <= (int)*datalen - blocksize) {
if(method->crypt(session, 0, *data + len_decrypted, blocksize,
&abstract,
len_decrypted == 0 ? FIRST_BLOCK :
((len_decrypted == (int)*datalen - blocksize) ?
LAST_BLOCK : MIDDLE_BLOCK)
)) {
ret = LIBSSH2_ERROR_DECRYPT;
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
_libssh2_explicit_zero(*data, *datalen);
LIBSSH2_FREE(session, *data);
goto out;
}
len_decrypted += blocksize;
}
}
/* Account for padding */
padding = (*data)[*datalen - 1];
memset(&(*data)[*datalen-padding], 0, padding);
*datalen -= padding;
/* Clean up */
_libssh2_explicit_zero((char *)secret, sizeof(secret));
method->dtor(session, &abstract);
#else
ret = -1;
goto out;
#endif
}
ret = 0;
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
int
_libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
const char *headerbegin,
const char *headerend,
const char *filedata, size_t filedata_len,
unsigned char **data, size_t *datalen)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
size_t off = 0;
int ret;
do {
*line = '\0';
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
} while(strcmp(line, headerbegin) != 0);
*line = '\0';
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1;
goto out;
}
} while(strcmp(line, headerend) != 0);
if(!b64data) {
return -1;
}
if(_libssh2_base64_decode(session, (char **) data, datalen,
b64data, b64datalen)) {
ret = -1;
goto out;
}
ret = 0;
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
/* OpenSSH formatted keys */
#define AUTH_MAGIC "openssh-key-v1"
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----"
static int
_libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *b64data, size_t b64datalen,
struct string_buf **decrypted_buf)
{
const LIBSSH2_CRYPT_METHOD *method = NULL;
struct string_buf decoded, decrypted, kdf_buf;
unsigned char *ciphername = NULL;
unsigned char *kdfname = NULL;
unsigned char *kdf = NULL;
unsigned char *buf = NULL;
unsigned char *salt = NULL;
uint32_t nkeys, check1, check2;
uint32_t rounds = 0;
unsigned char *key = NULL;
unsigned char *key_part = NULL;
unsigned char *iv_part = NULL;
unsigned char *f = NULL;
size_t f_len = 0;
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
if(decrypted_buf)
*decrypted_buf = NULL;
/* decode file */
if(_libssh2_base64_decode(session, (char **)&f, &f_len,
b64data, b64datalen)) {
ret = -1;
goto out;
}
/* Parse the file */
decoded.data = (unsigned char *)f;
decoded.dataptr = (unsigned char *)f;
decoded.len = f_len;
if(decoded.len < strlen(AUTH_MAGIC)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short");
goto out;
}
if(strncmp((char *) decoded.dataptr, AUTH_MAGIC,
strlen(AUTH_MAGIC)) != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"key auth magic mismatch");
goto out;
}
decoded.dataptr += strlen(AUTH_MAGIC) + 1;
if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"ciphername is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdfname is missing");
goto out;
}
if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf is missing");
goto out;
}
else {
kdf_buf.data = kdf;
kdf_buf.dataptr = kdf;
kdf_buf.len = kdf_len;
}
if((!passphrase || strlen((const char *)passphrase) == 0) &&
strcmp((const char *)ciphername, "none") != 0) {
/* passphrase required */
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(strcmp((const char *)kdfname, "none") != 0 &&
strcmp((const char *)kdfname, "bcrypt") != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"unknown cipher");
goto out;
}
if(!strcmp((const char *)kdfname, "none") &&
strcmp((const char *)ciphername, "none") != 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"invalid format");
goto out;
}
if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Multiple keys are unsupported");
goto out;
}
/* unencrypted public key */
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Invalid private key; "
"expect embedded public key");
goto out;
}
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key data not found");
goto out;
}
/* decode encrypted private key */
decrypted.data = decrypted.dataptr = buf;
decrypted.len = tmp_len;
if(ciphername && strcmp((const char *)ciphername, "none") != 0) {
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
all_methods = libssh2_crypt_methods();
/* !checksrc! disable EQUALSNULL 1 */
while((cur_method = *all_methods++) != NULL) {
if(*cur_method->name &&
memcmp(ciphername, cur_method->name,
strlen(cur_method->name)) == 0) {
method = cur_method;
}
}
/* None of the available crypt methods were able to decrypt the key */
if(!method) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"No supported cipher found");
goto out;
}
}
if(method) {
int free_iv = 0, free_secret = 0, len_decrypted = 0;
int blocksize;
void *abstract = NULL;
keylen = method->secret_len;
ivlen = method->iv_len;
total_len = keylen + ivlen;
key = LIBSSH2_CALLOC(session, total_len);
if(!key) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key");
goto out;
}
if(strcmp((const char *)kdfname, "bcrypt") == 0 && passphrase) {
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"kdf contains unexpected values");
LIBSSH2_FREE(session, key);
goto out;
}
if(_libssh2_bcrypt_pbkdf((const char *)passphrase,
strlen((const char *)passphrase),
salt, salt_len, key,
keylen + ivlen, rounds) < 0) {
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
"invalid format");
LIBSSH2_FREE(session, key);
goto out;
}
}
else {
ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED,
"bcrypted without passphrase");
LIBSSH2_FREE(session, key);
goto out;
}
/* Set up decryption */
blocksize = method->blocksize;
key_part = LIBSSH2_CALLOC(session, keylen);
if(!key_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc key part");
goto out;
}
iv_part = LIBSSH2_CALLOC(session, ivlen);
if(!iv_part) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Could not alloc iv part");
goto out;
}
memcpy(key_part, key, keylen);
memcpy(iv_part, key + keylen, ivlen);
/* Initialize the decryption */
if(method->init(session, method, iv_part, &free_iv, key_part,
&free_secret, 0, &abstract)) {
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
/* Do the actual decryption */
if((decrypted.len % blocksize) != 0) {
method->dtor(session, &abstract);
ret = LIBSSH2_ERROR_DECRYPT;
goto out;
}
if(method->flags & LIBSSH2_CRYPT_FLAG_REQUIRES_FULL_PACKET) {
if(method->crypt(session, 0, decrypted.data,
decrypted.len,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
}
else {
while((size_t)len_decrypted <= decrypted.len - blocksize) {
/* We always pass MIDDLE_BLOCK here because OpenSSH Key Files
* do not use AAD to authenticate the length.
* Furthermore, the authentication tag is appended after the
* encrypted key, and the length of the authentication tag is
* not included in the key length, so we check it after the
* loop.
*/
if(method->crypt(session, 0, decrypted.data + len_decrypted,
blocksize,
&abstract,
MIDDLE_BLOCK)) {
ret = LIBSSH2_ERROR_DECRYPT;
method->dtor(session, &abstract);
goto out;
}
len_decrypted += blocksize;
}
/* No padding */
/* for the AES GCM methods, the 16 byte authentication tag is
* appended to the encrypted key */
if(strcmp(method->name, "aes256-gcm@openssh.com") == 0 ||
strcmp(method->name, "aes128-gcm@openssh.com") == 0) {
if(!_libssh2_check_length(&decoded, 16)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"GCM auth tag missing");
method->dtor(session, &abstract);
goto out;
}
if(method->crypt(session, 0, decoded.dataptr, 16, &abstract,
LAST_BLOCK)) {
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
"GCM auth tag invalid");
method->dtor(session, &abstract);
goto out;
}
decoded.dataptr += 16;
}
}
method->dtor(session, &abstract);
}
/* Check random bytes match */
if(_libssh2_get_u32(&decrypted, &check1) != 0 ||
_libssh2_get_u32(&decrypted, &check2) != 0 ||
check1 != check2) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Private key unpack failed (correct password?)");
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
goto out;
}
if(decrypted_buf) {
/* copy data to out-going buffer */
struct string_buf *out_buf = _libssh2_string_buf_new(session);
if(!out_buf) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
goto out;
}
out_buf->data = LIBSSH2_CALLOC(session, decrypted.len);
if(!out_buf->data) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"decrypted struct");
_libssh2_string_buf_free(session, out_buf);
goto out;
}
memcpy(out_buf->data, decrypted.data, decrypted.len);
out_buf->dataptr = out_buf->data +
(decrypted.dataptr - decrypted.data);
out_buf->len = decrypted.len;
*decrypted_buf = out_buf;
}
out:
/* Clean up */
if(key) {
_libssh2_explicit_zero(key, total_len);
LIBSSH2_FREE(session, key);
}
if(key_part) {
_libssh2_explicit_zero(key_part, keylen);
LIBSSH2_FREE(session, key_part);
}
if(iv_part) {
_libssh2_explicit_zero(iv_part, ivlen);
LIBSSH2_FREE(session, iv_part);
}
if(f) {
_libssh2_explicit_zero(f, f_len);
LIBSSH2_FREE(session, f);
}
return ret;
}
int
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
FILE * fp, struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
int ret = 0;
/* read file */
do {
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
if(readline(line, LINE_SIZE, fp)) {
return -1;
}
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for PEM parsing");
ret = -1;
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(readline(line, LINE_SIZE, fp)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data) {
return -1;
}
ret = _libssh2_openssh_pem_parse_data(session,
passphrase,
(const char *)b64data,
b64datalen,
decrypted_buf);
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
out:
return ret;
}
int
_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
const unsigned char *passphrase,
const char *filedata, size_t filedata_len,
struct string_buf **decrypted_buf)
{
char line[LINE_SIZE];
char *b64data = NULL;
size_t b64datalen = 0;
size_t off = 0;
int ret;
if(!filedata || filedata_len <= 0)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: filedata missing");
do {
*line = '\0';
if(off >= filedata_len)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: "
"OpenSSH header not found");
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
return -1;
}
} while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
*line = '\0';
do {
if(*line) {
char *tmp;
size_t linelen;
linelen = strlen(line);
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
if(!tmp) {
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"PEM parsing");
goto out;
}
memcpy(tmp + b64datalen, line, linelen);
b64data = tmp;
b64datalen += linelen;
}
*line = '\0';
if(off >= filedata_len) {
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: offset out of bounds");
goto out;
}
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
ret = -1;
goto out;
}
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
if(!b64data)
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Error parsing PEM: base 64 data missing");
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
b64datalen, decrypted_buf);
out:
if(b64data) {
_libssh2_explicit_zero(b64data, b64datalen);
LIBSSH2_FREE(session, b64data);
}
return ret;
}
static int
read_asn1_length(const unsigned char *data,
size_t datalen, size_t *len)
{
unsigned int lenlen;
int nextpos;
if(datalen < 1) {
return -1;
}
*len = data[0];
if(*len >= 0x80) {
lenlen = *len & 0x7F;
*len = data[1];
if(1 + lenlen > datalen) {
return -1;
}
if(lenlen > 1) {
*len <<= 8;
*len |= data[2];
}
}
else {
lenlen = 0;
}
nextpos = 1 + lenlen;
if(lenlen > 2 || 1 + lenlen + *len > datalen) {
return -1;
}
return nextpos;
}
int
_libssh2_pem_decode_sequence(unsigned char **data, size_t *datalen)
{
size_t len;
int lenlen;
if(*datalen < 1) {
return -1;
}
if((*data)[0] != '\x30') {
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if(lenlen < 0 || lenlen + len != *datalen) {
return -1;
}
*data += lenlen;
*datalen -= lenlen;
return 0;
}
int
_libssh2_pem_decode_integer(unsigned char **data, size_t *datalen,
unsigned char **i, unsigned int *ilen)
{
size_t len;
int lenlen;
if(*datalen < 1) {
return -1;
}
if((*data)[0] != '\x02') {
return -1;
}
(*data)++;
(*datalen)--;
lenlen = read_asn1_length(*data, *datalen, &len);
if(lenlen < 0 || lenlen + len > *datalen) {
return -1;
}
*data += lenlen;
*datalen -= lenlen;
*i = *data;
*ilen = (unsigned int)len;
*data += len;
*datalen -= len;
return 0;
}
+206
View File
@@ -0,0 +1,206 @@
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */
#include "libssh2_priv.h"
#include "poly1305.h"
#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
#define U8TO32_LE(p) \
(((uint32_t)((p)[0])) | \
((uint32_t)((p)[1]) << 8) | \
((uint32_t)((p)[2]) << 16) | \
((uint32_t)((p)[3]) << 24))
#define U32TO8_LE(p, v) \
do { \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24); \
} while (0)
void
poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m,
size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
uint32_t t0;
uint32_t t1;
uint32_t t2;
uint32_t t3;
uint32_t h0;
uint32_t h1;
uint32_t h2;
uint32_t h3;
uint32_t h4;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t b;
uint32_t nb;
size_t j;
uint64_t t[5];
uint64_t f0;
uint64_t f1;
uint64_t f2;
uint64_t f3;
uint32_t g0;
uint32_t g1;
uint32_t g2;
uint32_t g3;
uint32_t g4;
uint64_t c;
unsigned char mp[16];
/* clamp key */
t0 = U8TO32_LE(key + 0);
t1 = U8TO32_LE(key + 4);
t2 = U8TO32_LE(key + 8);
t3 = U8TO32_LE(key + 12);
/* precompute multipliers */
r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
r3 = t2 & 0x3f03fff; t3 >>= 8;
r4 = t3 & 0x00fffff;
s1 = r1 * 5;
s2 = r2 * 5;
s3 = r3 * 5;
s4 = r4 * 5;
/* init state */
h0 = 0;
h1 = 0;
h2 = 0;
h3 = 0;
h4 = 0;
/* full blocks */
if(inlen < 16)
goto poly1305_donna_atmost15bytes;
poly1305_donna_16bytes:
m += 16;
inlen -= 16;
t0 = U8TO32_LE(m-16);
t1 = U8TO32_LE(m-12);
t2 = U8TO32_LE(m-8);
t3 = U8TO32_LE(m-4);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8) | (1 << 24);
poly1305_donna_mul:
t[0] = mul32x32_64(h0, r0) + mul32x32_64(h1, s4) + mul32x32_64(h2, s3) +
mul32x32_64(h3, s2) + mul32x32_64(h4, s1);
t[1] = mul32x32_64(h0, r1) + mul32x32_64(h1, r0) + mul32x32_64(h2, s4) +
mul32x32_64(h3, s3) + mul32x32_64(h4, s2);
t[2] = mul32x32_64(h0, r2) + mul32x32_64(h1, r1) + mul32x32_64(h2, r0) +
mul32x32_64(h3, s4) + mul32x32_64(h4, s3);
t[3] = mul32x32_64(h0, r3) + mul32x32_64(h1, r2) + mul32x32_64(h2, r1) +
mul32x32_64(h3, r0) + mul32x32_64(h4, s4);
t[4] = mul32x32_64(h0, r4) + mul32x32_64(h1, r3) + mul32x32_64(h2, r2) +
mul32x32_64(h3, r1) + mul32x32_64(h4, r0);
h0 = (uint32_t)t[0] & 0x3ffffff;
c = (t[0] >> 26);
t[1] += c;
h1 = (uint32_t)t[1] & 0x3ffffff;
b = (uint32_t)(t[1] >> 26);
t[2] += b;
h2 = (uint32_t)t[2] & 0x3ffffff;
b = (uint32_t)(t[2] >> 26);
t[3] += b;
h3 = (uint32_t)t[3] & 0x3ffffff;
b = (uint32_t)(t[3] >> 26);
t[4] += b;
h4 = (uint32_t)t[4] & 0x3ffffff;
b = (uint32_t)(t[4] >> 26);
h0 += b * 5;
if(inlen >= 16)
goto poly1305_donna_16bytes;
/* final bytes */
poly1305_donna_atmost15bytes:
if(!inlen)
goto poly1305_donna_finish;
for(j = 0; j < inlen; j++) mp[j] = m[j];
mp[j++] = 1;
for(; j < 16; j++)
mp[j] = 0;
inlen = 0;
t0 = U8TO32_LE(mp + 0);
t1 = U8TO32_LE(mp + 4);
t2 = U8TO32_LE(mp + 8);
t3 = U8TO32_LE(mp + 12);
h0 += t0 & 0x3ffffff;
h1 += ((uint32_t)((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff);
h2 += ((uint32_t)((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff);
h3 += ((uint32_t)((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff);
h4 += (t3 >> 8);
goto poly1305_donna_mul;
poly1305_donna_finish:
b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
h1 += b;
g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
g4 = h4 + b - (1 << 26);
b = (g4 >> 31) - 1;
nb = ~b;
h0 = (h0 & nb) | (g0 & b);
h1 = (h1 & nb) | (g1 & b);
h2 = (h2 & nb) | (g2 & b);
h3 = (h3 & nb) | (g3 & b);
h4 = (h4 & nb) | (g4 & b);
f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
U32TO8_LE(&out[12], f3);
}
+20
View File
@@ -0,0 +1,20 @@
/* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */
/*
* Public Domain poly1305 from Andrew Moon
* poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
* Copyright not intended 2024.
*
* SPDX-License-Identifier: SAX-PD-2.0
*/
#ifndef POLY1305_H
#define POLY1305_H
#define POLY1305_KEYLEN 32
#define POLY1305_TAGLEN 16
void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen,
const u_char key[POLY1305_KEYLEN]);
#endif /* POLY1305_H */
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+94
View File
@@ -0,0 +1,94 @@
#ifndef LIBSSH2_SESSION_H
#define LIBSSH2_SESSION_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* Copyright (C) Simon Josefsson <simon@josefsson.org>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* Conveniance-macros to allow code like this;
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock));
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock));
The point being to make sure that while in non-blocking mode these always
return no matter what the return code is, but in blocking mode it blocks
if EAGAIN is the reason for the return from the underlying function.
*/
#define BLOCK_ADJUST(rc, sess, x) \
do { \
time_t entry_time = time(NULL); \
do { \
rc = x; \
/* the order of the check below is important to properly \
deal with the case when the 'sess' is freed */ \
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
/*
* For functions that returns a pointer, we need to check if the API is
* non-blocking and return immediately. If the pointer is non-NULL we return
* immediately. If the API is blocking and we get a NULL we check the errno
* and *only* if that is EAGAIN we loop and wait for socket action.
*/
#define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
do { \
time_t entry_time = time(NULL); \
int rc; \
do { \
ptr = x; \
if(!sess->api_block_mode || \
(ptr != NULL) || \
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN)) \
break; \
rc = _libssh2_wait_socket(sess, entry_time); \
} while(!rc); \
} while(0)
int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
/* this is the lib-internal set blocking function */
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
#endif /* LIBSSH2_SESSION_H */
File diff suppressed because it is too large. Load diff
+242
View File
@@ -0,0 +1,242 @@
#ifndef LIBSSH2_SFTP_PRIV_H
#define LIBSSH2_SFTP_PRIV_H
/*
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the
* amount of data sent in each FXP_WRITE packet
*/
#define MAX_SFTP_OUTGOING_SIZE 30000
/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
* packets.
*/
#define MAX_SFTP_READ_SIZE 30000
struct sftp_pipeline_chunk {
struct list_node node;
libssh2_uint64_t offset; /* READ: offset at which to start reading
WRITE: not used */
size_t len; /* WRITE: size of the data to write
READ: how many bytes that was asked for */
size_t sent;
ssize_t lefttosend; /* if 0, the entire packet has been sent off */
uint32_t request_id;
unsigned char packet[1]; /* data */
};
struct sftp_zombie_requests {
struct list_node node;
uint32_t request_id;
};
struct _LIBSSH2_SFTP_PACKET
{
struct list_node node; /* linked list header */
uint32_t request_id;
unsigned char *data;
size_t data_len; /* payload size */
};
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
/* Increasing from 256 to 4092 since OpenSSH doesn't honor it. */
#define SFTP_HANDLE_MAXLEN 4092 /* according to spec, this should be 256! */
struct _LIBSSH2_SFTP_HANDLE
{
struct list_node node;
LIBSSH2_SFTP *sftp;
char handle[SFTP_HANDLE_MAXLEN];
size_t handle_len;
enum {
LIBSSH2_SFTP_HANDLE_FILE,
LIBSSH2_SFTP_HANDLE_DIR
} handle_type;
union _libssh2_sftp_handle_data
{
struct _libssh2_sftp_handle_file_data
{
libssh2_uint64_t offset;
libssh2_uint64_t offset_sent;
size_t acked; /* container for acked data that hasn't been
returned to caller yet, used for sftp_write */
/* 'data' is used by sftp_read() and is allocated data that has
been received already from the server but wasn't returned to
the caller yet. It is of size 'data_len' and 'data_left is the
number of bytes not yet returned, counted from the end of the
buffer. */
unsigned char *data;
size_t data_len;
size_t data_left;
char eof; /* we have read to the end */
} file;
struct _libssh2_sftp_handle_dir_data
{
uint32_t names_left;
void *names_packet;
char *next_name;
size_t names_packet_len;
} dir;
} u;
/* State variables used in libssh2_sftp_close_handle() */
libssh2_nonblocking_states close_state;
uint32_t close_request_id;
unsigned char *close_packet;
/* list of outstanding packets sent to server */
struct list_head packet_list;
};
struct _LIBSSH2_SFTP
{
LIBSSH2_CHANNEL *channel;
uint32_t request_id, version, posix_rename_version;
struct list_head packets;
/* List of FXP_READ responses to ignore because EOF already received. */
struct list_head zombie_requests;
/* a list of _LIBSSH2_SFTP_HANDLE structs */
struct list_head sftp_handles;
uint32_t last_errno;
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
unsigned char packet_header[9];
/* packet size (4) packet type (1) request id (4) */
size_t packet_header_len; /* packet_header length */
unsigned char *partial_packet; /* The data, with header */
uint32_t partial_len; /* Desired number of bytes */
size_t partial_received; /* Bytes received so far */
/* Time that libssh2_sftp_packet_requirev() started reading */
time_t requirev_start;
/* State variables used in libssh2_sftp_open_ex() */
libssh2_nonblocking_states open_state;
unsigned char *open_packet;
uint32_t open_packet_len; /* 32 bit on the wire */
size_t open_packet_sent;
uint32_t open_request_id;
/* State variable used in sftp_read() */
libssh2_nonblocking_states read_state;
/* State variable used in sftp_packet_read() */
libssh2_nonblocking_states packet_state;
/* State variable used in sftp_write() */
libssh2_nonblocking_states write_state;
/* State variables used in sftp_fsync() */
libssh2_nonblocking_states fsync_state;
unsigned char *fsync_packet;
uint32_t fsync_request_id;
/* State variables used in libssh2_sftp_readdir() */
libssh2_nonblocking_states readdir_state;
unsigned char *readdir_packet;
uint32_t readdir_request_id;
/* State variables used in libssh2_sftp_fstat_ex() */
libssh2_nonblocking_states fstat_state;
unsigned char *fstat_packet;
uint32_t fstat_request_id;
/* State variables used in libssh2_sftp_unlink_ex() */
libssh2_nonblocking_states unlink_state;
unsigned char *unlink_packet;
uint32_t unlink_request_id;
/* State variables used in libssh2_sftp_rename_ex() */
libssh2_nonblocking_states rename_state;
unsigned char *rename_packet;
unsigned char *rename_s;
uint32_t rename_request_id;
/* State variables used in libssh2_sftp_posix_rename_ex() */
libssh2_nonblocking_states posix_rename_state;
unsigned char *posix_rename_packet;
uint32_t posix_rename_request_id;
/* State variables used in libssh2_sftp_fstatvfs() */
libssh2_nonblocking_states fstatvfs_state;
unsigned char *fstatvfs_packet;
uint32_t fstatvfs_request_id;
/* State variables used in libssh2_sftp_statvfs() */
libssh2_nonblocking_states statvfs_state;
unsigned char *statvfs_packet;
uint32_t statvfs_request_id;
/* State variables used in libssh2_sftp_mkdir() */
libssh2_nonblocking_states mkdir_state;
unsigned char *mkdir_packet;
uint32_t mkdir_request_id;
/* State variables used in libssh2_sftp_rmdir() */
libssh2_nonblocking_states rmdir_state;
unsigned char *rmdir_packet;
uint32_t rmdir_request_id;
/* State variables used in libssh2_sftp_stat() */
libssh2_nonblocking_states stat_state;
unsigned char *stat_packet;
uint32_t stat_request_id;
/* State variables used in libssh2_sftp_symlink() */
libssh2_nonblocking_states symlink_state;
unsigned char *symlink_packet;
uint32_t symlink_request_id;
};
#endif /* LIBSSH2_SFTP_PRIV_H */
File diff suppressed because it is too large. Load diff
+87
View File
@@ -0,0 +1,87 @@
#ifndef LIBSSH2_TRANSPORT_H
#define LIBSSH2_TRANSPORT_H
/* Copyright (C) The Written Word, Inc.
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* This file handles reading and writing to the SECSH transport layer. RFC4253.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "packet.h"
/*
* libssh2_transport_send
*
* Send a packet, encrypting it and adding a MAC code if necessary
* Returns 0 on success, non-zero on failure.
*
* The data is provided as _two_ data areas that are combined by this
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
* be set to NULL (or data2_len to 0) to only use a single part.
*
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
* not sent yet. If it does so, the caller should call this function again as
* soon as it is likely that more data can be sent, and this function MUST
* then be called with the same argument set (same data pointer and same
* data_len) until ERROR_NONE or failure is returned.
*
* This function DOES NOT call _libssh2_error() on any errors.
*/
int _libssh2_transport_send(LIBSSH2_SESSION *session,
const unsigned char *data, size_t data_len,
const unsigned char *data2, size_t data2_len);
/*
* _libssh2_transport_read
*
* Collect a packet into the input brigade block only controls whether or not
* to wait for a packet to start.
*
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
* packet.
*/
/*
* This function reads the binary stream as specified in chapter 6 of RFC4253
* "The Secure Shell (SSH) Transport Layer Protocol"
*/
int _libssh2_transport_read(LIBSSH2_SESSION * session);
#endif /* LIBSSH2_TRANSPORT_H */
File diff suppressed because it is too large. Load diff
+53
View File
@@ -0,0 +1,53 @@
#ifndef LIBSSH2_USERAUTH_H
#define LIBSSH2_USERAUTH_H
/* Copyright (C) Sara Golemon <sarag@libssh2.org>
* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
int
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
const char *username,
size_t username_len,
const unsigned char *pubkeydata,
size_t pubkeydata_len,
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
((*sign_callback)),
void *abstract);
#endif /* LIBSSH2_USERAUTH_H */
+166
View File
@@ -0,0 +1,166 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
#include "userauth_kbd_packet.h"
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *session)
{
unsigned char *language_tag;
size_t language_tag_len;
unsigned int i;
unsigned char packet_type;
uint32_t tmp_u32;
struct string_buf decoded;
decoded.data = session->userauth_kybd_data;
decoded.dataptr = session->userauth_kybd_data;
decoded.len = session->userauth_kybd_data_len;
if(session->userauth_kybd_data_len < 17) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"userauth keyboard data buffer too small "
"to get length");
return -1;
}
/* byte SSH_MSG_USERAUTH_INFO_REQUEST */
_libssh2_get_byte(&decoded, &packet_type);
/* string name (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_name,
&session->userauth_kybd_auth_name_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'name' "
"request field");
return -1;
}
/* string instruction (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_auth_instruction,
&session->userauth_kybd_auth_instruction_len)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'instruction' "
"request field");
return -1;
}
/* string language tag (as defined in [RFC-3066]) */
if(_libssh2_get_string(&decoded, &language_tag,
&language_tag_len) == -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive 'language tag' "
"request field");
return -1;
}
/* int num-prompts */
if(_libssh2_get_u32(&decoded, &tmp_u32) == -1 ||
(session->userauth_kybd_num_prompts = tmp_u32) != tmp_u32) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"keyboard-interactive number of keyboard prompts");
return -1;
}
if(session->userauth_kybd_num_prompts > 100) {
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
"Too many replies for "
"keyboard-interactive prompts");
return -1;
}
if(session->userauth_kybd_num_prompts == 0) {
return 0;
}
session->userauth_kybd_prompts =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_prompts) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive prompts array");
return -1;
}
session->userauth_kybd_responses =
LIBSSH2_CALLOC(session,
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
session->userauth_kybd_num_prompts);
if(!session->userauth_kybd_responses) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to allocate memory for "
"keyboard-interactive responses array");
return -1;
}
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
/* string prompt[1] (ISO-10646 UTF-8) */
if(_libssh2_copy_string(session, &decoded,
&session->userauth_kybd_prompts[i].text,
&session->userauth_kybd_prompts[i].length)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
"Unable to decode "
"keyboard-interactive prompt message");
return -1;
}
/* boolean echo[1] */
if(_libssh2_get_boolean(&decoded,
&session->userauth_kybd_prompts[i].echo)
== -1) {
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
"Unable to decode "
"user auth keyboard prompt echo");
return -1;
}
}
return 0;
}
+45
View File
@@ -0,0 +1,45 @@
/* Copyright (C) Xaver Loppenstedt <xaver@loppenstedt.de>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef LIBSSH2_USERAUTH_KBD_PACKET_H
#define LIBSSH2_USERAUTH_KBD_PACKET_H
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *);
#endif /* LIBSSH2_USERAUTH_KBD_PACKET_H */
+54
View File
@@ -0,0 +1,54 @@
/* Copyright (C) Daniel Stenberg
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "libssh2_priv.h"
LIBSSH2_API
const char *libssh2_version(int req_version_num)
{
if(req_version_num <= LIBSSH2_VERSION_NUM)
return LIBSSH2_VERSION;
return NULL; /* this is not a suitable library! */
}
LIBSSH2_API
libssh2_crypto_engine_t libssh2_crypto_engine(void)
{
return LIBSSH2_CRYPTO_ENGINE;
}
File diff suppressed because it is too large. Load diff
+561
View File
@@ -0,0 +1,561 @@
#ifndef LIBSSH2_WINCNG_H
#define LIBSSH2_WINCNG_H
/*
* Copyright (C) Marc Hoersken <info@marc-hoersken.de>
* 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 copyright holder nor the names
* of any other contributors may be used to endorse or
* promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#define LIBSSH2_CRYPTO_ENGINE libssh2_wincng
/* required for cross-compilation against the w64 mingw-runtime package */
#if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600)
#undef _WIN32_WINNT
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
#include <bcrypt.h>
#define LIBSSH2_MD5 1
#define LIBSSH2_HMAC_RIPEMD 0
#define LIBSSH2_HMAC_SHA256 1
#define LIBSSH2_HMAC_SHA512 1
#define LIBSSH2_AES_CBC 1
#define LIBSSH2_AES_CTR 1
#define LIBSSH2_AES_GCM 0
#define LIBSSH2_BLOWFISH 0
#define LIBSSH2_RC4 1
#define LIBSSH2_CAST 0
#define LIBSSH2_3DES 1
#define LIBSSH2_RSA 1
#define LIBSSH2_RSA_SHA1 1
#define LIBSSH2_RSA_SHA2 1
#define LIBSSH2_DSA 1
#define LIBSSH2_ED25519 0
/*
* Conditionally enable ECDSA support.
*
* ECDSA support requires the use of
*
* BCryptDeriveKey(..., BCRYPT_KDF_RAW_SECRET, ... )
*
* This functionality is only available as of Windows 10. To maintain
* backward compatibility, ECDSA support is therefore disabled
* by default and needs to be explicitly enabled using a build
* flag.
*/
#ifdef LIBSSH2_ECDSA_WINCNG
#define LIBSSH2_ECDSA 1
#else
#define LIBSSH2_ECDSA 0
#endif
#include "crypto_config.h"
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define MD5_DIGEST_LENGTH 16
#endif
#define SHA_DIGEST_LENGTH 20
#define SHA256_DIGEST_LENGTH 32
#define SHA384_DIGEST_LENGTH 48
#define SHA512_DIGEST_LENGTH 64
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
#if LIBSSH2_ECDSA
#else
#define _libssh2_ec_key void
#endif
/*******************************************************************/
/*
* Windows CNG backend: Global context handles
*/
struct _libssh2_wincng_ctx {
BCRYPT_ALG_HANDLE hAlgRNG;
BCRYPT_ALG_HANDLE hAlgHashMD5;
BCRYPT_ALG_HANDLE hAlgHashSHA1;
BCRYPT_ALG_HANDLE hAlgHashSHA256;
BCRYPT_ALG_HANDLE hAlgHashSHA384;
BCRYPT_ALG_HANDLE hAlgHashSHA512;
BCRYPT_ALG_HANDLE hAlgHmacMD5;
BCRYPT_ALG_HANDLE hAlgHmacSHA1;
BCRYPT_ALG_HANDLE hAlgHmacSHA256;
BCRYPT_ALG_HANDLE hAlgHmacSHA384;
BCRYPT_ALG_HANDLE hAlgHmacSHA512;
BCRYPT_ALG_HANDLE hAlgRSA;
BCRYPT_ALG_HANDLE hAlgDSA;
BCRYPT_ALG_HANDLE hAlgAES_CBC;
BCRYPT_ALG_HANDLE hAlgAES_ECB;
BCRYPT_ALG_HANDLE hAlgRC4_NA;
BCRYPT_ALG_HANDLE hAlg3DES_CBC;
BCRYPT_ALG_HANDLE hAlgDH;
BCRYPT_ALG_HANDLE hAlgChacha20;
#if LIBSSH2_ECDSA
BCRYPT_ALG_HANDLE hAlgECDH[3]; /* indexed by libssh2_curve_type */
BCRYPT_ALG_HANDLE hAlgECDSA[3]; /* indexed by libssh2_curve_type */
#endif
volatile int hasAlgDHwithKDF; /* -1=no, 0=maybe, 1=yes */
};
extern struct _libssh2_wincng_ctx _libssh2_wincng;
/*******************************************************************/
/*
* Windows CNG backend: Generic functions
*/
#define libssh2_crypto_init() \
_libssh2_wincng_init()
#define libssh2_crypto_exit() \
_libssh2_wincng_free()
#define _libssh2_random(buf, len) \
_libssh2_wincng_random(buf, len)
#define libssh2_prepare_iovec(vec, len) /* Empty. */
/*******************************************************************/
/*
* Windows CNG backend: Hash structure
*/
typedef struct __libssh2_wincng_hash_ctx {
BCRYPT_HASH_HANDLE hHash;
unsigned char *pbHashObject;
ULONG dwHashObject;
ULONG cbHash;
} _libssh2_wincng_hash_ctx;
/*
* Windows CNG backend: Hash functions
*/
#define libssh2_sha1_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha1_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA1, \
SHA_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha1_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha1_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha1(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA1, \
hash, SHA_DIGEST_LENGTH)
#define libssh2_sha256_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha256_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA256, \
SHA256_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha256_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha256_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha256(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA256, \
hash, SHA256_DIGEST_LENGTH)
#define libssh2_sha384_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha384_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA384, \
SHA384_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha384_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha384_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha384(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA384, \
hash, SHA384_DIGEST_LENGTH)
#define libssh2_sha512_ctx _libssh2_wincng_hash_ctx
#define libssh2_sha512_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashSHA512, \
SHA512_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_sha512_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_sha512_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#define libssh2_sha512(data, datalen, hash) \
_libssh2_wincng_hash(data, datalen, _libssh2_wincng.hAlgHashSHA512, \
hash, SHA512_DIGEST_LENGTH)
#if LIBSSH2_MD5 || LIBSSH2_MD5_PEM
#define libssh2_md5_ctx _libssh2_wincng_hash_ctx
#define libssh2_md5_init(ctx) \
(_libssh2_wincng_hash_init(ctx, _libssh2_wincng.hAlgHashMD5, \
MD5_DIGEST_LENGTH, NULL, 0) == 0)
#define libssh2_md5_update(ctx, data, datalen) \
(_libssh2_wincng_hash_update(&ctx, data, (ULONG) datalen) == 0)
#define libssh2_md5_final(ctx, hash) \
(_libssh2_wincng_hash_final(&ctx, hash) == 0)
#endif
/*
* Windows CNG backend: HMAC functions
*/
#define libssh2_hmac_ctx _libssh2_wincng_hash_ctx
/*******************************************************************/
/*
* Windows CNG backend: Key Context structure
*/
typedef struct __libssh2_wincng_key_ctx {
BCRYPT_KEY_HANDLE hKey;
void *pbKeyObject;
DWORD cbKeyObject;
} _libssh2_wincng_key_ctx;
/*
* Windows CNG backend: RSA functions
*/
#define libssh2_rsa_ctx _libssh2_wincng_key_ctx
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len) \
_libssh2_wincng_rsa_new(rsactx, e, e_len, n, n_len, \
d, d_len, p, p_len, q, q_len, \
e1, e1_len, e2, e2_len, c, c_len)
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
_libssh2_wincng_rsa_new_private(rsactx, s, filename, passphrase)
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_rsa_new_private_frommemory(rsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
_libssh2_wincng_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
_libssh2_wincng_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
#define _libssh2_rsa_free(rsactx) \
_libssh2_wincng_rsa_free(rsactx)
/*
* Windows CNG backend: DSA functions
*/
#define libssh2_dsa_ctx _libssh2_wincng_key_ctx
#define _libssh2_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len) \
_libssh2_wincng_dsa_new(dsactx, p, p_len, q, q_len, \
g, g_len, y, y_len, x, x_len)
#define _libssh2_dsa_new_private(dsactx, s, filename, passphrase) \
_libssh2_wincng_dsa_new_private(dsactx, s, filename, passphrase)
#define _libssh2_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_dsa_new_private_frommemory(dsactx, s, filedata, \
filedata_len, passphrase)
#define _libssh2_dsa_sha1_sign(dsactx, hash, hash_len, sig) \
_libssh2_wincng_dsa_sha1_sign(dsactx, hash, hash_len, sig)
#define _libssh2_dsa_sha1_verify(dsactx, sig, m, m_len) \
_libssh2_wincng_dsa_sha1_verify(dsactx, sig, m, m_len)
#define _libssh2_dsa_free(dsactx) \
_libssh2_wincng_dsa_free(dsactx)
/*
* Windows CNG backend: ECDSA functions
*/
typedef enum {
LIBSSH2_EC_CURVE_NISTP256 = 0,
LIBSSH2_EC_CURVE_NISTP384 = 1,
LIBSSH2_EC_CURVE_NISTP521 = 2,
} libssh2_curve_type;
typedef struct __libssh2_wincng_ecdsa_ctx {
BCRYPT_KEY_HANDLE handle;
libssh2_curve_type curve;
} _libssh2_wincng_ecdsa_key;
#define libssh2_ecdsa_ctx _libssh2_wincng_ecdsa_key
#if LIBSSH2_ECDSA
#define _libssh2_ec_key _libssh2_wincng_ecdsa_key
#endif
void
_libssh2_wincng_ecdsa_free(libssh2_ecdsa_ctx* ctx);
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve) \
_libssh2_wincng_ecdh_create_key(session, privkey, pubkey_octal, \
pubkey_octal_len, curve)
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
_libssh2_wincng_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
_libssh2_wincng_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
_libssh2_wincng_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
_libssh2_wincng_ecdsa_new_private(ctx, session, filename, passphrase)
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase) \
_libssh2_wincng_ecdsa_new_private_frommemory(ctx, session, filedata, \
filedata_len, passphrase)
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
_libssh2_wincng_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
#define _libssh2_ecdsa_get_curve_type(ctx) \
_libssh2_wincng_ecdsa_get_curve_type(ctx)
#define _libssh2_ecdsa_free(ecdsactx) \
_libssh2_wincng_ecdsa_free(ecdsactx)
/*
* Windows CNG backend: Key functions
*/
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
_libssh2_wincng_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw) \
_libssh2_wincng_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
pk, pk_len, pw)
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw) \
_libssh2_wincng_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
f, kh, kh_len, pk, pk_len, pw)
/*******************************************************************/
/*
* Windows CNG backend: Cipher Context structure
*/
struct _libssh2_wincng_cipher_ctx {
BCRYPT_KEY_HANDLE hKey;
unsigned char *pbKeyObject;
unsigned char *pbIV;
unsigned char *pbCtr;
ULONG dwKeyObject;
ULONG dwIV;
ULONG dwBlockLength;
ULONG dwCtrLength;
};
#define _libssh2_cipher_ctx struct _libssh2_wincng_cipher_ctx
/*
* Windows CNG backend: Cipher Type structure
*/
struct _libssh2_wincng_cipher_type {
BCRYPT_ALG_HANDLE *phAlg;
ULONG dwKeyLength;
int useIV; /* TODO: Convert to bool when a C89 compatible bool type
is defined */
int ctrMode;
};
#define _libssh2_cipher_type(type) struct _libssh2_wincng_cipher_type type
#define _libssh2_cipher_aes256ctr { &_libssh2_wincng.hAlgAES_ECB, 32, 0, 1 }
#define _libssh2_cipher_aes192ctr { &_libssh2_wincng.hAlgAES_ECB, 24, 0, 1 }
#define _libssh2_cipher_aes128ctr { &_libssh2_wincng.hAlgAES_ECB, 16, 0, 1 }
#define _libssh2_cipher_aes256 { &_libssh2_wincng.hAlgAES_CBC, 32, 1, 0 }
#define _libssh2_cipher_aes192 { &_libssh2_wincng.hAlgAES_CBC, 24, 1, 0 }
#define _libssh2_cipher_aes128 { &_libssh2_wincng.hAlgAES_CBC, 16, 1, 0 }
#define _libssh2_cipher_arcfour { &_libssh2_wincng.hAlgRC4_NA, 16, 0, 0 }
#define _libssh2_cipher_3des { &_libssh2_wincng.hAlg3DES_CBC, 24, 1, 0 }
#define _libssh2_cipher_chacha20 { &_libssh2_wincng.hAlgChacha20, 24, 1, 0 }
/*
* Windows CNG backend: Cipher functions
*/
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
_libssh2_wincng_cipher_init(ctx, type, iv, secret, encrypt)
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen, fl) \
_libssh2_wincng_cipher_crypt(ctx, type, encrypt, block, blocklen, fl)
#define _libssh2_cipher_dtor(ctx) \
_libssh2_wincng_cipher_dtor(ctx)
/*******************************************************************/
/*
* Windows CNG backend: BigNumber Context
*/
#define _libssh2_bn_ctx int /* not used */
#define _libssh2_bn_ctx_new() 0 /* not used */
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
/*******************************************************************/
/*
* Windows CNG backend: BigNumber structure
*/
struct _libssh2_wincng_bignum {
unsigned char *bignum;
ULONG length;
};
#define _libssh2_bn struct _libssh2_wincng_bignum
/*
* Windows CNG backend: BigNumber functions
*/
#define _libssh2_bn_init() \
_libssh2_wincng_bignum_init()
#define _libssh2_bn_init_from_bin() \
_libssh2_bn_init()
#define _libssh2_bn_set_word(bn, word) \
_libssh2_wincng_bignum_set_word(bn, word)
#define _libssh2_bn_from_bin(bn, len, bin) \
_libssh2_wincng_bignum_from_bin(bn, (ULONG) len, bin)
#define _libssh2_bn_to_bin(bn, bin) \
_libssh2_wincng_bignum_to_bin(bn, bin)
#define _libssh2_bn_bytes(bn) bn->length
#define _libssh2_bn_bits(bn) \
_libssh2_wincng_bignum_bits(bn)
#define _libssh2_bn_free(bn) \
_libssh2_wincng_bignum_free(bn)
/*
* Windows CNG backend: Diffie-Hellman support
*/
/* Default generate and safe prime sizes for
diffie-hellman-group-exchange-sha1 */
#define LIBSSH2_DH_GEX_MINGROUP 2048
#define LIBSSH2_DH_GEX_OPTGROUP 4096
#define LIBSSH2_DH_GEX_MAXGROUP 4096
#define LIBSSH2_DH_MAX_MODULUS_BITS 16384
typedef struct {
/* holds our private and public key components */
BCRYPT_KEY_HANDLE dh_handle;
/* records the parsed out modulus and generator
* parameters that are shared with the peer */
BCRYPT_DH_PARAMETER_HEADER *dh_params;
/* records the parsed out private key component for
* fallback if the DH API raw KDF is not supported */
struct _libssh2_wincng_bignum *dh_privbn;
} _libssh2_dh_ctx;
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
_libssh2_dh_secret(dhctx, secret, f, p)
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
/*******************************************************************/
/*
* Windows CNG backend: forward declarations
*/
void _libssh2_wincng_init(void);
void _libssh2_wincng_free(void);
int _libssh2_wincng_random(void *buf, size_t len);
int
_libssh2_wincng_hash_init(_libssh2_wincng_hash_ctx *ctx,
BCRYPT_ALG_HANDLE hAlg, ULONG hashlen,
unsigned char *key, ULONG keylen);
int
_libssh2_wincng_hash_update(_libssh2_wincng_hash_ctx *ctx,
const void *data, ULONG datalen);
int
_libssh2_wincng_hash_final(_libssh2_wincng_hash_ctx *ctx,
unsigned char *hash);
int
_libssh2_wincng_hash(const unsigned char *data, ULONG datalen,
BCRYPT_ALG_HANDLE hAlg,
unsigned char *hash, ULONG hashlen);
void
_libssh2_wincng_rsa_free(libssh2_rsa_ctx *rsa);
#if LIBSSH2_DSA
void
_libssh2_wincng_dsa_free(libssh2_dsa_ctx *dsa);
#endif
void
_libssh2_wincng_cipher_dtor(_libssh2_cipher_ctx *ctx);
_libssh2_bn *
_libssh2_wincng_bignum_init(void);
int
_libssh2_wincng_bignum_set_word(_libssh2_bn *bn, ULONG word);
ULONG
_libssh2_wincng_bignum_bits(const _libssh2_bn *bn);
int
_libssh2_wincng_bignum_from_bin(_libssh2_bn *bn, ULONG len,
const unsigned char *bin);
int
_libssh2_wincng_bignum_to_bin(const _libssh2_bn *bn, unsigned char *bin);
void
_libssh2_wincng_bignum_free(_libssh2_bn *bn);
extern void
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
extern int
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
_libssh2_bn *g, _libssh2_bn *p, int group_order);
extern int
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
_libssh2_bn *f, _libssh2_bn *p);
extern void
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
#endif /* LIBSSH2_WINCNG_H */
+293
View File
@@ -0,0 +1,293 @@
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,17 +1,8 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g., crates.io) dependencies.
-#
-# If you are reading this file be aware that the original Cargo.toml
-# will likely look very different (and much more reasonable).
-# See Cargo.toml.orig for the original contents.
-
+# Vendored from crates.io libssh2-sys 0.3.3; see PROVENANCE.md.
[package]
name = "libssh2-sys"
version = "0.3.3"
+publish = false
authors = [
"Alex Crichton <alex@alexcrichton.com>",
"Wez Furlong <wez@wezfurlong.org>",
@@ -50,12 +41,6 @@
[build-dependencies.cc]
version = "1.0.25"
-[build-dependencies.pkg-config]
-version = "0.3.11"
-
-[target.'cfg(target_env = "msvc")'.build-dependencies.vcpkg]
-version = "0.2"
-
[target."cfg(unix)".dependencies.openssl-sys]
version = "0.9.35"
--- a/build.rs
+++ b/build.rs
@@ -1,42 +1,19 @@
extern crate cc;
-extern crate pkg_config;
-
-#[cfg(target_env = "msvc")]
-extern crate vcpkg;
use std::env;
use std::fs;
-use std::path::{Path, PathBuf};
-use std::process::Command;
+use std::path::PathBuf;
fn main() {
- let zlib_ng_compat = env::var("CARGO_FEATURE_ZLIB_NG_COMPAT").is_ok();
-
- if !zlib_ng_compat && try_vcpkg() {
- return;
+ // This distribution contains reviewed security backports that an
+ // arbitrary system libssh2 may lack. Always compile this source tree.
+ println!("cargo:rerun-if-env-changed=LIBSSH2_SYS_USE_PKG_CONFIG");
+ if env::var_os("LIBSSH2_SYS_USE_PKG_CONFIG").is_some() {
+ panic!("This distribution requires its patched bundled libssh2; unset LIBSSH2_SYS_USE_PKG_CONFIG");
}
-
- // The system copy of libssh2 is not used by default because it
- // can lead to having two copies of libssl loaded at once.
- // See https://github.com/alexcrichton/ssh2-rs/pull/88
- println!("cargo:rerun-if-env-changed=LIBSSH2_SYS_USE_PKG_CONFIG");
- if env::var("LIBSSH2_SYS_USE_PKG_CONFIG").is_ok() {
- if zlib_ng_compat {
- panic!("LIBSSH2_SYS_USE_PKG_CONFIG set, but cannot use zlib-ng-compat with system libssh2");
- }
- if let Ok(lib) = pkg_config::find_library("libssh2") {
- for path in &lib.include_paths {
- println!("cargo:include={}", path.display());
- }
- return;
- }
- }
-
- if !Path::new("libssh2/.git").exists() {
- let _ = Command::new("git")
- .args(&["submodule", "update", "--init"])
- .status();
- }
+ println!("cargo:rerun-if-changed=libssh2/src");
+ println!("cargo:rerun-if-changed=libssh2/include");
+ println!("cargo:rerun-if-changed=libssh2/libssh2.pc.in");
let target = env::var("TARGET").unwrap();
let profile = env::var("PROFILE").unwrap();
@@ -201,45 +178,3 @@
}
}
-#[cfg(not(target_env = "msvc"))]
-fn try_vcpkg() -> bool {
- false
-}
-
-#[cfg(target_env = "msvc")]
-fn try_vcpkg() -> bool {
- vcpkg::Config::new()
- .emit_includes(true)
- .probe("libssh2")
- .map(|_| {
- // found libssh2 which depends on openssl and zlib
- vcpkg::Config::new()
- .lib_name("libssl")
- .lib_name("libcrypto")
- .probe("openssl")
- .or_else(|_| {
- // openssl 1.1 was not found, try openssl 1.0
- vcpkg::Config::new()
- .lib_name("libeay32")
- .lib_name("ssleay32")
- .probe("openssl")
- })
- .expect(
- "configured libssh2 from vcpkg but could not \
- find openssl libraries that it depends on",
- );
-
- vcpkg::Config::new()
- .lib_names("zlib", "zlib1")
- .probe("zlib")
- .expect(
- "configured libssh2 from vcpkg but could not \
- find the zlib library that it depends on",
- );
-
- println!("cargo:rustc-link-lib=crypt32");
- println!("cargo:rustc-link-lib=gdi32");
- println!("cargo:rustc-link-lib=user32");
- })
- .is_ok()
-}
--- a/libssh2/src/userauth.c
+++ b/libssh2/src/userauth.c
@@ -80,6 +80,12 @@
memset(&session->userauth_list_packet_requirev_state, 0,
sizeof(session->userauth_list_packet_requirev_state));
+ if(username_len > UINT32_MAX - 27) {
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "username_len out of bounds");
+ return NULL;
+ }
+
session->userauth_list_data_len = username_len + 27;
s = session->userauth_list_data =
@@ -307,6 +313,11 @@
* 40 = packet_type(1) + username_len(4) + service_len(4) +
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
* chgpwdbool(1) + password_len(4) */
+ if(username_len > UINT32_MAX - 40) {
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "username_len out of bounds");
+ }
+
session->userauth_pswd_data_len = username_len + 40;
session->userauth_pswd_data0 =
@@ -447,7 +458,7 @@
}
/* basic data_len + newpw_len(4) */
- if(username_len + password_len + 44 <= UINT_MAX) {
+ if(username_len <= UINT32_MAX - password_len - 44) {
session->userauth_pswd_data_len =
username_len + password_len + 44;
s = session->userauth_pswd_data =
--- a/libssh2/src/sftp.c
+++ b/libssh2/src/sftp.c
@@ -1279,6 +1279,7 @@
"got HANDLE FXOK"));
LIBSSH2_FREE(session, data);
+ data = NULL;
/* silly situation, but check for a HANDLE */
rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
--- a/libssh2/src/openssl.c
+++ b/libssh2/src/openssl.c
@@ -1042,13 +1042,15 @@
const int aadlen = (is_aesgcm && IS_FIRST(firstlast)) ? 4 : 0;
/* size of AT, if present */
const int authenticationtag = IS_LAST(firstlast) ? authlen : 0;
- /* length to encrypt */
- const int cryptlen = (unsigned int)blocksize - aadlen - authenticationtag;
+ unsigned int cryptlen; /* length to encrypt */
(void)algo;
- assert(blocksize <= sizeof(buf));
- assert(cryptlen >= 0);
+ if(blocksize > sizeof(buf) ||
+ blocksize < (size_t)(aadlen + authenticationtag))
+ return 1;
+
+ cryptlen = (unsigned int)blocksize - aadlen - authenticationtag;
#if LIBSSH2_AES_GCM
/* First block */
--- a/libssh2/src/transport.c
+++ b/libssh2/src/transport.c
@@ -242,6 +242,13 @@
unsigned char *decrypt_buffer;
int blocksize = session->remote.crypt->blocksize;
+ if(p->total_num < mac_len + 4 + (size_t)blocksize) {
+ LIBSSH2_FREE(session, p->payload);
+ p->payload = NULL;
+ return LIBSSH2_ERROR_DECRYPT;
+ }
+ decrypt_size = (ssize_t)(p->total_num - mac_len - 4);
+
rc = decrypt(session, p->payload + 4,
first_block, blocksize, FIRST_BLOCK);
if(rc) {
@@ -249,7 +256,6 @@
}
/* we need buffer for decrypt */
- decrypt_size = p->total_num - mac_len - 4;
decrypt_buffer = LIBSSH2_ALLOC(session, decrypt_size);
if(!decrypt_buffer) {
return LIBSSH2_ERROR_ALLOC;
--- a/libssh2/src/publickey.c
+++ b/libssh2/src/publickey.c
@@ -972,6 +972,8 @@
goto err_exit;
}
list = newlist;
+ memset(&list[keys], 0,
+ (max_keys - keys + 1) * sizeof(list[keys]));
}
if(pkey->version == 1) {
unsigned long comment_len;
@@ -988,6 +990,13 @@
}
if(comment_len) {
+ if(pkey->listFetch_s + comment_len >
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
list[keys].num_attrs = 1;
list[keys].attrs =
LIBSSH2_ALLOC(session,
@@ -1114,6 +1123,11 @@
}
if(list[keys].num_attrs) {
+ if(list[keys].num_attrs > 1024) {
+ _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Too many publickey attributes");
+ goto err_exit;
+ }
list[keys].attrs =
LIBSSH2_ALLOC(session,
list[keys].num_attrs *
@@ -1188,10 +1202,9 @@
}
/* To be FREEd in libssh2_publickey_list_free() */
list[keys].packet = pkey->listFetch_data;
+ pkey->listFetch_data = NULL;
+
keys++;
-
- list[keys].packet = NULL; /* Terminate the list */
- pkey->listFetch_data = NULL;
break;
default:
/* Unknown/Unexpected */
@@ -1230,11 +1243,13 @@
session = pkey->channel->session;
- while(p->packet) {
+ while(p->attrs || p->packet) {
if(p->attrs) {
LIBSSH2_FREE(session, p->attrs);
}
- LIBSSH2_FREE(session, p->packet);
+ if(p->packet) {
+ LIBSSH2_FREE(session, p->packet);
+ }
p++;
}
+56
View File
@@ -0,0 +1,56 @@
[
{
"name": "7598-256d04b60d80.patch",
"url": "https://github.com/libssh2/libssh2/commit/256d04b60d80bf1190e96b0ad1e91b2174d744b1.patch",
"commit": "256d04b60d80bf1190e96b0ad1e91b2174d744b1",
"sha256": "fd4775228fe04a11532043355099fe2643993aae4fb63576620b1941f9a80645"
},
{
"name": "66032-5e4776146552.patch",
"url": "https://github.com/libssh2/libssh2/commit/5e4776146552d898b9c0e1b313cd093fa8dc92d0.patch",
"commit": "5e4776146552d898b9c0e1b313cd093fa8dc92d0",
"sha256": "a70ff256ce24fc5e4144fcc4409a5874c397e1f9e1b1d437120e4be3f5fc051d"
},
{
"name": "66033-a2ed82d40964.patch",
"url": "https://github.com/libssh2/libssh2/commit/a2ed82d40964bbc0d64cd717aa0a5a892117d2e6.patch",
"commit": "a2ed82d40964bbc0d64cd717aa0a5a892117d2e6",
"sha256": "f59ff6d6575ec8f17af41825aac4dc6c8ddcdd6909dc6ae3a535fa13dba8a290"
},
{
"name": "66034-a13bb6c773f0.patch",
"url": "https://github.com/libssh2/libssh2/commit/a13bb6c773f0d55ad1628cede57e99803cd898d9.patch",
"commit": "a13bb6c773f0d55ad1628cede57e99803cd898d9",
"sha256": "896ff800992af462519f0b2d2f47a84f5096728f27c9faf36b1676eaa9c6620f"
},
{
"name": "66035-42e33d81577e.patch",
"url": "https://github.com/libssh2/libssh2/commit/42e33d81577ed4b95d4b4f6f845e5ee8efe5eeb4.patch",
"commit": "42e33d81577ed4b95d4b4f6f845e5ee8efe5eeb4",
"sha256": "0422c11e22df21dc8154fa0aeb812157d0798d990bd9ab2cd05844dc21653693"
},
{
"name": "58050-34497525929b.patch",
"url": "https://github.com/libssh2/libssh2/commit/34497525929b9a47f03dfb81887ac896202b7e12.patch",
"commit": "34497525929b9a47f03dfb81887ac896202b7e12",
"sha256": "9cb033e07004a755675e2095eb7f05ebeaafa70b0920a1fdb8f6ad23498047d9"
},
{
"name": "58051-a9758da45a52.patch",
"url": "https://github.com/libssh2/libssh2/commit/a9758da45a52bc8c630ec9493804d0c6ea30b24a.patch",
"commit": "a9758da45a52bc8c630ec9493804d0c6ea30b24a",
"sha256": "0aee020bbc88acd2a3d828f1c85861f9f5a36204c07543cddc0abd68d4b5ed0a"
},
{
"name": "publickey-leak-c2f1a3a21b4c.patch",
"url": "https://github.com/libssh2/libssh2/commit/c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a.patch",
"commit": "c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a",
"sha256": "8d0e86562978b93406b85531e1f391d2f03c0387c057fb8b3a6e14b228aabdb5"
},
{
"name": "publickey-terminator-ad16eb112f4a.patch",
"url": "https://github.com/libssh2/libssh2/commit/ad16eb112f4a9591acdf5f6f2981328613e6b626.patch",
"commit": "ad16eb112f4a9591acdf5f6f2981328613e6b626",
"sha256": "6464c70d8d34249e5d0a0969136f35c1a2a0e3d0424c2889c5b8e6fbe874f232"
}
]
@@ -0,0 +1,35 @@
From 34497525929b9a47f03dfb81887ac896202b7e12 Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Sun, 28 Jun 2026 02:12:52 +0200
Subject: [PATCH] publickey: fix potential multiplication overflow in 32-bit
`libssh2_publickey_list_fetch()`
Cap list size at 1024 elements.
Reported-and-initial-patch-by: Mateusz Gierblinski
Reported-and-initial-patch-by: Behzod Abdullayev
Reported-by: Sharique Raza
Follow-up to e15f5d97a04cc676ce117dd324fef85b046207a9
Closes #2128
---
src/publickey.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/src/publickey.c b/src/publickey.c
index a0d3100005..3a6dd116d2 100644
--- a/src/publickey.c
+++ b/src/publickey.c
@@ -1048,6 +1048,11 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
}
if(list[keys].num_attrs) {
+ if(list[keys].num_attrs > 1024) {
+ ssh2_err(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Too many publickey attributes");
+ goto err_exit;
+ }
list[keys].attrs =
SSH2_ALLOC(session,
list[keys].num_attrs *
@@ -0,0 +1,28 @@
From a9758da45a52bc8c630ec9493804d0c6ea30b24a Mon Sep 17 00:00:00 2001
From: Viktor Szakats <vszakats@users.noreply.github.com>
Date: Mon, 29 Jun 2026 19:12:21 +0200
Subject: [PATCH] publickey: fix potential arbitrary free in
`libssh2_publickey_list_fetch()` (#2127)
Due to uninitialized list entry.
Reported-and-patch-by: Behzod Abdullayev
Reported-by: Sharique Raza
Follow-up to e15f5d97a04cc676ce117dd324fef85b046207a9
---
src/publickey.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/publickey.c b/src/publickey.c
index b7f384310e..a0d3100005 100644
--- a/src/publickey.c
+++ b/src/publickey.c
@@ -905,6 +905,7 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
goto err_exit;
}
list = newlist;
+ memset(&list[keys], 0, sizeof(list[keys]));
}
if(pkey->version == 1) {
unsigned long comment_len;
@@ -0,0 +1,25 @@
From 5e4776146552d898b9c0e1b313cd093fa8dc92d0 Mon Sep 17 00:00:00 2001
From: Will Cosgrove <will@panic.com>
Date: Thu, 2 Jul 2026 11:00:23 -0700
Subject: [PATCH] Prevent dangling pointer by nullifying data (#2180)
Set data to NULL after freeing it to avoid dangling pointer. fixes
GHSA-px3w-7g75-hg7w.
Credit: VladimirEliTokarev
---
src/sftp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/sftp.c b/src/sftp.c
index ec3a8ae18a..842eb6ea51 100644
--- a/src/sftp.c
+++ b/src/sftp.c
@@ -1259,6 +1259,7 @@ static LIBSSH2_SFTP_HANDLE *sftp_open(LIBSSH2_SFTP *sftp,
ssh2_deb((session, LIBSSH2_TRACE_SFTP, "got HANDLE FXOK"));
SSH2_FREE(session, data);
+ data = NULL;
/* silly situation, but check for a HANDLE */
rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
@@ -0,0 +1,41 @@
From a2ed82d40964bbc0d64cd717aa0a5a892117d2e6 Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Thu, 23 Jul 2026 10:32:04 +0200
Subject: [PATCH] openssl: fix potential OOB read/write with AES-GCM in
`ssh2_cipher_crypt()`
By applying two bounds checks to non-debug builds.
Reported-by: Vladimir Eli Tokarev
Fixes GHSA-c4f7-cvfc-33j7
Follow-up to 3c953c05d67eb1ebcfd3316f279f12c4b1d600b4 #797
Closes #2401
---
src/openssl.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/openssl.c b/src/openssl.c
index 6a38b55b91..31ef6db371 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -945,13 +945,15 @@ int ssh2_cipher_crypt(ssh2_cipher_ctx *ctx, SSH2_CIPHER_T(algo), int encrypt,
const int aadlen = (is_aesgcm && IS_FIRST(firstlast)) ? 4 : 0;
/* size of AT, if present */
const int authenticationtag = IS_LAST(firstlast) ? authlen : 0;
- /* length to encrypt */
- const int cryptlen = (unsigned int)blocksize - aadlen - authenticationtag;
+ unsigned int cryptlen; /* length to encrypt */
(void)algo;
- assert(blocksize <= sizeof(buf));
- assert(cryptlen >= 0);
+ if(blocksize > sizeof(buf) ||
+ blocksize < (size_t)(aadlen + authenticationtag))
+ return 1;
+
+ cryptlen = (unsigned int)blocksize - aadlen - authenticationtag;
#if LIBSSH2_AES_GCM
/* First block */
@@ -0,0 +1,32 @@
From a13bb6c773f0d55ad1628cede57e99803cd898d9 Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Sat, 4 Jul 2026 11:19:49 +0200
Subject: [PATCH] publickey: fix potential OOB read in
`libssh2_publickey_list_fetch()`
Reported-by: Vladimir Eli Tokarev
Fixes GHSA-w6g9-cpfp-22gc
Closes #2202
---
src/publickey.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/publickey.c b/src/publickey.c
index 3254ad91e7..ec263c2287 100644
--- a/src/publickey.c
+++ b/src/publickey.c
@@ -929,6 +929,13 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
}
if(comment_len) {
+ if(pkey->listFetch_s + comment_len >
+ pkey->listFetch_data + pkey->listFetch_data_len) {
+ ssh2_err(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "ListFetch data too short");
+ goto err_exit;
+ }
+
list[keys].num_attrs = 1;
list[keys].attrs =
SSH2_ALLOC(session,
@@ -0,0 +1,38 @@
From 42e33d81577ed4b95d4b4f6f845e5ee8efe5eeb4 Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Fri, 3 Jul 2026 18:22:55 +0200
Subject: [PATCH] transport: fix potential heap overflow on ETM decrypt
Reported-by: Vladimir Eli Tokarev
Fixes GHSA-6c79-444r-wx26
Closes #2198
---
src/transport.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/transport.c b/src/transport.c
index 6f05a0fdd4..94c66745c2 100644
--- a/src/transport.c
+++ b/src/transport.c
@@ -237,6 +237,12 @@ static int transport_fullpacket(LIBSSH2_SESSION *session,
unsigned char *decrypt_buffer;
int blocksize = session->remote.crypt->blocksize;
+ if(p->total_num < mac_len + 4 + (size_t)blocksize) {
+ SSH2_SAFEFREE(session, p->payload);
+ return LIBSSH2_ERROR_DECRYPT;
+ }
+ decrypt_size = (ssize_t)(p->total_num - mac_len - 4);
+
first_block[0] = 0;
rc = transport_decrypt(session, p->payload + 4,
@@ -245,7 +251,6 @@ static int transport_fullpacket(LIBSSH2_SESSION *session,
return rc;
/* we need buffer for decrypt */
- decrypt_size = p->total_num - mac_len - 4;
decrypt_buffer = SSH2_ALLOC(session, decrypt_size);
if(!decrypt_buffer)
return LIBSSH2_ERROR_ALLOC;
@@ -0,0 +1,52 @@
From 256d04b60d80bf1190e96b0ad1e91b2174d744b1 Mon Sep 17 00:00:00 2001
From: Will Cosgrove <will@panic.com>
Date: Mon, 13 Apr 2026 11:18:25 -0700
Subject: [PATCH] userauth.c: username_len bounds checking (#1858)
Return errors when username_len will exceed bounds, fix existing bounds
check.
Credit:
[dapickle](https://github.com/dapickle)
---
src/userauth.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/userauth.c b/src/userauth.c
index f8e02651c4..43d9ab9b9d 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
memset(&session->userauth_list_packet_requirev_state, 0,
sizeof(session->userauth_list_packet_requirev_state));
+ if(username_len > UINT32_MAX - 27) {
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "username_len out of bounds");
+ return NULL;
+ }
+
session->userauth_list_data_len = username_len + 27;
if(session->userauth_list_data) {
@@ -316,6 +322,11 @@ userauth_password(LIBSSH2_SESSION *session,
* 40 = packet_type(1) + username_len(4) + service_len(4) +
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
* chgpwdbool(1) + password_len(4) */
+ if(username_len > UINT32_MAX - 40) {
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "username_len out of bounds");
+ }
+
session->userauth_pswd_data_len = username_len + 40;
session->userauth_pswd_data0 =
@@ -456,7 +467,7 @@ userauth_password(LIBSSH2_SESSION *session,
}
/* basic data_len + newpw_len(4) */
- if(username_len + password_len + 44 <= UINT_MAX) {
+ if(username_len <= UINT32_MAX - password_len - 44) {
session->userauth_pswd_data_len =
username_len + password_len + 44;
s = session->userauth_pswd_data =
@@ -0,0 +1,61 @@
From c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a Mon Sep 17 00:00:00 2001
From: Viktor Szakats <commit@vsz.me>
Date: Tue, 21 Jul 2026 17:51:42 +0200
Subject: [PATCH] publickey: fix `attr` memleak on error in
`libssh2_publickey_list_fetch()`
In case of error, the last touched list entry could have the `attr`
field assigned to an allocated buffer, while still having NULL `packet`.
This made the destructore skip this entry and leak `attr`.
Fix by initializing all new list entries to zero and freeing entries
with either `attr` or `packet` set, up to entry where both are NULL.
Reported-by: hyunjiHong on github
Fixes #2368
Closes #2380
---
src/publickey.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/publickey.c b/src/publickey.c
index 43b8123e62..7db71a4249 100644
--- a/src/publickey.c
+++ b/src/publickey.c
@@ -941,7 +941,7 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
goto err_exit;
}
list = newlist;
- memset(&list[keys], 0, sizeof(list[keys]));
+ memset(&list[keys], 0, (max_keys - keys) * sizeof(list[keys]));
}
if(pkey->version == 1) {
unsigned long comment_len;
@@ -1180,10 +1180,9 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
}
/* To be FREEd in libssh2_publickey_list_free() */
list[keys].packet = pkey->listFetch_data;
- keys++;
-
- list[keys].packet = NULL; /* Terminate the list */
pkey->listFetch_data = NULL;
+
+ keys++;
break;
default:
/* Unknown/Unexpected */
@@ -1217,10 +1216,11 @@ void libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
session = pkey->channel->session;
- while(p->packet) {
+ while(p->attrs || p->packet) {
if(p->attrs)
SSH2_FREE(session, p->attrs);
- SSH2_FREE(session, p->packet);
+ if(p->packet)
+ SSH2_FREE(session, p->packet);
p++;
}
@@ -0,0 +1,32 @@
From ad16eb112f4a9591acdf5f6f2981328613e6b626 Mon Sep 17 00:00:00 2001
From: "RELAUNCH DEPT." <215028820+ceodaradigu@users.noreply.github.com>
Date: Thu, 3 Sep 2026 15:51:41 +0200
Subject: [PATCH] publickey: initialize the list terminator
The allocation reserves `max_keys + 1` entries, while the initialization
after growth currently covers only `max_keys - keys` entries. Include
the additional reserved entry in that initialization so the list
terminator is initialized at exact capacity boundaries.
Follow-up to c2f1a3a21b4c922cbcf50bf7c009b740141a1e7a #2380
Ref: https://github.com/libssh2/libssh2/pull/2380#pullrequestreview-4746725158
Closes #2579
---
src/publickey.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/publickey.c b/src/publickey.c
index d49ec48d38..36a60c141a 100644
--- a/src/publickey.c
+++ b/src/publickey.c
@@ -941,7 +941,8 @@ int libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
goto err_exit;
}
list = newlist;
- memset(&list[keys], 0, (max_keys - keys) * sizeof(list[keys]));
+ memset(&list[keys], 0,
+ (max_keys - keys + 1) * sizeof(list[keys]));
}
if(pkey->version == 1) {
unsigned long comment_len;
+15
View File
@@ -0,0 +1,15 @@
#!/bin/sh
# Run against the exact bundled libssh2 archive produced by the Cargo build.
set -eu
if [ "$#" -ne 1 ] || [ ! -f "$1" ]; then
echo "Usage: $0 /absolute/path/to/target/.../out/build/libssh2.a" >&2
exit 2
fi
test_root=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
test_temp=$(mktemp -d)
trap 'rm -rf "$test_temp"' EXIT HUP INT TERM
"${CC:-cc}" -std=c99 -O2 -DNDEBUG -Wall -Wextra -Werror \
-I"$test_root/../libssh2/include" \
"$test_root/security-regression.c" "$1" -lssl -lcrypto -lz \
-o "$test_temp/security-regression"
"$test_temp/security-regression"
+73
View File
@@ -0,0 +1,73 @@
/* Targeted runtime checks for the vendored libssh2 security backports.
* SPDX-License-Identifier: MIT
* This program deliberately supplies boundary lengths, without any network.
*/
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include "libssh2.h"
/* Internal function from the statically linked, patched OpenSSL backend. */
extern int _libssh2_cipher_crypt(EVP_CIPHER_CTX **ctx,
const EVP_CIPHER *(*algo)(void),
int encrypt, unsigned char *block,
size_t blocksize, int firstlast);
static int check_crypto_bounds(void)
{
unsigned char buffer[EVP_MAX_BLOCK_LENGTH + 32];
unsigned char original[sizeof(buffer)];
size_t length;
memset(buffer, 0xa5, sizeof(buffer));
memcpy(original, buffer, sizeof(buffer));
/* A complete AES-GCM block requires 4 bytes of AAD plus a 16-byte tag.
* A null context makes an accidental call into OpenSSL fail immediately;
* a correct bounds check rejects these inputs before touching it. */
for(length = 0; length < 20; length++) {
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
length, 3) != 1)
return 1;
}
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
sizeof(buffer), 3) != 1)
return 1;
if(_libssh2_cipher_crypt(NULL, EVP_aes_128_gcm, 0, buffer,
SIZE_MAX, 3) != 1)
return 1;
return memcmp(buffer, original, sizeof(buffer)) != 0;
}
static int check_username_bounds(void)
{
LIBSSH2_SESSION *session = libssh2_session_init();
int failure = 0;
if(!session)
return 1;
if(libssh2_userauth_list(session, "x", UINT_MAX) != NULL ||
libssh2_session_last_errno(session) != LIBSSH2_ERROR_PROTO)
failure = 1;
if(libssh2_userauth_password_ex(session, "x", UINT_MAX, "p", 1,
NULL) != LIBSSH2_ERROR_PROTO)
failure = 1;
libssh2_session_free(session);
return failure;
}
int main(void)
{
int failure;
if(libssh2_init(0) != 0)
return 1;
failure = check_crypto_bounds() | check_username_bounds();
libssh2_exit();
if(failure) {
fputs("libssh2 security boundary regression failed\n", stderr);
return 1;
}
puts("libssh2 security boundaries: AES-GCM short/oversized blocks and overflowing username lengths PASS");
return 0;
}