Compare commits
51 Commits
zig-3.8.1
...
9679f074d2
| Author | SHA1 | Date | |
|---|---|---|---|
|
9679f074d2
|
|||
|
c673c25fc9
|
|||
|
7940593eb8
|
|||
|
e68d5f484b
|
|||
|
e2db88c634
|
|||
|
c06f268a16
|
|||
|
9f96f4f711
|
|||
|
e85e51738d
|
|||
|
bbf2737c2b
|
|||
|
|
2553853c96 | ||
|
|
79fe4adf48 | ||
|
|
f075fe34bf | ||
|
|
2652fb2f1e | ||
|
|
ef83583d88 | ||
|
|
1a5be425a9 | ||
|
|
18f5064a9d | ||
|
|
f06374e731 | ||
|
|
60f4156d76 | ||
|
|
eed367e19c | ||
|
|
124e0192c8 | ||
|
|
548b3d0485 | ||
|
|
9bca15bad5 | ||
|
|
dd1d96f643 | ||
|
|
98a5122bc6 | ||
|
|
1fd73818df | ||
|
|
ce79c96489 | ||
|
|
c4bb6b79ea | ||
|
|
8048941622 | ||
|
|
321fa56d9a | ||
|
|
01e3b10f50 | ||
|
|
fca20b23d6 | ||
|
|
fe731f3db0 | ||
|
|
5319ff3b17 | ||
|
|
04fa997f54 | ||
|
|
b112e37275 | ||
|
|
8e4af3b18b | ||
|
|
1defa3baa5 | ||
|
|
c923880fb9 | ||
|
|
e56ec2ae95 | ||
|
|
70db97f5a6 | ||
|
|
f3c946b03f | ||
|
|
dbf729b46e | ||
|
|
9e5971d828 | ||
|
|
ef5867b4e6 | ||
|
|
c90e80d21e | ||
|
|
4663543082 | ||
|
|
ccaec87950 | ||
|
|
34f45b6cd7 | ||
|
|
70688874f8 | ||
|
|
a6bd25d3bd | ||
|
|
8fa9337f65 |
10
.github/rust-openssl.patch
vendored
10
.github/rust-openssl.patch
vendored
@@ -1,13 +1,13 @@
|
||||
diff --git a/openssl-sys/build/main.rs b/openssl-sys/build/main.rs
|
||||
index 21ccf3d0..1cf2d184 100644
|
||||
index 82013b6c..2974abed 100644
|
||||
--- a/openssl-sys/build/main.rs
|
||||
+++ b/openssl-sys/build/main.rs
|
||||
@@ -272,7 +272,7 @@ See rust-openssl documentation for more information:
|
||||
(3, 7, 0) => ('3', '7', '0'),
|
||||
@@ -273,7 +273,7 @@ See rust-openssl documentation for more information:
|
||||
(3, 7, 1) => ('3', '7', '1'),
|
||||
(3, 7, _) => ('3', '7', 'x'),
|
||||
- (3, 8, 0) => ('3', '8', '0'),
|
||||
+ (3, 8, _) => ('3', '8', '0'),
|
||||
(3, 8, 0) => ('3', '8', '0'),
|
||||
- (3, 8, 1) => ('3', '8', '1'),
|
||||
+ (3, 8, _) => ('3', '8', 'x'),
|
||||
_ => version_error(),
|
||||
};
|
||||
|
||||
|
||||
@@ -63,11 +63,7 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
endif()
|
||||
|
||||
# Enable asserts regardless of build type
|
||||
if(MSVC)
|
||||
add_definitions(/UNDEBUG)
|
||||
else()
|
||||
add_definitions(-UNDEBUG)
|
||||
endif()
|
||||
add_definitions(-UNDEBUG)
|
||||
|
||||
set(BUILD_NC true)
|
||||
|
||||
@@ -152,17 +148,17 @@ if(MSVC)
|
||||
"C4100" # 'identifier' : unreferenced formal parameter
|
||||
"C4127" # conditional expression is constant
|
||||
"C4146" # unary minus operator applied to unsigned type,
|
||||
# result still unsigned
|
||||
# result still unsigned
|
||||
"C4244" # 'argument' : conversion from 'type1' to 'type2',
|
||||
# possible loss of data
|
||||
# possible loss of data
|
||||
"C4245" # 'conversion' : conversion from 'type1' to 'type2',
|
||||
# signed/unsigned mismatch
|
||||
# signed/unsigned mismatch
|
||||
"C4267" # 'var' : conversion from 'size_t' to 'type',
|
||||
# possible loss of data
|
||||
# possible loss of data
|
||||
"C4389" # 'operator' : signed/unsigned mismatch
|
||||
"C4706" # assignment within conditional expression
|
||||
"C4996" # The POSIX name for this item is deprecated.
|
||||
# Instead, use the ISO C and C++ conformant name
|
||||
# Instead, use the ISO C and C++ conformant name
|
||||
)
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
|
||||
add_definitions(-D_CRT_SUPPRESS_RESTRICT)
|
||||
@@ -333,32 +329,32 @@ endif()
|
||||
# single architecture work on macOS at least.
|
||||
#
|
||||
# Don't set CMAKE_OSX_ARCHITECTURES to more than a single value for now.
|
||||
if(APPLE)
|
||||
if(APPLE AND (NOT CMAKE_OSX_ARCHITECTURES STREQUAL ""))
|
||||
set(CMAKE_SYSTEM_PROCESSOR "${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif()
|
||||
|
||||
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(aarch64|arm64)")
|
||||
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(aarch64|arm64|ARM64)")
|
||||
set(HOST_AARCH64 true)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "arm")
|
||||
set(HOST_ARM true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS" AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386")
|
||||
set(HOST_X86_64 true)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64)")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64|AMD64)")
|
||||
set(HOST_X86_64 true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "[i?86|x86]")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(i[3-6]86|[xX]86)")
|
||||
set(ENABLE_ASM false)
|
||||
set(HOST_I386 true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "mips64")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "mips64")
|
||||
set(HOST_MIPS64 true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "mips")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "mips")
|
||||
set(HOST_MIPS true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "powerpc")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "powerpc")
|
||||
set(HOST_POWERPC true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "ppc64")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "ppc64")
|
||||
set(HOST_PPC64 true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "riscv64")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "riscv64")
|
||||
set(HOST_RISCV64 true)
|
||||
elseif("${CMAKE_SYSTEM_NAME}" MATCHES "sparc64")
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "sparc64")
|
||||
set(HOST_SPARC64 true)
|
||||
else()
|
||||
set(ENABLE_ASM false)
|
||||
@@ -405,7 +401,6 @@ if(SIZEOF_TIME_T STREQUAL "4")
|
||||
message(WARNING " ** Warning, this system is unable to represent times past 2038\n"
|
||||
" ** It will behave incorrectly when handling valid RFC5280 dates")
|
||||
endif()
|
||||
add_definitions(-DSIZEOF_TIME_T=${SIZEOF_TIME_T})
|
||||
|
||||
set(OPENSSL_LIBS ssl crypto ${PLATFORM_LIBS})
|
||||
set(LIBTLS_LIBS tls ${PLATFORM_LIBS})
|
||||
@@ -473,8 +468,8 @@ if(ENABLE_LIBRESSL_INSTALL)
|
||||
INSTALL_DESTINATION "${LIBRESSL_INSTALL_CMAKEDIR}"
|
||||
)
|
||||
install(FILES
|
||||
"${CMAKE_BINARY_DIR}/install-config/LibreSSLConfig.cmake"
|
||||
"${CMAKE_BINARY_DIR}/LibreSSLConfigVersion.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/install-config/LibreSSLConfig.cmake"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/LibreSSLConfigVersion.cmake"
|
||||
DESTINATION "${LIBRESSL_INSTALL_CMAKEDIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
43
ChangeLog
43
ChangeLog
@@ -28,7 +28,48 @@ history is also available from Git.
|
||||
|
||||
LibreSSL Portable Release Notes:
|
||||
|
||||
3.8.1 - In development
|
||||
3.9.0 - In development
|
||||
|
||||
* Portable changes
|
||||
* Internal improvements
|
||||
* Documentation improvements
|
||||
* Testing and proactive security
|
||||
* Bug fixes
|
||||
- Fixed aliasing issues in BN_mod_exp_simple() and BN_mod_exp_recp()
|
||||
|
||||
3.8.2 - Stable release
|
||||
|
||||
* Portable changes
|
||||
- Fixed processor detection for CMake targets.
|
||||
Thanks to @jiegec from github.
|
||||
- Enabled building oscpcheck with MSVC.
|
||||
Thanks to @FtZPetruska from github.
|
||||
- Improve CMake package detection and installation.
|
||||
Thanks to @mark-groundctl from github.
|
||||
- Fixed assembly optimizations on x64 Windows targets.
|
||||
- Allow disabling warnings about WINCRYPT overrides.
|
||||
- Use system arc4random on FreeBSD 12 and newer.
|
||||
* Documentation improvements
|
||||
- Documented the RFC 3779 API.
|
||||
* Compatibility changes
|
||||
- Restrict the RFC 3779 code to IPv4 and IPv6. It was not written
|
||||
to be able to deal with anything else.
|
||||
- Fixed EVP_CIPHER_CTX_iv_length() to return what was set with
|
||||
EVP_CTRL_AEAD_SET_IVLEN or one of its aliases.
|
||||
* Bug fixes
|
||||
- Fixed EVP_PKEY_get{0,1}_RSA for RSA-PSS.
|
||||
- Plug a potential memory leak in ASN1_TIME_normalize().
|
||||
- Avoid memory leak in EVP_CipherInit().
|
||||
- Redirect EVP_PKEY_get1_* through their get0 siblings.
|
||||
- Fixed a use of uninitialized in i2r_IPAddrBlocks().
|
||||
- Rewrote CMS_SignerInfo_{sign,verify}().
|
||||
- Further cleanup and refactoring in the EC code.
|
||||
- Allow IP addresses to be specified in a URI.
|
||||
- Fixed a copy-paste error in ASN1_TIME_compare() that could lead
|
||||
to two UTCTimes or two GeneralizedTimes incorrectly being compared
|
||||
as equal.
|
||||
|
||||
3.8.1 - Development release
|
||||
|
||||
* Portable changes
|
||||
- Applications bundled as part of the LibreSSL package internally,
|
||||
|
||||
@@ -6,16 +6,19 @@ set_and_check(LIBRESSL_INCLUDE_DIR @PACKAGE_INCLUDE_DIRECTORY@)
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/LibreSSL-Crypto.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/LibreSSL-Crypto.cmake")
|
||||
set(LIBRESSL_CRYPTO_LIBRARY LibreSSL::Crypto)
|
||||
set(LibreSSL_Crypto_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/LibreSSL-SSL.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/LibreSSL-SSL.cmake")
|
||||
set(LIBRESSL_SSL_LIBRARY LibreSSL::SSL)
|
||||
set(LibreSSL_SSL_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/LibreSSL-TLS.cmake")
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/LibreSSL-TLS.cmake")
|
||||
set(LIBRESSL_TLS_LIBRARY LibreSSL::TLS)
|
||||
set(LibreSSL_TLS_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
set(LIBRESSL_LIBRARIES
|
||||
@@ -24,10 +27,10 @@ set(LIBRESSL_LIBRARIES
|
||||
${LIBRESSL_TLS_LIBRARY}
|
||||
)
|
||||
|
||||
check_required_components(
|
||||
Crypto
|
||||
SSL
|
||||
TLS
|
||||
)
|
||||
check_required_components(LibreSSL)
|
||||
|
||||
set(LIBRESSL_FOUND TRUE)
|
||||
if(DEFINED LibreSSL_FOUND)
|
||||
set(LIBRESSL_FOUND ${LibreSSL_FOUND})
|
||||
else()
|
||||
set(LIBRESSL_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
@@ -1 +1 @@
|
||||
master
|
||||
OPENBSD_7_4
|
||||
|
||||
@@ -4,13 +4,13 @@ This is a somewhat hacky port of the LibreSSL build system to Zig. It builds Lib
|
||||
|
||||
Notes:
|
||||
|
||||
1. In order for this to work, `.\update.sh` must have first been run to bring in the LibreSSL OpenBSD sources. (Or, if you trust me, you may use the `zig-3.8.1` branch which has the upstream sources committed to the repository, for ease of use with the Zig package manager).
|
||||
1. In order for this to work, `.\update.sh` must have first been run to bring in the LibreSSL OpenBSD sources. (Or, if you trust me, you may use the `zig-3.8.2` branch which has the upstream sources committed to the repository, for ease of use with the Zig package manager).
|
||||
|
||||
2. I don't know if this causes LibreSSL to be compiled in a way that Compromises Its Cryptographic Integrity. Hopefully it is not even possible to do such a thing in the first place. But I am not an expert, and I ain't looking to port the tests.
|
||||
|
||||
3. This does not (currently) compile the assembly routines, only the C versions, which may cause reduced performance on some platforms.
|
||||
|
||||
4. Only the "big 3" platforms are supported (namely: macOS, Linux, and Windows), and they may be poorly supported, at that. I can cross compile to them from my computer but I have not tried natively compiling on all platforms.
|
||||
4. Only the "big 3" platforms are supported (namely: macOS, Linux, and Windows). Native and cross-compilation appears to work on modern versions of all three, but this has not been exhaustively tested.
|
||||
|
||||
5. Why LibreSSL? It has a CMake-based build system rather than the insane hand-rolled perl mess that OpenSSL does, so it was very straightforward to follow the build process for the purposes of porting it. In theory, its OpenSSL compatibility layer makes it possible to use with a variety of other programs that want to link OpenSSL.
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/* $OpenBSD: atomicio.c,v 1.11 2012/12/04 02:24:47 deraadt Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 2005 Anil Madhavapeddy. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "atomicio.h"
|
||||
|
||||
/*
|
||||
* ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t
|
||||
atomicio(ssize_t (*f) (int, void *, size_t), int fd, void *_s, size_t n)
|
||||
{
|
||||
char *s = _s;
|
||||
size_t pos = 0;
|
||||
ssize_t res;
|
||||
struct pollfd pfd;
|
||||
|
||||
pfd.fd = fd;
|
||||
pfd.events = f == read ? POLLIN : POLLOUT;
|
||||
while (n > pos) {
|
||||
res = (f) (fd, s + pos, n - pos);
|
||||
switch (res) {
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if ((errno == EAGAIN) || (errno == ENOBUFS)) {
|
||||
(void)poll(&pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
case 0:
|
||||
errno = EPIPE;
|
||||
return pos;
|
||||
default:
|
||||
pos += (size_t)res;
|
||||
}
|
||||
}
|
||||
return (pos);
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* $OpenBSD: atomicio.h,v 1.2 2007/09/07 14:50:44 tobias Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Damien Miller. All rights reserved.
|
||||
* Copyright (c) 1995,1999 Theo de Raadt. All rights reserved.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _ATOMICIO_H
|
||||
#define _ATOMICIO_H
|
||||
|
||||
/*
|
||||
* Ensure all of data on socket comes through. f==read || f==vwrite
|
||||
*/
|
||||
size_t atomicio(ssize_t (*)(int, void *, size_t), int, void *, size_t);
|
||||
|
||||
#define vwrite (ssize_t (*)(int, void *, size_t))write
|
||||
|
||||
#endif /* _ATOMICIO_H */
|
||||
@@ -1,307 +0,0 @@
|
||||
/* $OpenBSD: base64.c,v 1.15 2021/10/25 14:41:09 jca Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
-------------------------------------------------
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_ntop(unsigned char const *src, size_t srclength, char *target,
|
||||
size_t targsize)
|
||||
{
|
||||
size_t datalength = 0;
|
||||
unsigned char input[3];
|
||||
unsigned char output[4];
|
||||
int i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0 != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
if (srclength == 1)
|
||||
target[datalength++] = Pad64;
|
||||
else
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0'; /* Returned value doesn't count \0. */
|
||||
return (datalength);
|
||||
}
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_pton(char const *src, unsigned char *target, size_t targsize)
|
||||
{
|
||||
int tarindex, state, ch;
|
||||
unsigned char nextbyte;
|
||||
char *pos;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while ((ch = (unsigned char)*src++) != '\0') {
|
||||
if (isspace(ch)) /* Skip whitespace anywhere. */
|
||||
continue;
|
||||
|
||||
if (ch == Pad64)
|
||||
break;
|
||||
|
||||
pos = strchr(Base64, ch);
|
||||
if (pos == 0) /* A non-base64 character. */
|
||||
return (-1);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = (pos - Base64) << 2;
|
||||
}
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 4;
|
||||
nextbyte = ((pos - Base64) & 0x0f) << 4;
|
||||
if (tarindex + 1 < targsize)
|
||||
target[tarindex+1] = nextbyte;
|
||||
else if (nextbyte)
|
||||
return (-1);
|
||||
}
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 2;
|
||||
nextbyte = ((pos - Base64) & 0x03) << 6;
|
||||
if (tarindex + 1 < targsize)
|
||||
target[tarindex+1] = nextbyte;
|
||||
else if (nextbyte)
|
||||
return (-1);
|
||||
}
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if (tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64);
|
||||
}
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = (unsigned char)*src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for (; ch != '\0'; ch = (unsigned char)*src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = (unsigned char)*src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for (; ch != '\0'; ch = (unsigned char)*src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target && tarindex < targsize &&
|
||||
target[tarindex] != 0)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
1910
apps/nc/netcat.c
1910
apps/nc/netcat.c
File diff suppressed because it is too large
Load Diff
400
apps/nc/socks.c
400
apps/nc/socks.c
@@ -1,400 +0,0 @@
|
||||
/* $OpenBSD: socks.c,v 1.31 2022/06/08 20:20:26 djm Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Niklas Hallqvist. All rights reserved.
|
||||
* Copyright (c) 2004, 2005 Damien Miller. 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <resolv.h>
|
||||
#include <readpassphrase.h>
|
||||
#include "atomicio.h"
|
||||
|
||||
#define SOCKS_PORT "1080"
|
||||
#define HTTP_PROXY_PORT "3128"
|
||||
#define HTTP_MAXHDRS 64
|
||||
#define SOCKS_V5 5
|
||||
#define SOCKS_V4 4
|
||||
#define SOCKS_NOAUTH 0
|
||||
#define SOCKS_NOMETHOD 0xff
|
||||
#define SOCKS_CONNECT 1
|
||||
#define SOCKS_IPV4 1
|
||||
#define SOCKS_DOMAIN 3
|
||||
#define SOCKS_IPV6 4
|
||||
|
||||
int remote_connect(const char *, const char *, struct addrinfo, char *);
|
||||
int socks_connect(const char *, const char *, struct addrinfo,
|
||||
const char *, const char *, struct addrinfo, int,
|
||||
const char *);
|
||||
|
||||
static int
|
||||
decode_addrport(const char *h, const char *p, struct sockaddr *addr,
|
||||
socklen_t addrlen, int v4only, int numeric)
|
||||
{
|
||||
int r;
|
||||
struct addrinfo hints, *res;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = v4only ? PF_INET : PF_UNSPEC;
|
||||
hints.ai_flags = numeric ? AI_NUMERICHOST : 0;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
r = getaddrinfo(h, p, &hints, &res);
|
||||
/* Don't fatal when attempting to convert a numeric address */
|
||||
if (r != 0) {
|
||||
if (!numeric) {
|
||||
errx(1, "getaddrinfo(\"%.64s\", \"%.64s\"): %s", h, p,
|
||||
gai_strerror(r));
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
if (addrlen < res->ai_addrlen) {
|
||||
freeaddrinfo(res);
|
||||
errx(1, "internal error: addrlen < res->ai_addrlen");
|
||||
}
|
||||
memcpy(addr, res->ai_addr, res->ai_addrlen);
|
||||
freeaddrinfo(res);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
proxy_read_line(int fd, char *buf, size_t bufsz)
|
||||
{
|
||||
size_t off;
|
||||
|
||||
for(off = 0;;) {
|
||||
if (off >= bufsz)
|
||||
errx(1, "proxy read too long");
|
||||
if (atomicio(read, fd, buf + off, 1) != 1)
|
||||
err(1, "proxy read");
|
||||
/* Skip CR */
|
||||
if (buf[off] == '\r')
|
||||
continue;
|
||||
if (buf[off] == '\n') {
|
||||
buf[off] = '\0';
|
||||
break;
|
||||
}
|
||||
off++;
|
||||
}
|
||||
return (off);
|
||||
}
|
||||
|
||||
static void
|
||||
getproxypass(const char *proxyuser, const char *proxyhost,
|
||||
char *pw, size_t pwlen)
|
||||
{
|
||||
char prompt[512];
|
||||
|
||||
snprintf(prompt, sizeof(prompt), "Proxy password for %s@%s: ",
|
||||
proxyuser, proxyhost);
|
||||
if (readpassphrase(prompt, pw, pwlen, RPP_REQUIRE_TTY) == NULL)
|
||||
errx(1, "Unable to read proxy passphrase");
|
||||
}
|
||||
|
||||
/*
|
||||
* Error strings adapted from the generally accepted SOCKSv4 spec:
|
||||
*
|
||||
* http://ftp.icm.edu.pl/packages/socks/socks4/SOCKS4.protocol
|
||||
*/
|
||||
static const char *
|
||||
socks4_strerror(int e)
|
||||
{
|
||||
switch (e) {
|
||||
case 90:
|
||||
return "Succeeded";
|
||||
case 91:
|
||||
return "Request rejected or failed";
|
||||
case 92:
|
||||
return "SOCKS server cannot connect to identd on the client";
|
||||
case 93:
|
||||
return "Client program and identd report different user-ids";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Error strings taken almost directly from RFC 1928.
|
||||
*/
|
||||
static const char *
|
||||
socks5_strerror(int e)
|
||||
{
|
||||
switch (e) {
|
||||
case 0:
|
||||
return "Succeeded";
|
||||
case 1:
|
||||
return "General SOCKS server failure";
|
||||
case 2:
|
||||
return "Connection not allowed by ruleset";
|
||||
case 3:
|
||||
return "Network unreachable";
|
||||
case 4:
|
||||
return "Host unreachable";
|
||||
case 5:
|
||||
return "Connection refused";
|
||||
case 6:
|
||||
return "TTL expired";
|
||||
case 7:
|
||||
return "Command not supported";
|
||||
case 8:
|
||||
return "Address type not supported";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
socks_connect(const char *host, const char *port,
|
||||
struct addrinfo hints __attribute__ ((__unused__)),
|
||||
const char *proxyhost, const char *proxyport, struct addrinfo proxyhints,
|
||||
int socksv, const char *proxyuser)
|
||||
{
|
||||
int proxyfd, r, authretry = 0;
|
||||
size_t hlen, wlen;
|
||||
unsigned char buf[1024];
|
||||
size_t cnt;
|
||||
struct sockaddr_storage addr;
|
||||
struct sockaddr_in *in4 = (struct sockaddr_in *)&addr;
|
||||
struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&addr;
|
||||
in_port_t serverport;
|
||||
|
||||
if (proxyport == NULL)
|
||||
proxyport = (socksv == -1) ? HTTP_PROXY_PORT : SOCKS_PORT;
|
||||
|
||||
/* Abuse API to lookup port */
|
||||
if (decode_addrport("0.0.0.0", port, (struct sockaddr *)&addr,
|
||||
sizeof(addr), 1, 1) == -1)
|
||||
errx(1, "unknown port \"%.64s\"", port);
|
||||
serverport = in4->sin_port;
|
||||
|
||||
again:
|
||||
if (authretry++ > 3)
|
||||
errx(1, "Too many authentication failures");
|
||||
|
||||
proxyfd = remote_connect(proxyhost, proxyport, proxyhints, NULL);
|
||||
|
||||
if (proxyfd < 0)
|
||||
return (-1);
|
||||
|
||||
if (socksv == 5) {
|
||||
if (decode_addrport(host, port, (struct sockaddr *)&addr,
|
||||
sizeof(addr), 0, 1) == -1)
|
||||
addr.ss_family = 0; /* used in switch below */
|
||||
|
||||
/* Version 5, one method: no authentication */
|
||||
buf[0] = SOCKS_V5;
|
||||
buf[1] = 1;
|
||||
buf[2] = SOCKS_NOAUTH;
|
||||
cnt = atomicio(vwrite, proxyfd, buf, 3);
|
||||
if (cnt != 3)
|
||||
err(1, "write failed (%zu/3)", cnt);
|
||||
|
||||
cnt = atomicio(read, proxyfd, buf, 2);
|
||||
if (cnt != 2)
|
||||
err(1, "read failed (%zu/3)", cnt);
|
||||
|
||||
if (buf[1] == SOCKS_NOMETHOD)
|
||||
errx(1, "authentication method negotiation failed");
|
||||
|
||||
switch (addr.ss_family) {
|
||||
case 0:
|
||||
/* Version 5, connect: domain name */
|
||||
|
||||
/* Max domain name length is 255 bytes */
|
||||
hlen = strlen(host);
|
||||
if (hlen > 255)
|
||||
errx(1, "host name too long for SOCKS5");
|
||||
buf[0] = SOCKS_V5;
|
||||
buf[1] = SOCKS_CONNECT;
|
||||
buf[2] = 0;
|
||||
buf[3] = SOCKS_DOMAIN;
|
||||
buf[4] = hlen;
|
||||
memcpy(buf + 5, host, hlen);
|
||||
memcpy(buf + 5 + hlen, &serverport, sizeof serverport);
|
||||
wlen = 7 + hlen;
|
||||
break;
|
||||
case AF_INET:
|
||||
/* Version 5, connect: IPv4 address */
|
||||
buf[0] = SOCKS_V5;
|
||||
buf[1] = SOCKS_CONNECT;
|
||||
buf[2] = 0;
|
||||
buf[3] = SOCKS_IPV4;
|
||||
memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
|
||||
memcpy(buf + 8, &in4->sin_port, sizeof in4->sin_port);
|
||||
wlen = 10;
|
||||
break;
|
||||
case AF_INET6:
|
||||
/* Version 5, connect: IPv6 address */
|
||||
buf[0] = SOCKS_V5;
|
||||
buf[1] = SOCKS_CONNECT;
|
||||
buf[2] = 0;
|
||||
buf[3] = SOCKS_IPV6;
|
||||
memcpy(buf + 4, &in6->sin6_addr, sizeof in6->sin6_addr);
|
||||
memcpy(buf + 20, &in6->sin6_port,
|
||||
sizeof in6->sin6_port);
|
||||
wlen = 22;
|
||||
break;
|
||||
default:
|
||||
errx(1, "internal error: silly AF");
|
||||
}
|
||||
|
||||
cnt = atomicio(vwrite, proxyfd, buf, wlen);
|
||||
if (cnt != wlen)
|
||||
err(1, "write failed (%zu/%zu)", cnt, wlen);
|
||||
|
||||
cnt = atomicio(read, proxyfd, buf, 4);
|
||||
if (cnt != 4)
|
||||
err(1, "read failed (%zu/4)", cnt);
|
||||
if (buf[1] != 0) {
|
||||
errx(1, "connection failed, SOCKSv5 error: %s",
|
||||
socks5_strerror(buf[1]));
|
||||
}
|
||||
switch (buf[3]) {
|
||||
case SOCKS_IPV4:
|
||||
cnt = atomicio(read, proxyfd, buf + 4, 6);
|
||||
if (cnt != 6)
|
||||
err(1, "read failed (%zu/6)", cnt);
|
||||
break;
|
||||
case SOCKS_IPV6:
|
||||
cnt = atomicio(read, proxyfd, buf + 4, 18);
|
||||
if (cnt != 18)
|
||||
err(1, "read failed (%zu/18)", cnt);
|
||||
break;
|
||||
default:
|
||||
errx(1, "connection failed, unsupported address type");
|
||||
}
|
||||
} else if (socksv == 4) {
|
||||
/* This will exit on lookup failure */
|
||||
decode_addrport(host, port, (struct sockaddr *)&addr,
|
||||
sizeof(addr), 1, 0);
|
||||
|
||||
/* Version 4 */
|
||||
buf[0] = SOCKS_V4;
|
||||
buf[1] = SOCKS_CONNECT; /* connect */
|
||||
memcpy(buf + 2, &in4->sin_port, sizeof in4->sin_port);
|
||||
memcpy(buf + 4, &in4->sin_addr, sizeof in4->sin_addr);
|
||||
buf[8] = 0; /* empty username */
|
||||
wlen = 9;
|
||||
|
||||
cnt = atomicio(vwrite, proxyfd, buf, wlen);
|
||||
if (cnt != wlen)
|
||||
err(1, "write failed (%zu/%zu)", cnt, wlen);
|
||||
|
||||
cnt = atomicio(read, proxyfd, buf, 8);
|
||||
if (cnt != 8)
|
||||
err(1, "read failed (%zu/8)", cnt);
|
||||
if (buf[1] != 90) {
|
||||
errx(1, "connection failed, SOCKSv4 error: %s",
|
||||
socks4_strerror(buf[1]));
|
||||
}
|
||||
} else if (socksv == -1) {
|
||||
/* HTTP proxy CONNECT */
|
||||
|
||||
/* Disallow bad chars in hostname */
|
||||
if (strcspn(host, "\r\n\t []") != strlen(host))
|
||||
errx(1, "Invalid hostname");
|
||||
|
||||
/* Try to be sane about numeric IPv6 addresses */
|
||||
if (strchr(host, ':') != NULL) {
|
||||
r = snprintf(buf, sizeof(buf),
|
||||
"CONNECT [%s]:%d HTTP/1.0\r\n",
|
||||
host, ntohs(serverport));
|
||||
} else {
|
||||
r = snprintf(buf, sizeof(buf),
|
||||
"CONNECT %s:%d HTTP/1.0\r\n",
|
||||
host, ntohs(serverport));
|
||||
}
|
||||
if (r < 0 || (size_t)r >= sizeof(buf))
|
||||
errx(1, "hostname too long");
|
||||
r = strlen(buf);
|
||||
|
||||
cnt = atomicio(vwrite, proxyfd, buf, r);
|
||||
if (cnt != r)
|
||||
err(1, "write failed (%zu/%d)", cnt, r);
|
||||
|
||||
if (authretry > 1) {
|
||||
char proxypass[256];
|
||||
char resp[1024];
|
||||
|
||||
getproxypass(proxyuser, proxyhost,
|
||||
proxypass, sizeof proxypass);
|
||||
r = snprintf(buf, sizeof(buf), "%s:%s",
|
||||
proxyuser, proxypass);
|
||||
explicit_bzero(proxypass, sizeof proxypass);
|
||||
if (r == -1 || (size_t)r >= sizeof(buf) ||
|
||||
b64_ntop(buf, strlen(buf), resp,
|
||||
sizeof(resp)) == -1)
|
||||
errx(1, "Proxy username/password too long");
|
||||
r = snprintf(buf, sizeof(buf), "Proxy-Authorization: "
|
||||
"Basic %s\r\n", resp);
|
||||
if (r < 0 || (size_t)r >= sizeof(buf))
|
||||
errx(1, "Proxy auth response too long");
|
||||
r = strlen(buf);
|
||||
if ((cnt = atomicio(vwrite, proxyfd, buf, r)) != r)
|
||||
err(1, "write failed (%zu/%d)", cnt, r);
|
||||
explicit_bzero(proxypass, sizeof proxypass);
|
||||
explicit_bzero(buf, sizeof buf);
|
||||
}
|
||||
|
||||
/* Terminate headers */
|
||||
if ((cnt = atomicio(vwrite, proxyfd, "\r\n", 2)) != 2)
|
||||
err(1, "write failed (%zu/2)", cnt);
|
||||
|
||||
/* Read status reply */
|
||||
proxy_read_line(proxyfd, buf, sizeof(buf));
|
||||
if (proxyuser != NULL &&
|
||||
(strncmp(buf, "HTTP/1.0 407 ", 12) == 0 ||
|
||||
strncmp(buf, "HTTP/1.1 407 ", 12) == 0)) {
|
||||
if (authretry > 1) {
|
||||
fprintf(stderr, "Proxy authentication "
|
||||
"failed\n");
|
||||
}
|
||||
close(proxyfd);
|
||||
goto again;
|
||||
} else if (strncmp(buf, "HTTP/1.0 200 ", 12) != 0 &&
|
||||
strncmp(buf, "HTTP/1.1 200 ", 12) != 0)
|
||||
errx(1, "Proxy error: \"%s\"", buf);
|
||||
|
||||
/* Headers continue until we hit an empty line */
|
||||
for (r = 0; r < HTTP_MAXHDRS; r++) {
|
||||
proxy_read_line(proxyfd, buf, sizeof(buf));
|
||||
if (*buf == '\0')
|
||||
break;
|
||||
}
|
||||
if (*buf != '\0')
|
||||
errx(1, "Too many proxy headers received");
|
||||
} else
|
||||
errx(1, "Unknown proxy protocol %d", socksv);
|
||||
|
||||
return (proxyfd);
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
if(NOT MSVC)
|
||||
|
||||
set(
|
||||
OCSPCHECK_SRC
|
||||
http.c
|
||||
@@ -33,5 +31,3 @@ if(ENABLE_LIBRESSL_INSTALL)
|
||||
install(FILES ocspcheck.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8)
|
||||
|
||||
endif(ENABLE_LIBRESSL_INSTALL)
|
||||
|
||||
endif()
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
/* $OpenBSD: memmem.c,v 1.5 2020/04/16 12:39:28 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005-2020 Rich Felker, et al.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static char *
|
||||
twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
|
||||
{
|
||||
uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
|
||||
for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
|
||||
if (hw == nw) return (char *)h-2;
|
||||
return hw == nw ? (char *)h-2 : 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
|
||||
{
|
||||
uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
|
||||
uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
|
||||
for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
|
||||
if (hw == nw) return (char *)h-3;
|
||||
return hw == nw ? (char *)h-3 : 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
|
||||
{
|
||||
uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
|
||||
uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
|
||||
for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
|
||||
if (hw == nw) return (char *)h-4;
|
||||
return hw == nw ? (char *)h-4 : 0;
|
||||
}
|
||||
|
||||
#define MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
|
||||
#define BITOP(a,b,op) \
|
||||
((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
|
||||
|
||||
/*
|
||||
* Maxime Crochemore and Dominique Perrin, Two-way string-matching,
|
||||
* Journal of the ACM, 38(3):651-675, July 1991.
|
||||
*/
|
||||
static char *
|
||||
twoway_memmem(const unsigned char *h, const unsigned char *z,
|
||||
const unsigned char *n, size_t l)
|
||||
{
|
||||
size_t i, ip, jp, k, p, ms, p0, mem, mem0;
|
||||
size_t byteset[32 / sizeof(size_t)] = { 0 };
|
||||
size_t shift[256];
|
||||
|
||||
/* Computing length of needle and fill shift table */
|
||||
for (i=0; i<l; i++)
|
||||
BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
|
||||
|
||||
/* Compute maximal suffix */
|
||||
ip = -1; jp = 0; k = p = 1;
|
||||
while (jp+k<l) {
|
||||
if (n[ip+k] == n[jp+k]) {
|
||||
if (k == p) {
|
||||
jp += p;
|
||||
k = 1;
|
||||
} else k++;
|
||||
} else if (n[ip+k] > n[jp+k]) {
|
||||
jp += k;
|
||||
k = 1;
|
||||
p = jp - ip;
|
||||
} else {
|
||||
ip = jp++;
|
||||
k = p = 1;
|
||||
}
|
||||
}
|
||||
ms = ip;
|
||||
p0 = p;
|
||||
|
||||
/* And with the opposite comparison */
|
||||
ip = -1; jp = 0; k = p = 1;
|
||||
while (jp+k<l) {
|
||||
if (n[ip+k] == n[jp+k]) {
|
||||
if (k == p) {
|
||||
jp += p;
|
||||
k = 1;
|
||||
} else k++;
|
||||
} else if (n[ip+k] < n[jp+k]) {
|
||||
jp += k;
|
||||
k = 1;
|
||||
p = jp - ip;
|
||||
} else {
|
||||
ip = jp++;
|
||||
k = p = 1;
|
||||
}
|
||||
}
|
||||
if (ip+1 > ms+1) ms = ip;
|
||||
else p = p0;
|
||||
|
||||
/* Periodic needle? */
|
||||
if (memcmp(n, n+p, ms+1)) {
|
||||
mem0 = 0;
|
||||
p = MAX(ms, l-ms-1) + 1;
|
||||
} else mem0 = l-p;
|
||||
mem = 0;
|
||||
|
||||
/* Search loop */
|
||||
for (;;) {
|
||||
/* If remainder of haystack is shorter than needle, done */
|
||||
if (z-h < l) return 0;
|
||||
|
||||
/* Check last byte first; advance by shift on mismatch */
|
||||
if (BITOP(byteset, h[l-1], &)) {
|
||||
k = l-shift[h[l-1]];
|
||||
if (k) {
|
||||
if (k < mem) k = mem;
|
||||
h += k;
|
||||
mem = 0;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
h += l;
|
||||
mem = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Compare right half */
|
||||
for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
|
||||
if (k < l) {
|
||||
h += k-ms;
|
||||
mem = 0;
|
||||
continue;
|
||||
}
|
||||
/* Compare left half */
|
||||
for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
|
||||
if (k <= mem) return (char *)h;
|
||||
h += p;
|
||||
mem = mem0;
|
||||
}
|
||||
}
|
||||
|
||||
void *
|
||||
memmem(const void *h0, size_t k, const void *n0, size_t l)
|
||||
{
|
||||
const unsigned char *h = h0, *n = n0;
|
||||
|
||||
/* Return immediately on empty needle */
|
||||
if (!l) return (void *)h;
|
||||
|
||||
/* Return immediately when needle is longer than haystack */
|
||||
if (k<l) return 0;
|
||||
|
||||
/* Use faster algorithms for short needles */
|
||||
h = memchr(h0, *n, k);
|
||||
if (!h || l==1) return (void *)h;
|
||||
k -= h - (const unsigned char *)h0;
|
||||
if (k<l) return 0;
|
||||
if (l==2) return twobyte_memmem(h, k, n);
|
||||
if (l==3) return threebyte_memmem(h, k, n);
|
||||
if (l==4) return fourbyte_memmem(h, k, n);
|
||||
|
||||
return twoway_memmem(h, h+k, n, l);
|
||||
}
|
||||
@@ -1,777 +0,0 @@
|
||||
/* $Id: http.c,v 1.17 2023/04/19 12:58:16 jsg Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* 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 AUTHORS DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <err.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <tls.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "http.h"
|
||||
|
||||
/*
|
||||
* A buffer for transferring HTTP/S data.
|
||||
*/
|
||||
struct httpxfer {
|
||||
char *hbuf; /* header transfer buffer */
|
||||
size_t hbufsz; /* header buffer size */
|
||||
int headok; /* header has been parsed */
|
||||
char *bbuf; /* body transfer buffer */
|
||||
size_t bbufsz; /* body buffer size */
|
||||
int bodyok; /* body has been parsed */
|
||||
char *headbuf; /* lookaside buffer for headers */
|
||||
struct httphead *head; /* parsed headers */
|
||||
size_t headsz; /* number of headers */
|
||||
};
|
||||
|
||||
/*
|
||||
* An HTTP/S connection object.
|
||||
*/
|
||||
struct http {
|
||||
int fd; /* connected socket */
|
||||
short port; /* port number */
|
||||
struct source src; /* endpoint (raw) host */
|
||||
char *path; /* path to request */
|
||||
char *host; /* name of endpoint host */
|
||||
struct tls *ctx; /* if TLS */
|
||||
writefp writer; /* write function */
|
||||
readfp reader; /* read function */
|
||||
};
|
||||
|
||||
struct tls_config *tlscfg;
|
||||
|
||||
static ssize_t
|
||||
dosysread(char *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = read(http->fd, buf, sz);
|
||||
if (rc == -1)
|
||||
warn("%s: read", http->src.ip);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
dosyswrite(const void *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
rc = write(http->fd, buf, sz);
|
||||
if (rc == -1)
|
||||
warn("%s: write", http->src.ip);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
dotlsread(char *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
do {
|
||||
rc = tls_read(http->ctx, buf, sz);
|
||||
} while (rc == TLS_WANT_POLLIN || rc == TLS_WANT_POLLOUT);
|
||||
|
||||
if (rc == -1)
|
||||
warnx("%s: tls_read: %s", http->src.ip,
|
||||
tls_error(http->ctx));
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
dotlswrite(const void *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
do {
|
||||
rc = tls_write(http->ctx, buf, sz);
|
||||
} while (rc == TLS_WANT_POLLIN || rc == TLS_WANT_POLLOUT);
|
||||
|
||||
if (rc == -1)
|
||||
warnx("%s: tls_write: %s", http->src.ip,
|
||||
tls_error(http->ctx));
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
http_init(void)
|
||||
{
|
||||
if (tlscfg != NULL)
|
||||
return 0;
|
||||
|
||||
tlscfg = tls_config_new();
|
||||
if (tlscfg == NULL) {
|
||||
warn("tls_config_new");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tls_config_set_ca_file(tlscfg, tls_default_ca_cert_file()) == -1) {
|
||||
warn("tls_config_set_ca_file: %s", tls_config_error(tlscfg));
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
tls_config_free(tlscfg);
|
||||
tlscfg = NULL;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
http_read(char *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t ssz, xfer;
|
||||
|
||||
xfer = 0;
|
||||
do {
|
||||
if ((ssz = http->reader(buf, sz, http)) < 0)
|
||||
return -1;
|
||||
if (ssz == 0)
|
||||
break;
|
||||
xfer += ssz;
|
||||
sz -= ssz;
|
||||
buf += ssz;
|
||||
} while (ssz > 0 && sz > 0);
|
||||
|
||||
return xfer;
|
||||
}
|
||||
|
||||
static int
|
||||
http_write(const char *buf, size_t sz, const struct http *http)
|
||||
{
|
||||
ssize_t ssz, xfer;
|
||||
|
||||
xfer = sz;
|
||||
while (sz > 0) {
|
||||
if ((ssz = http->writer(buf, sz, http)) < 0)
|
||||
return -1;
|
||||
sz -= ssz;
|
||||
buf += (size_t)ssz;
|
||||
}
|
||||
return xfer;
|
||||
}
|
||||
|
||||
void
|
||||
http_disconnect(struct http *http)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (http->ctx != NULL) {
|
||||
/* TLS connection. */
|
||||
do {
|
||||
rc = tls_close(http->ctx);
|
||||
} while (rc == TLS_WANT_POLLIN || rc == TLS_WANT_POLLOUT);
|
||||
|
||||
if (rc < 0)
|
||||
warnx("%s: tls_close: %s", http->src.ip,
|
||||
tls_error(http->ctx));
|
||||
|
||||
tls_free(http->ctx);
|
||||
}
|
||||
if (http->fd != -1) {
|
||||
if (close(http->fd) == -1)
|
||||
warn("%s: close", http->src.ip);
|
||||
}
|
||||
|
||||
http->fd = -1;
|
||||
http->ctx = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
http_free(struct http *http)
|
||||
{
|
||||
|
||||
if (http == NULL)
|
||||
return;
|
||||
http_disconnect(http);
|
||||
free(http->host);
|
||||
free(http->path);
|
||||
free(http->src.ip);
|
||||
free(http);
|
||||
}
|
||||
|
||||
struct http *
|
||||
http_alloc(const struct source *addrs, size_t addrsz,
|
||||
const char *host, short port, const char *path)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
int family, fd, c;
|
||||
socklen_t len;
|
||||
size_t cur, i = 0;
|
||||
struct http *http;
|
||||
|
||||
/* Do this while we still have addresses to connect. */
|
||||
again:
|
||||
if (i == addrsz)
|
||||
return NULL;
|
||||
cur = i++;
|
||||
|
||||
/* Convert to PF_INET or PF_INET6 address from string. */
|
||||
|
||||
memset(&ss, 0, sizeof(struct sockaddr_storage));
|
||||
|
||||
if (addrs[cur].family == 4) {
|
||||
family = PF_INET;
|
||||
((struct sockaddr_in *)&ss)->sin_family = AF_INET;
|
||||
((struct sockaddr_in *)&ss)->sin_port = htons(port);
|
||||
c = inet_pton(AF_INET, addrs[cur].ip,
|
||||
&((struct sockaddr_in *)&ss)->sin_addr);
|
||||
len = sizeof(struct sockaddr_in);
|
||||
} else if (addrs[cur].family == 6) {
|
||||
family = PF_INET6;
|
||||
((struct sockaddr_in6 *)&ss)->sin6_family = AF_INET6;
|
||||
((struct sockaddr_in6 *)&ss)->sin6_port = htons(port);
|
||||
c = inet_pton(AF_INET6, addrs[cur].ip,
|
||||
&((struct sockaddr_in6 *)&ss)->sin6_addr);
|
||||
len = sizeof(struct sockaddr_in6);
|
||||
} else {
|
||||
warnx("%s: unknown family", addrs[cur].ip);
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (c < 0) {
|
||||
warn("%s: inet_ntop", addrs[cur].ip);
|
||||
goto again;
|
||||
} else if (c == 0) {
|
||||
warnx("%s: inet_ntop", addrs[cur].ip);
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* Create socket and connect. */
|
||||
|
||||
fd = socket(family, SOCK_STREAM, 0);
|
||||
if (fd == -1) {
|
||||
warn("%s: socket", addrs[cur].ip);
|
||||
goto again;
|
||||
} else if (connect(fd, (struct sockaddr *)&ss, len) == -1) {
|
||||
warn("%s: connect", addrs[cur].ip);
|
||||
close(fd);
|
||||
goto again;
|
||||
}
|
||||
|
||||
/* Allocate the communicator. */
|
||||
|
||||
http = calloc(1, sizeof(struct http));
|
||||
if (http == NULL) {
|
||||
warn("calloc");
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
http->fd = fd;
|
||||
http->port = port;
|
||||
http->src.family = addrs[cur].family;
|
||||
http->src.ip = strdup(addrs[cur].ip);
|
||||
http->host = strdup(host);
|
||||
http->path = strdup(path);
|
||||
if (http->src.ip == NULL || http->host == NULL || http->path == NULL) {
|
||||
warn("strdup");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If necessary, do our TLS setup. */
|
||||
|
||||
if (port != 443) {
|
||||
http->writer = dosyswrite;
|
||||
http->reader = dosysread;
|
||||
return http;
|
||||
}
|
||||
|
||||
http->writer = dotlswrite;
|
||||
http->reader = dotlsread;
|
||||
|
||||
if ((http->ctx = tls_client()) == NULL) {
|
||||
warn("tls_client");
|
||||
goto err;
|
||||
} else if (tls_configure(http->ctx, tlscfg) == -1) {
|
||||
warnx("%s: tls_configure: %s",
|
||||
http->src.ip, tls_error(http->ctx));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tls_connect_socket(http->ctx, http->fd, http->host) != 0) {
|
||||
warnx("%s: tls_connect_socket: %s, %s", http->src.ip,
|
||||
http->host, tls_error(http->ctx));
|
||||
goto err;
|
||||
}
|
||||
|
||||
return http;
|
||||
err:
|
||||
http_free(http);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct httpxfer *
|
||||
http_open(const struct http *http, const void *p, size_t psz)
|
||||
{
|
||||
char *req;
|
||||
int c;
|
||||
struct httpxfer *trans;
|
||||
|
||||
if (p == NULL) {
|
||||
c = asprintf(&req,
|
||||
"GET %s HTTP/1.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
"\r\n",
|
||||
http->path, http->host);
|
||||
} else {
|
||||
c = asprintf(&req,
|
||||
"POST %s HTTP/1.0\r\n"
|
||||
"Host: %s\r\n"
|
||||
"Content-Type: application/ocsp-request\r\n"
|
||||
"Content-Length: %zu\r\n"
|
||||
"\r\n",
|
||||
http->path, http->host, psz);
|
||||
}
|
||||
if (c == -1) {
|
||||
warn("asprintf");
|
||||
return NULL;
|
||||
} else if (!http_write(req, c, http)) {
|
||||
free(req);
|
||||
return NULL;
|
||||
} else if (p != NULL && !http_write(p, psz, http)) {
|
||||
free(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
free(req);
|
||||
|
||||
trans = calloc(1, sizeof(struct httpxfer));
|
||||
if (trans == NULL)
|
||||
warn("calloc");
|
||||
return trans;
|
||||
}
|
||||
|
||||
void
|
||||
http_close(struct httpxfer *x)
|
||||
{
|
||||
|
||||
if (x == NULL)
|
||||
return;
|
||||
free(x->hbuf);
|
||||
free(x->bbuf);
|
||||
free(x->headbuf);
|
||||
free(x->head);
|
||||
free(x);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the HTTP body from the wire.
|
||||
* If invoked multiple times, this will return the same pointer with the
|
||||
* same data (or NULL, if the original invocation returned NULL).
|
||||
* Returns NULL if read or allocation errors occur.
|
||||
* You must not free the returned pointer.
|
||||
*/
|
||||
char *
|
||||
http_body_read(const struct http *http, struct httpxfer *trans, size_t *sz)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
ssize_t ssz;
|
||||
void *pp;
|
||||
size_t szp;
|
||||
|
||||
if (sz == NULL)
|
||||
sz = &szp;
|
||||
|
||||
/* Have we already parsed this? */
|
||||
|
||||
if (trans->bodyok > 0) {
|
||||
*sz = trans->bbufsz;
|
||||
return trans->bbuf;
|
||||
} else if (trans->bodyok < 0)
|
||||
return NULL;
|
||||
|
||||
*sz = 0;
|
||||
trans->bodyok = -1;
|
||||
|
||||
do {
|
||||
/* If less than sizeof(buf), at EOF. */
|
||||
if ((ssz = http_read(buf, sizeof(buf), http)) < 0)
|
||||
return NULL;
|
||||
else if (ssz == 0)
|
||||
break;
|
||||
|
||||
pp = recallocarray(trans->bbuf,
|
||||
trans->bbufsz, trans->bbufsz + ssz, 1);
|
||||
if (pp == NULL) {
|
||||
warn("recallocarray");
|
||||
return NULL;
|
||||
}
|
||||
trans->bbuf = pp;
|
||||
memcpy(trans->bbuf + trans->bbufsz, buf, ssz);
|
||||
trans->bbufsz += ssz;
|
||||
} while (ssz == sizeof(buf));
|
||||
|
||||
trans->bodyok = 1;
|
||||
*sz = trans->bbufsz;
|
||||
return trans->bbuf;
|
||||
}
|
||||
|
||||
struct httphead *
|
||||
http_head_get(const char *v, struct httphead *h, size_t hsz)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < hsz; i++) {
|
||||
if (strcmp(h[i].key, v))
|
||||
continue;
|
||||
return &h[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look through the headers and determine our HTTP code.
|
||||
* This will return -1 on failure, otherwise the code.
|
||||
*/
|
||||
int
|
||||
http_head_status(const struct http *http, struct httphead *h, size_t sz)
|
||||
{
|
||||
int rc;
|
||||
unsigned int code;
|
||||
struct httphead *st;
|
||||
|
||||
if ((st = http_head_get("Status", h, sz)) == NULL) {
|
||||
warnx("%s: no status header", http->src.ip);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = sscanf(st->val, "%*s %u %*s", &code);
|
||||
if (rc < 0) {
|
||||
warn("sscanf");
|
||||
return -1;
|
||||
} else if (rc != 1) {
|
||||
warnx("%s: cannot convert status header", http->src.ip);
|
||||
return -1;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse headers from the transfer.
|
||||
* Malformed headers are skipped.
|
||||
* A special "Status" header is added for the HTTP status line.
|
||||
* This can only happen once http_head_read has been called with
|
||||
* success.
|
||||
* This can be invoked multiple times: it will only parse the headers
|
||||
* once and after that it will just return the cache.
|
||||
* You must not free the returned pointer.
|
||||
* If the original header parse failed, or if memory allocation fails
|
||||
* internally, this returns NULL.
|
||||
*/
|
||||
struct httphead *
|
||||
http_head_parse(const struct http *http, struct httpxfer *trans, size_t *sz)
|
||||
{
|
||||
size_t hsz, szp;
|
||||
struct httphead *h;
|
||||
char *cp, *ep, *ccp, *buf;
|
||||
|
||||
if (sz == NULL)
|
||||
sz = &szp;
|
||||
|
||||
/*
|
||||
* If we've already parsed the headers, return the
|
||||
* previously-parsed buffer now.
|
||||
* If we have errors on the stream, return NULL now.
|
||||
*/
|
||||
|
||||
if (trans->head != NULL) {
|
||||
*sz = trans->headsz;
|
||||
return trans->head;
|
||||
} else if (trans->headok <= 0)
|
||||
return NULL;
|
||||
|
||||
if ((buf = strdup(trans->hbuf)) == NULL) {
|
||||
warn("strdup");
|
||||
return NULL;
|
||||
}
|
||||
hsz = 0;
|
||||
cp = buf;
|
||||
|
||||
do {
|
||||
if ((cp = strstr(cp, "\r\n")) != NULL)
|
||||
cp += 2;
|
||||
hsz++;
|
||||
} while (cp != NULL);
|
||||
|
||||
/*
|
||||
* Allocate headers, then step through the data buffer, parsing
|
||||
* out headers as we have them.
|
||||
* We know at this point that the buffer is NUL-terminated in
|
||||
* the usual way.
|
||||
*/
|
||||
|
||||
h = calloc(hsz, sizeof(struct httphead));
|
||||
if (h == NULL) {
|
||||
warn("calloc");
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*sz = hsz;
|
||||
hsz = 0;
|
||||
cp = buf;
|
||||
|
||||
do {
|
||||
if ((ep = strstr(cp, "\r\n")) != NULL) {
|
||||
*ep = '\0';
|
||||
ep += 2;
|
||||
}
|
||||
if (hsz == 0) {
|
||||
h[hsz].key = "Status";
|
||||
h[hsz++].val = cp;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip bad headers. */
|
||||
if ((ccp = strchr(cp, ':')) == NULL) {
|
||||
warnx("%s: header without separator", http->src.ip);
|
||||
continue;
|
||||
}
|
||||
|
||||
*ccp++ = '\0';
|
||||
while (isspace((unsigned char)*ccp))
|
||||
ccp++;
|
||||
h[hsz].key = cp;
|
||||
h[hsz++].val = ccp;
|
||||
} while ((cp = ep) != NULL);
|
||||
|
||||
trans->headbuf = buf;
|
||||
trans->head = h;
|
||||
trans->headsz = hsz;
|
||||
return h;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the HTTP headers from the wire.
|
||||
* If invoked multiple times, this will return the same pointer with the
|
||||
* same data (or NULL, if the original invocation returned NULL).
|
||||
* Returns NULL if read or allocation errors occur.
|
||||
* You must not free the returned pointer.
|
||||
*/
|
||||
char *
|
||||
http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
ssize_t ssz;
|
||||
char *ep;
|
||||
void *pp;
|
||||
size_t szp;
|
||||
|
||||
if (sz == NULL)
|
||||
sz = &szp;
|
||||
|
||||
/* Have we already parsed this? */
|
||||
|
||||
if (trans->headok > 0) {
|
||||
*sz = trans->hbufsz;
|
||||
return trans->hbuf;
|
||||
} else if (trans->headok < 0)
|
||||
return NULL;
|
||||
|
||||
*sz = 0;
|
||||
ep = NULL;
|
||||
trans->headok = -1;
|
||||
|
||||
/*
|
||||
* Begin by reading by BUFSIZ blocks until we reach the header
|
||||
* termination marker (two CRLFs).
|
||||
* We might read into our body, but that's ok: we'll copy out
|
||||
* the body parts into our body buffer afterward.
|
||||
*/
|
||||
|
||||
do {
|
||||
/* If less than sizeof(buf), at EOF. */
|
||||
if ((ssz = http_read(buf, sizeof(buf), http)) < 0)
|
||||
return NULL;
|
||||
else if (ssz == 0)
|
||||
break;
|
||||
pp = realloc(trans->hbuf, trans->hbufsz + ssz);
|
||||
if (pp == NULL) {
|
||||
warn("realloc");
|
||||
return NULL;
|
||||
}
|
||||
trans->hbuf = pp;
|
||||
memcpy(trans->hbuf + trans->hbufsz, buf, ssz);
|
||||
trans->hbufsz += ssz;
|
||||
/* Search for end of headers marker. */
|
||||
ep = memmem(trans->hbuf, trans->hbufsz, "\r\n\r\n", 4);
|
||||
} while (ep == NULL && ssz == sizeof(buf));
|
||||
|
||||
if (ep == NULL) {
|
||||
warnx("%s: partial transfer", http->src.ip);
|
||||
return NULL;
|
||||
}
|
||||
*ep = '\0';
|
||||
|
||||
/*
|
||||
* The header data is invalid if it has any binary characters in
|
||||
* it: check that now.
|
||||
* This is important because we want to guarantee that all
|
||||
* header keys and pairs are properly NUL-terminated.
|
||||
*/
|
||||
|
||||
if (strlen(trans->hbuf) != (uintptr_t)(ep - trans->hbuf)) {
|
||||
warnx("%s: binary data in header", http->src.ip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy remaining buffer into body buffer.
|
||||
*/
|
||||
|
||||
ep += 4;
|
||||
trans->bbufsz = (trans->hbuf + trans->hbufsz) - ep;
|
||||
trans->bbuf = malloc(trans->bbufsz);
|
||||
if (trans->bbuf == NULL) {
|
||||
warn("malloc");
|
||||
return NULL;
|
||||
}
|
||||
memcpy(trans->bbuf, ep, trans->bbufsz);
|
||||
|
||||
trans->headok = 1;
|
||||
*sz = trans->hbufsz;
|
||||
return trans->hbuf;
|
||||
}
|
||||
|
||||
void
|
||||
http_get_free(struct httpget *g)
|
||||
{
|
||||
|
||||
if (g == NULL)
|
||||
return;
|
||||
http_close(g->xfer);
|
||||
http_free(g->http);
|
||||
free(g);
|
||||
}
|
||||
|
||||
struct httpget *
|
||||
http_get(const struct source *addrs, size_t addrsz, const char *domain,
|
||||
short port, const char *path, const void *post, size_t postsz)
|
||||
{
|
||||
struct http *h;
|
||||
struct httpxfer *x;
|
||||
struct httpget *g;
|
||||
struct httphead *head;
|
||||
size_t headsz, bodsz, headrsz;
|
||||
int code;
|
||||
char *bod, *headr;
|
||||
|
||||
h = http_alloc(addrs, addrsz, domain, port, path);
|
||||
if (h == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((x = http_open(h, post, postsz)) == NULL) {
|
||||
http_free(h);
|
||||
return NULL;
|
||||
} else if ((headr = http_head_read(h, x, &headrsz)) == NULL) {
|
||||
http_close(x);
|
||||
http_free(h);
|
||||
return NULL;
|
||||
} else if ((bod = http_body_read(h, x, &bodsz)) == NULL) {
|
||||
http_close(x);
|
||||
http_free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
http_disconnect(h);
|
||||
|
||||
if ((head = http_head_parse(h, x, &headsz)) == NULL) {
|
||||
http_close(x);
|
||||
http_free(h);
|
||||
return NULL;
|
||||
} else if ((code = http_head_status(h, head, headsz)) < 0) {
|
||||
http_close(x);
|
||||
http_free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((g = calloc(1, sizeof(struct httpget))) == NULL) {
|
||||
warn("calloc");
|
||||
http_close(x);
|
||||
http_free(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g->headpart = headr;
|
||||
g->headpartsz = headrsz;
|
||||
g->bodypart = bod;
|
||||
g->bodypartsz = bodsz;
|
||||
g->head = head;
|
||||
g->headsz = headsz;
|
||||
g->code = code;
|
||||
g->xfer = x;
|
||||
g->http = h;
|
||||
return g;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
struct httpget *g;
|
||||
struct httphead *httph;
|
||||
size_t i, httphsz;
|
||||
struct source addrs[2];
|
||||
size_t addrsz;
|
||||
|
||||
#if 0
|
||||
addrs[0].ip = "127.0.0.1";
|
||||
addrs[0].family = 4;
|
||||
addrsz = 1;
|
||||
#else
|
||||
addrs[0].ip = "2a00:1450:400a:806::2004";
|
||||
addrs[0].family = 6;
|
||||
addrs[1].ip = "193.135.3.123";
|
||||
addrs[1].family = 4;
|
||||
addrsz = 2;
|
||||
#endif
|
||||
|
||||
if (http_init() == -1)
|
||||
errx(EXIT_FAILURE, "http_init");
|
||||
|
||||
#if 0
|
||||
g = http_get(addrs, addrsz, "localhost", 80, "/index.html");
|
||||
#else
|
||||
g = http_get(addrs, addrsz, "www.google.ch", 80, "/index.html",
|
||||
NULL, 0);
|
||||
#endif
|
||||
|
||||
if (g == NULL)
|
||||
errx(EXIT_FAILURE, "http_get");
|
||||
|
||||
httph = http_head_parse(g->http, g->xfer, &httphsz);
|
||||
warnx("code: %d", g->code);
|
||||
|
||||
for (i = 0; i < httphsz; i++)
|
||||
warnx("head: [%s]=[%s]", httph[i].key, httph[i].val);
|
||||
|
||||
http_get_free(g);
|
||||
return (EXIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
@@ -1,92 +0,0 @@
|
||||
/* $Id: http.h,v 1.3 2017/01/25 13:52:53 inoguchi Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv>
|
||||
*
|
||||
* 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 AUTHORS DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
|
||||
*/
|
||||
#ifndef HTTP_H
|
||||
#define HTTP_H
|
||||
|
||||
struct source {
|
||||
int family; /* 4 (PF_INET) or 6 (PF_INET6) */
|
||||
char *ip; /* IPV4 or IPV6 address */
|
||||
};
|
||||
|
||||
struct http;
|
||||
|
||||
/*
|
||||
* Write and read callbacks to allow HTTP and HTTPS.
|
||||
* Both of these return the number of bytes read (or written) or -1 on
|
||||
* failure.
|
||||
* 0 bytes read means that the connection has closed.
|
||||
*/
|
||||
typedef ssize_t (*writefp)(const void *, size_t, const struct http *);
|
||||
typedef ssize_t (*readfp)(char *, size_t, const struct http *);
|
||||
|
||||
/*
|
||||
* HTTP/S header pair.
|
||||
* There's also a cooked-up pair, "Status", with the status code.
|
||||
* Both strings are NUL-terminated.
|
||||
*/
|
||||
struct httphead {
|
||||
const char *key;
|
||||
const char *val;
|
||||
};
|
||||
|
||||
/*
|
||||
* Grab all information from a transfer.
|
||||
* DO NOT free any parts of this, and editing the parts (e.g., changing
|
||||
* the underlying strings) will persist; so in short, don't.
|
||||
* All of these values will be set upon http_get() success.
|
||||
*/
|
||||
struct httpget {
|
||||
struct httpxfer *xfer; /* underlying transfer */
|
||||
struct http *http; /* underlying connection */
|
||||
int code; /* return code */
|
||||
struct httphead *head; /* headers */
|
||||
size_t headsz; /* number of headers */
|
||||
char *headpart; /* header buffer */
|
||||
size_t headpartsz; /* size of headpart */
|
||||
char *bodypart; /* body buffer */
|
||||
size_t bodypartsz; /* size of bodypart */
|
||||
};
|
||||
|
||||
int http_init(void);
|
||||
|
||||
/* Convenience functions. */
|
||||
struct httpget *http_get(const struct source *, size_t,
|
||||
const char *, short, const char *,
|
||||
const void *, size_t);
|
||||
void http_get_free(struct httpget *);
|
||||
|
||||
/* Allocation and release. */
|
||||
struct http *http_alloc(const struct source *, size_t,
|
||||
const char *, short, const char *);
|
||||
void http_free(struct http *);
|
||||
struct httpxfer *http_open(const struct http *, const void *, size_t);
|
||||
void http_close(struct httpxfer *);
|
||||
void http_disconnect(struct http *);
|
||||
|
||||
/* Access. */
|
||||
char *http_head_read(const struct http *,
|
||||
struct httpxfer *, size_t *);
|
||||
struct httphead *http_head_parse(const struct http *,
|
||||
struct httpxfer *, size_t *);
|
||||
char *http_body_read(const struct http *,
|
||||
struct httpxfer *, size_t *);
|
||||
int http_head_status(const struct http *,
|
||||
struct httphead *, size_t);
|
||||
struct httphead *http_head_get(const char *,
|
||||
struct httphead *, size_t);
|
||||
|
||||
#endif /* HTTP_H */
|
||||
@@ -1,761 +0,0 @@
|
||||
/* $OpenBSD: ocspcheck.c,v 1.31 2022/12/28 21:30:17 jmc Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017,2020 Bob Beck <beck@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 AUTHORS DISCLAIM ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ocsp.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "http.h"
|
||||
|
||||
#define MAXAGE_SEC (14*24*60*60)
|
||||
#define JITTER_SEC (60)
|
||||
#define OCSP_MAX_RESPONSE_SIZE (20480)
|
||||
|
||||
typedef struct ocsp_request {
|
||||
STACK_OF(X509) *fullchain;
|
||||
OCSP_REQUEST *req;
|
||||
char *url;
|
||||
unsigned char *data;
|
||||
size_t size;
|
||||
int nonce;
|
||||
} ocsp_request;
|
||||
|
||||
int verbose;
|
||||
#define vspew(fmt, ...) \
|
||||
do { if (verbose >= 1) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
|
||||
#define dspew(fmt, ...) \
|
||||
do { if (verbose >= 2) fprintf(stderr, fmt, __VA_ARGS__); } while (0)
|
||||
|
||||
#define MAX_SERVERS_DNS 8
|
||||
|
||||
struct addr {
|
||||
int family; /* 4 for PF_INET, 6 for PF_INET6 */
|
||||
char ip[INET6_ADDRSTRLEN];
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
host_dns(const char *s, struct addr vec[MAX_SERVERS_DNS])
|
||||
{
|
||||
struct addrinfo hints, *res0, *res;
|
||||
int error;
|
||||
ssize_t vecsz;
|
||||
struct sockaddr *sa;
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM; /* DUMMY */
|
||||
|
||||
error = getaddrinfo(s, NULL, &hints, &res0);
|
||||
|
||||
if (error == EAI_AGAIN ||
|
||||
#ifdef EAI_NODATA
|
||||
error == EAI_NODATA ||
|
||||
#endif
|
||||
error == EAI_NONAME)
|
||||
return 0;
|
||||
|
||||
if (error) {
|
||||
warnx("%s: parse error: %s", s, gai_strerror(error));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (vecsz = 0, res = res0;
|
||||
res != NULL && vecsz < MAX_SERVERS_DNS;
|
||||
res = res->ai_next) {
|
||||
if (res->ai_family != AF_INET &&
|
||||
res->ai_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
sa = res->ai_addr;
|
||||
|
||||
if (res->ai_family == AF_INET) {
|
||||
vec[vecsz].family = 4;
|
||||
inet_ntop(AF_INET,
|
||||
&(((struct sockaddr_in *)sa)->sin_addr),
|
||||
vec[vecsz].ip, INET6_ADDRSTRLEN);
|
||||
} else {
|
||||
vec[vecsz].family = 6;
|
||||
inet_ntop(AF_INET6,
|
||||
&(((struct sockaddr_in6 *)sa)->sin6_addr),
|
||||
vec[vecsz].ip, INET6_ADDRSTRLEN);
|
||||
}
|
||||
|
||||
dspew("DNS returns %s for %s\n", vec[vecsz].ip, s);
|
||||
vecsz++;
|
||||
}
|
||||
|
||||
freeaddrinfo(res0);
|
||||
return vecsz;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the domain and port from a URL.
|
||||
* The url must be formatted as schema://address[/stuff].
|
||||
* This returns NULL on failure.
|
||||
*/
|
||||
static char *
|
||||
url2host(const char *host, short *port, char **path)
|
||||
{
|
||||
char *url, *ep;
|
||||
|
||||
/* We only understand HTTP and HTTPS. */
|
||||
|
||||
if (strncmp(host, "https://", 8) == 0) {
|
||||
*port = 443;
|
||||
if ((url = strdup(host + 8)) == NULL) {
|
||||
warn("strdup");
|
||||
return (NULL);
|
||||
}
|
||||
} else if (strncmp(host, "http://", 7) == 0) {
|
||||
*port = 80;
|
||||
if ((url = strdup(host + 7)) == NULL) {
|
||||
warn("strdup");
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
warnx("%s: unknown schema", host);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Terminate path part. */
|
||||
|
||||
if ((ep = strchr(url, '/')) != NULL) {
|
||||
*path = strdup(ep);
|
||||
*ep = '\0';
|
||||
} else
|
||||
*path = strdup("/");
|
||||
|
||||
if (*path == NULL) {
|
||||
warn("strdup");
|
||||
free(url);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Check to see if there is a port in the url */
|
||||
if ((ep = strchr(url, ':')) != NULL) {
|
||||
const char *errstr;
|
||||
short pp;
|
||||
pp = strtonum(ep + 1, 1, SHRT_MAX, &errstr);
|
||||
if (errstr != NULL) {
|
||||
warnx("error parsing port from '%s': %s", url, errstr);
|
||||
free(url);
|
||||
free(*path);
|
||||
return NULL;
|
||||
}
|
||||
*port = pp;
|
||||
*ep = '\0';
|
||||
}
|
||||
|
||||
return (url);
|
||||
}
|
||||
|
||||
static time_t
|
||||
parse_ocsp_time(ASN1_GENERALIZEDTIME *gt)
|
||||
{
|
||||
struct tm tm;
|
||||
time_t rv = -1;
|
||||
|
||||
if (gt == NULL)
|
||||
return -1;
|
||||
/* RFC 6960 specifies that all times in OCSP must be GENERALIZEDTIME */
|
||||
if (ASN1_time_parse(gt->data, gt->length, &tm,
|
||||
V_ASN1_GENERALIZEDTIME) == -1)
|
||||
return -1;
|
||||
if ((rv = timegm(&tm)) == -1)
|
||||
return -1;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static X509_STORE *
|
||||
read_cacerts(const char *file, const char *dir)
|
||||
{
|
||||
X509_STORE *store = NULL;
|
||||
X509_LOOKUP *lookup;
|
||||
|
||||
if (file == NULL && dir == NULL) {
|
||||
warnx("No CA certs to load");
|
||||
goto end;
|
||||
}
|
||||
if ((store = X509_STORE_new()) == NULL) {
|
||||
warnx("Malloc failed");
|
||||
goto end;
|
||||
}
|
||||
if (file != NULL) {
|
||||
if ((lookup = X509_STORE_add_lookup(store,
|
||||
X509_LOOKUP_file())) == NULL) {
|
||||
warnx("Unable to load CA cert file");
|
||||
goto end;
|
||||
}
|
||||
if (!X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM)) {
|
||||
warnx("Unable to load CA certs from file %s", file);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (dir != NULL) {
|
||||
if ((lookup = X509_STORE_add_lookup(store,
|
||||
X509_LOOKUP_hash_dir())) == NULL) {
|
||||
warnx("Unable to load CA cert directory");
|
||||
goto end;
|
||||
}
|
||||
if (!X509_LOOKUP_add_dir(lookup, dir, X509_FILETYPE_PEM)) {
|
||||
warnx("Unable to load CA certs from directory %s", dir);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
return store;
|
||||
|
||||
end:
|
||||
X509_STORE_free(store);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static STACK_OF(X509) *
|
||||
read_fullchain(const char *file, int *count)
|
||||
{
|
||||
int i;
|
||||
BIO *bio;
|
||||
STACK_OF(X509_INFO) *xis = NULL;
|
||||
X509_INFO *xi;
|
||||
STACK_OF(X509) *rv = NULL;
|
||||
|
||||
*count = 0;
|
||||
|
||||
if ((bio = BIO_new_file(file, "r")) == NULL) {
|
||||
warn("Unable to read a certificate from %s", file);
|
||||
goto end;
|
||||
}
|
||||
if ((xis = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL)) == NULL) {
|
||||
warnx("Unable to read PEM format from %s", file);
|
||||
goto end;
|
||||
}
|
||||
if (sk_X509_INFO_num(xis) <= 0) {
|
||||
warnx("No certificates in file %s", file);
|
||||
goto end;
|
||||
}
|
||||
if ((rv = sk_X509_new_null()) == NULL) {
|
||||
warnx("malloc failed");
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_X509_INFO_num(xis); i++) {
|
||||
xi = sk_X509_INFO_value(xis, i);
|
||||
if (xi->x509 == NULL)
|
||||
continue;
|
||||
if (!sk_X509_push(rv, xi->x509)) {
|
||||
warnx("unable to build x509 chain");
|
||||
sk_X509_pop_free(rv, X509_free);
|
||||
rv = NULL;
|
||||
goto end;
|
||||
}
|
||||
xi->x509 = NULL;
|
||||
(*count)++;
|
||||
}
|
||||
end:
|
||||
BIO_free(bio);
|
||||
sk_X509_INFO_pop_free(xis, X509_INFO_free);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static inline X509 *
|
||||
cert_from_chain(STACK_OF(X509) *fullchain)
|
||||
{
|
||||
return sk_X509_value(fullchain, 0);
|
||||
}
|
||||
|
||||
static const X509 *
|
||||
issuer_from_chain(STACK_OF(X509) *fullchain)
|
||||
{
|
||||
const X509 *cert;
|
||||
X509_NAME *issuer_name;
|
||||
|
||||
cert = cert_from_chain(fullchain);
|
||||
if ((issuer_name = X509_get_issuer_name(cert)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return X509_find_by_subject(fullchain, issuer_name);
|
||||
}
|
||||
|
||||
static ocsp_request *
|
||||
ocsp_request_new_from_cert(const char *cadir, char *file, int nonce)
|
||||
{
|
||||
X509 *cert;
|
||||
int count = 0;
|
||||
OCSP_CERTID *id = NULL;
|
||||
ocsp_request *request = NULL;
|
||||
const EVP_MD *cert_id_md = NULL;
|
||||
const X509 *issuer;
|
||||
STACK_OF(OPENSSL_STRING) *urls = NULL;
|
||||
|
||||
if ((request = calloc(1, sizeof(ocsp_request))) == NULL) {
|
||||
warn("malloc");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((request->req = OCSP_REQUEST_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
request->fullchain = read_fullchain(file, &count);
|
||||
if (cadir == NULL) {
|
||||
/* Drop rpath from pledge, we don't need to read anymore */
|
||||
if (pledge("stdio inet dns", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
}
|
||||
if (request->fullchain == NULL) {
|
||||
warnx("Unable to read cert chain from file %s", file);
|
||||
goto err;
|
||||
}
|
||||
if (count <= 1) {
|
||||
warnx("File %s does not contain a cert chain", file);
|
||||
goto err;
|
||||
}
|
||||
if ((cert = cert_from_chain(request->fullchain)) == NULL) {
|
||||
warnx("No certificate found in %s", file);
|
||||
goto err;
|
||||
}
|
||||
if ((issuer = issuer_from_chain(request->fullchain)) == NULL) {
|
||||
warnx("Unable to find issuer for cert in %s", file);
|
||||
goto err;
|
||||
}
|
||||
|
||||
urls = X509_get1_ocsp(cert);
|
||||
if (urls == NULL || sk_OPENSSL_STRING_num(urls) <= 0) {
|
||||
warnx("Certificate in %s contains no OCSP url", file);
|
||||
goto err;
|
||||
}
|
||||
if ((request->url = strdup(sk_OPENSSL_STRING_value(urls, 0))) == NULL)
|
||||
goto err;
|
||||
X509_email_free(urls);
|
||||
urls = NULL;
|
||||
|
||||
cert_id_md = EVP_sha1(); /* XXX. This sucks but OCSP is poopy */
|
||||
if ((id = OCSP_cert_to_id(cert_id_md, cert, issuer)) == NULL) {
|
||||
warnx("Unable to get certificate id from cert in %s", file);
|
||||
goto err;
|
||||
}
|
||||
if (OCSP_request_add0_id(request->req, id) == NULL) {
|
||||
warnx("Unable to add certificate id to request");
|
||||
goto err;
|
||||
}
|
||||
id = NULL;
|
||||
|
||||
request->nonce = nonce;
|
||||
if (request->nonce)
|
||||
OCSP_request_add1_nonce(request->req, NULL, -1);
|
||||
|
||||
if ((request->size = i2d_OCSP_REQUEST(request->req,
|
||||
&request->data)) <= 0) {
|
||||
warnx("Unable to encode ocsp request");
|
||||
goto err;
|
||||
}
|
||||
if (request->data == NULL) {
|
||||
warnx("Unable to allocate memory");
|
||||
goto err;
|
||||
}
|
||||
return request;
|
||||
|
||||
err:
|
||||
if (request != NULL) {
|
||||
sk_X509_pop_free(request->fullchain, X509_free);
|
||||
free(request->url);
|
||||
OCSP_REQUEST_free(request->req);
|
||||
free(request->data);
|
||||
}
|
||||
X509_email_free(urls);
|
||||
OCSP_CERTID_free(id);
|
||||
free(request);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
validate_response(char *buf, size_t size, ocsp_request *request,
|
||||
X509_STORE *store, char *host, char *file)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *revtime = NULL, *thisupd = NULL, *nextupd = NULL;
|
||||
const unsigned char **p = (const unsigned char **)&buf;
|
||||
int status, cert_status = 0, crl_reason = 0;
|
||||
time_t now, rev_t = -1, this_t, next_t;
|
||||
OCSP_RESPONSE *resp = NULL;
|
||||
OCSP_BASICRESP *bresp = NULL;
|
||||
OCSP_CERTID *cid = NULL;
|
||||
const X509 *cert, *issuer;
|
||||
int ret = 0;
|
||||
|
||||
if ((cert = cert_from_chain(request->fullchain)) == NULL) {
|
||||
warnx("No certificate found in %s", file);
|
||||
goto err;
|
||||
}
|
||||
if ((issuer = issuer_from_chain(request->fullchain)) == NULL) {
|
||||
warnx("Unable to find certificate issuer for cert in %s", file);
|
||||
goto err;
|
||||
}
|
||||
if ((cid = OCSP_cert_to_id(NULL, cert, issuer)) == NULL) {
|
||||
warnx("Unable to get issuer cert/CID in %s", file);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((resp = d2i_OCSP_RESPONSE(NULL, p, size)) == NULL) {
|
||||
warnx("OCSP response unserializable from host %s", host);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((bresp = OCSP_response_get1_basic(resp)) == NULL) {
|
||||
warnx("Failed to load OCSP response from %s", host);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (OCSP_basic_verify(bresp, request->fullchain, store,
|
||||
OCSP_TRUSTOTHER) != 1) {
|
||||
warnx("OCSP verify failed from %s", host);
|
||||
goto err;
|
||||
}
|
||||
dspew("OCSP response signature validated from %s\n", host);
|
||||
|
||||
status = OCSP_response_status(resp);
|
||||
if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
|
||||
warnx("OCSP Failure: code %d (%s) from host %s",
|
||||
status, OCSP_response_status_str(status), host);
|
||||
goto err;
|
||||
}
|
||||
dspew("OCSP response status %d from host %s\n", status, host);
|
||||
|
||||
/* Check the nonce if we sent one */
|
||||
|
||||
if (request->nonce) {
|
||||
if (OCSP_check_nonce(request->req, bresp) <= 0) {
|
||||
warnx("No OCSP nonce, or mismatch, from host %s", host);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (OCSP_resp_find_status(bresp, cid, &cert_status, &crl_reason,
|
||||
&revtime, &thisupd, &nextupd) != 1) {
|
||||
warnx("OCSP verify failed: no result for cert");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (revtime && (rev_t = parse_ocsp_time(revtime)) == -1) {
|
||||
warnx("Unable to parse revocation time in OCSP reply");
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Belt and suspenders, Treat it as revoked if there is either
|
||||
* a revocation time, or status revoked.
|
||||
*/
|
||||
if (rev_t != -1 || cert_status == V_OCSP_CERTSTATUS_REVOKED) {
|
||||
warnx("Invalid OCSP reply: certificate is revoked");
|
||||
if (rev_t != -1)
|
||||
warnx("Certificate revoked at: %s", ctime(&rev_t));
|
||||
goto err;
|
||||
}
|
||||
if ((this_t = parse_ocsp_time(thisupd)) == -1) {
|
||||
warnx("unable to parse this update time in OCSP reply");
|
||||
goto err;
|
||||
}
|
||||
if ((next_t = parse_ocsp_time(nextupd)) == -1) {
|
||||
warnx("unable to parse next update time in OCSP reply");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Don't allow this update to precede next update */
|
||||
if (this_t >= next_t) {
|
||||
warnx("Invalid OCSP reply: this update >= next update");
|
||||
goto err;
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
/*
|
||||
* Check that this update is not more than JITTER seconds
|
||||
* in the future.
|
||||
*/
|
||||
if (this_t > now + JITTER_SEC) {
|
||||
warnx("Invalid OCSP reply: this update is in the future at %s",
|
||||
ctime(&this_t));
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that this update is not more than MAXSEC
|
||||
* in the past.
|
||||
*/
|
||||
if (this_t < now - MAXAGE_SEC) {
|
||||
warnx("Invalid OCSP reply: this update is too old %s",
|
||||
ctime(&this_t));
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that next update is still valid
|
||||
*/
|
||||
if (next_t < now - JITTER_SEC) {
|
||||
warnx("Invalid OCSP reply: reply has expired at %s",
|
||||
ctime(&next_t));
|
||||
goto err;
|
||||
}
|
||||
|
||||
vspew("OCSP response validated from %s\n", host);
|
||||
vspew(" This Update: %s", ctime(&this_t));
|
||||
vspew(" Next Update: %s", ctime(&next_t));
|
||||
ret = 1;
|
||||
err:
|
||||
OCSP_RESPONSE_free(resp);
|
||||
OCSP_BASICRESP_free(bresp);
|
||||
OCSP_CERTID_free(cid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: ocspcheck [-Nv] [-C CAfile] [-i staplefile] "
|
||||
"[-o staplefile] file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *cafile = NULL, *cadir = NULL;
|
||||
char *host = NULL, *path = NULL, *certfile = NULL, *outfile = NULL,
|
||||
*instaple = NULL, *infile = NULL;
|
||||
struct addr addrs[MAX_SERVERS_DNS] = {{0}};
|
||||
struct source sources[MAX_SERVERS_DNS];
|
||||
int i, ch, staplefd = -1, infd = -1, nonce = 1;
|
||||
ocsp_request *request = NULL;
|
||||
size_t rescount, httphsz = 0, instaplesz = 0;
|
||||
struct httphead *httph = NULL;
|
||||
struct httpget *hget;
|
||||
X509_STORE *castore;
|
||||
ssize_t written, w;
|
||||
short port;
|
||||
|
||||
while ((ch = getopt(argc, argv, "C:i:No:v")) != -1) {
|
||||
switch (ch) {
|
||||
case 'C':
|
||||
cafile = optarg;
|
||||
break;
|
||||
case 'N':
|
||||
nonce = 0;
|
||||
break;
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
infile = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1 || (certfile = argv[0]) == NULL)
|
||||
usage();
|
||||
|
||||
if (outfile != NULL) {
|
||||
if (strcmp(outfile, "-") == 0)
|
||||
staplefd = STDOUT_FILENO;
|
||||
else
|
||||
staplefd = open(outfile, O_WRONLY|O_CREAT,
|
||||
S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH);
|
||||
if (staplefd < 0)
|
||||
err(1, "Unable to open output file %s", outfile);
|
||||
}
|
||||
|
||||
if (infile != NULL) {
|
||||
if (strcmp(infile, "-") == 0)
|
||||
infd = STDIN_FILENO;
|
||||
else
|
||||
infd = open(infile, O_RDONLY);
|
||||
if (infd < 0)
|
||||
err(1, "Unable to open input file %s", infile);
|
||||
nonce = 0; /* Can't validate a nonce on a saved reply */
|
||||
}
|
||||
|
||||
if (cafile == NULL) {
|
||||
if (access(X509_get_default_cert_file(), R_OK) == 0)
|
||||
cafile = X509_get_default_cert_file();
|
||||
if (access(X509_get_default_cert_dir(), F_OK) == 0)
|
||||
cadir = X509_get_default_cert_dir();
|
||||
}
|
||||
|
||||
if (cafile != NULL) {
|
||||
if (unveil(cafile, "r") == -1)
|
||||
err(1, "unveil %s", cafile);
|
||||
}
|
||||
if (cadir != NULL) {
|
||||
if (unveil(cadir, "r") == -1)
|
||||
err(1, "unveil %s", cadir);
|
||||
}
|
||||
if (unveil(certfile, "r") == -1)
|
||||
err(1, "unveil %s", certfile);
|
||||
|
||||
if (pledge("stdio inet rpath dns", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
|
||||
/*
|
||||
* Load our certificate and keystore, and build up an
|
||||
* OCSP request based on the full certificate chain
|
||||
* we have been given to check.
|
||||
*/
|
||||
if ((castore = read_cacerts(cafile, cadir)) == NULL)
|
||||
exit(1);
|
||||
if ((request = ocsp_request_new_from_cert(cadir, certfile, nonce))
|
||||
== NULL)
|
||||
exit(1);
|
||||
|
||||
dspew("Built an %zu byte ocsp request\n", request->size);
|
||||
|
||||
if ((host = url2host(request->url, &port, &path)) == NULL)
|
||||
errx(1, "Invalid OCSP url %s from %s", request->url,
|
||||
certfile);
|
||||
|
||||
if (infd == -1) {
|
||||
/* Get a new OCSP response from the indicated server */
|
||||
|
||||
vspew("Using %s to host %s, port %d, path %s\n",
|
||||
port == 443 ? "https" : "http", host, port, path);
|
||||
|
||||
rescount = host_dns(host, addrs);
|
||||
for (i = 0; i < rescount; i++) {
|
||||
sources[i].ip = addrs[i].ip;
|
||||
sources[i].family = addrs[i].family;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do an HTTP post to send our request to the OCSP
|
||||
* server, and hopefully get an answer back
|
||||
*/
|
||||
hget = http_get(sources, rescount, host, port, path,
|
||||
request->data, request->size);
|
||||
if (hget == NULL)
|
||||
errx(1, "http_get");
|
||||
/*
|
||||
* Pledge minimally before fiddling with libcrypto init
|
||||
* routines and parsing untrusted input from someone's OCSP
|
||||
* server.
|
||||
*/
|
||||
if (cadir == NULL) {
|
||||
if (pledge("stdio", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
} else {
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
}
|
||||
|
||||
dspew("Server at %s returns:\n", host);
|
||||
for (i = 0; i < httphsz; i++)
|
||||
dspew(" [%s]=[%s]\n", httph[i].key, httph[i].val);
|
||||
dspew(" [Body]=[%zu bytes]\n", hget->bodypartsz);
|
||||
if (hget->bodypartsz <= 0)
|
||||
errx(1, "No body in reply from %s", host);
|
||||
|
||||
if (hget->code != 200)
|
||||
errx(1, "http reply code %d from %s", hget->code, host);
|
||||
|
||||
/*
|
||||
* Validate the OCSP response we got back
|
||||
*/
|
||||
OPENSSL_add_all_algorithms_noconf();
|
||||
if (!validate_response(hget->bodypart, hget->bodypartsz,
|
||||
request, castore, host, certfile))
|
||||
exit(1);
|
||||
instaple = hget->bodypart;
|
||||
instaplesz = hget->bodypartsz;
|
||||
} else {
|
||||
size_t nr = 0;
|
||||
instaplesz = 0;
|
||||
|
||||
/*
|
||||
* Pledge minimally before fiddling with libcrypto init
|
||||
*/
|
||||
if (cadir == NULL) {
|
||||
if (pledge("stdio", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
} else {
|
||||
if (pledge("stdio rpath", NULL) == -1)
|
||||
err(1, "pledge");
|
||||
}
|
||||
|
||||
dspew("Using ocsp response saved in %s:\n", infile);
|
||||
|
||||
/* Use the existing OCSP response saved in infd */
|
||||
instaple = calloc(OCSP_MAX_RESPONSE_SIZE, 1);
|
||||
if (instaple) {
|
||||
while ((nr = read(infd, instaple + instaplesz,
|
||||
OCSP_MAX_RESPONSE_SIZE - instaplesz)) != -1 &&
|
||||
nr != 0)
|
||||
instaplesz += nr;
|
||||
}
|
||||
if (instaplesz == 0)
|
||||
exit(1);
|
||||
/*
|
||||
* Validate the OCSP staple we read in.
|
||||
*/
|
||||
OPENSSL_add_all_algorithms_noconf();
|
||||
if (!validate_response(instaple, instaplesz,
|
||||
request, castore, host, certfile))
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have been given a place to save a staple,
|
||||
* write out the DER format response to the staplefd
|
||||
*/
|
||||
if (staplefd >= 0) {
|
||||
while (ftruncate(staplefd, 0) < 0) {
|
||||
if (errno == EINVAL)
|
||||
break;
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
err(1, "Write of OCSP response failed");
|
||||
}
|
||||
written = 0;
|
||||
while (written < instaplesz) {
|
||||
w = write(staplefd, instaple + written,
|
||||
instaplesz - written);
|
||||
if (w == -1) {
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
err(1, "Write of OCSP response failed");
|
||||
} else
|
||||
written += w;
|
||||
}
|
||||
close(staplefd);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
2186
apps/openssl/apps.c
2186
apps/openssl/apps.c
File diff suppressed because it is too large
Load Diff
@@ -1,324 +0,0 @@
|
||||
/* $OpenBSD: apps.h,v 1.34 2023/06/11 13:02:10 jsg Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_APPS_H
|
||||
#define HEADER_APPS_H
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/ossl_typ.h>
|
||||
#include <openssl/txt_db.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ui.h>
|
||||
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
#include <openssl/ocsp.h>
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
extern int single_execution;
|
||||
|
||||
extern CONF *config;
|
||||
extern char *default_config_file;
|
||||
extern BIO *bio_err;
|
||||
|
||||
#define PW_MIN_LENGTH 4
|
||||
typedef struct pw_cb_data {
|
||||
const void *password;
|
||||
const char *prompt_info;
|
||||
} PW_CB_DATA;
|
||||
|
||||
int password_callback(char *buf, int bufsiz, int verify, void *cb_data);
|
||||
|
||||
int setup_ui(void);
|
||||
void destroy_ui(void);
|
||||
|
||||
extern UI_METHOD *ui_method;
|
||||
int ui_open(UI *ui);
|
||||
int ui_read(UI *ui, UI_STRING *uis);
|
||||
int ui_write(UI *ui, UI_STRING *uis);
|
||||
int ui_close(UI *ui);
|
||||
|
||||
int should_retry(int i);
|
||||
int args_from_file(char *file, int *argc, char **argv[]);
|
||||
int str2fmt(char *s);
|
||||
void program_name(char *in, char *out, int size);
|
||||
#ifdef HEADER_X509_H
|
||||
int dump_cert_text(BIO *out, X509 *x);
|
||||
void print_name(BIO *out, const char *title, X509_NAME *nm,
|
||||
unsigned long lflags);
|
||||
#endif
|
||||
int set_cert_ex(unsigned long *flags, const char *arg);
|
||||
int set_name_ex(unsigned long *flags, const char *arg);
|
||||
int set_ext_copy(int *copy_type, const char *arg);
|
||||
int copy_extensions(X509 *x, X509_REQ *req, int copy_type);
|
||||
int app_passwd(BIO *err, char *arg1, char *arg2, char **pass1, char **pass2);
|
||||
int add_oid_section(BIO *err, CONF *conf);
|
||||
X509 *load_cert(BIO *err, const char *file, int format,
|
||||
const char *pass, const char *cert_descrip);
|
||||
EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
|
||||
const char *pass, const char *key_descrip);
|
||||
EVP_PKEY *load_pubkey(BIO *err, const char *file, int format, int maybe_stdin,
|
||||
const char *pass, const char *key_descrip);
|
||||
STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
|
||||
const char *pass, const char *cert_descrip);
|
||||
STACK_OF(X509_CRL) *load_crls(BIO *err, const char *file, int format,
|
||||
const char *pass, const char *cert_descrip);
|
||||
X509_STORE *setup_verify(BIO *bp, char *CAfile, char *CApath);
|
||||
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
OCSP_RESPONSE *process_responder(BIO *err, OCSP_REQUEST *req,
|
||||
char *host, char *path, char *port, int use_ssl,
|
||||
STACK_OF(CONF_VALUE) *headers, int req_timeout);
|
||||
#endif
|
||||
|
||||
int load_config(BIO *err, CONF *cnf);
|
||||
char *make_config_name(void);
|
||||
|
||||
/* Functions defined in ca.c and also used in ocsp.c */
|
||||
int unpack_revinfo(ASN1_TIME **prevtm, int *preason, ASN1_OBJECT **phold,
|
||||
ASN1_GENERALIZEDTIME **pinvtm, const char *str);
|
||||
|
||||
#define DB_type 0
|
||||
#define DB_exp_date 1
|
||||
#define DB_rev_date 2
|
||||
#define DB_serial 3 /* index - unique */
|
||||
#define DB_file 4
|
||||
#define DB_name 5 /* index - unique when active and not disabled */
|
||||
#define DB_NUMBER 6
|
||||
|
||||
#define DB_TYPE_REV 'R'
|
||||
#define DB_TYPE_EXP 'E'
|
||||
#define DB_TYPE_VAL 'V'
|
||||
#define DB_TYPE_SUSP 'S'
|
||||
|
||||
typedef struct db_attr_st {
|
||||
int unique_subject;
|
||||
} DB_ATTR;
|
||||
typedef struct ca_db_st {
|
||||
DB_ATTR attributes;
|
||||
TXT_DB *db;
|
||||
} CA_DB;
|
||||
|
||||
BIGNUM *load_serial(char *serialfile, int create, ASN1_INTEGER **retai);
|
||||
int save_serial(char *serialfile, char *suffix, BIGNUM *serial,
|
||||
ASN1_INTEGER **retai);
|
||||
int rotate_serial(char *serialfile, char *new_suffix, char *old_suffix);
|
||||
int rand_serial(BIGNUM *b, ASN1_INTEGER *ai);
|
||||
CA_DB *load_index(char *dbfile, DB_ATTR *dbattr);
|
||||
int index_index(CA_DB *db);
|
||||
int save_index(const char *dbfile, const char *suffix, CA_DB *db);
|
||||
int rotate_index(const char *dbfile, const char *new_suffix,
|
||||
const char *old_suffix);
|
||||
void free_index(CA_DB *db);
|
||||
#define index_name_cmp_noconst(a, b) \
|
||||
index_name_cmp((const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, a), \
|
||||
(const OPENSSL_CSTRING *)CHECKED_PTR_OF(OPENSSL_STRING, b))
|
||||
int index_name_cmp(const OPENSSL_CSTRING *a, const OPENSSL_CSTRING *b);
|
||||
int parse_yesno(const char *str, int def);
|
||||
|
||||
X509_NAME *parse_name(char *str, long chtype, int multirdn);
|
||||
int args_verify(char ***pargs, int *pargc, int *badarg, BIO *err,
|
||||
X509_VERIFY_PARAM **pm);
|
||||
int bio_to_mem(unsigned char **out, int maxlen, BIO *in);
|
||||
int pkey_ctrl_string(EVP_PKEY_CTX *ctx, char *value);
|
||||
int init_gen_str(BIO *err, EVP_PKEY_CTX **pctx, const char *algname,
|
||||
int do_param);
|
||||
int do_X509_sign(BIO *err, X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
int do_X509_REQ_sign(BIO *err, X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
int do_X509_CRL_sign(BIO *err, X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
|
||||
STACK_OF(OPENSSL_STRING) *sigopts);
|
||||
|
||||
unsigned char *next_protos_parse(unsigned short *outlen, const char *in);
|
||||
|
||||
#define FORMAT_UNDEF 0
|
||||
#define FORMAT_ASN1 1
|
||||
#define FORMAT_TEXT 2
|
||||
#define FORMAT_PEM 3
|
||||
|
||||
#define FORMAT_PKCS12 5
|
||||
#define FORMAT_SMIME 6
|
||||
|
||||
#define FORMAT_PEMRSA 9 /* PEM RSAPublicKey format */
|
||||
#define FORMAT_ASN1RSA 10 /* DER RSAPublicKey format */
|
||||
#define FORMAT_MSBLOB 11 /* MS Key blob format */
|
||||
#define FORMAT_PVK 12 /* MS PVK file format */
|
||||
|
||||
#define EXT_COPY_NONE 0
|
||||
#define EXT_COPY_ADD 1
|
||||
#define EXT_COPY_ALL 2
|
||||
|
||||
#define APP_PASS_LEN 1024
|
||||
|
||||
#define SERIAL_RAND_BITS 64
|
||||
|
||||
int app_isdir(const char *);
|
||||
|
||||
#define TM_RESET 0
|
||||
#define TM_GET 1
|
||||
double app_timer_real(int);
|
||||
double app_timer_user(int);
|
||||
|
||||
#define OPENSSL_NO_SSL_INTERN
|
||||
|
||||
struct option {
|
||||
const char *name;
|
||||
const char *argname;
|
||||
const char *desc;
|
||||
enum {
|
||||
OPTION_ARG,
|
||||
OPTION_ARGV_FUNC,
|
||||
OPTION_ARG_FORMAT,
|
||||
OPTION_ARG_FUNC,
|
||||
OPTION_ARG_INT,
|
||||
OPTION_ARG_LONG,
|
||||
OPTION_ARG_TIME,
|
||||
OPTION_DISCARD,
|
||||
OPTION_FUNC,
|
||||
OPTION_FLAG,
|
||||
OPTION_FLAG_ORD,
|
||||
OPTION_VALUE,
|
||||
OPTION_VALUE_AND,
|
||||
OPTION_VALUE_OR,
|
||||
OPTION_UL_VALUE_OR,
|
||||
OPTION_ORDER,
|
||||
} type;
|
||||
union {
|
||||
char **arg;
|
||||
int (*argfunc)(char *arg);
|
||||
int (*argvfunc)(int argc, char **argv, int *argsused);
|
||||
int *flag;
|
||||
int (*func)(void);
|
||||
long *lvalue;
|
||||
int *value;
|
||||
unsigned long *ulvalue;
|
||||
time_t *tvalue;
|
||||
int *order;
|
||||
} opt;
|
||||
const int value;
|
||||
const unsigned long ulvalue;
|
||||
int *order;
|
||||
};
|
||||
|
||||
void options_usage(const struct option *opts);
|
||||
int options_parse(int argc, char **argv, const struct option *opts,
|
||||
char **unnamed, int *argsused);
|
||||
|
||||
void show_cipher(const OBJ_NAME *name, void *arg);
|
||||
|
||||
int pkey_check(BIO *out, EVP_PKEY *pkey, int (check_fn)(EVP_PKEY_CTX *),
|
||||
const char *desc);
|
||||
#endif
|
||||
@@ -1,175 +0,0 @@
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Functions that need to be overridden by non-POSIX operating systems.
|
||||
*/
|
||||
|
||||
#include <sys/resource.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
double
|
||||
app_timer_real(int get)
|
||||
{
|
||||
static struct timespec start;
|
||||
struct timespec elapsed, now;
|
||||
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
if (get) {
|
||||
timespecsub(&now, &start, &elapsed);
|
||||
return elapsed.tv_sec + elapsed.tv_nsec / 1000000000.0;
|
||||
}
|
||||
start = now;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double
|
||||
app_timer_user(int get)
|
||||
{
|
||||
static struct timeval start;
|
||||
struct timeval elapsed;
|
||||
struct rusage now;
|
||||
|
||||
getrusage(RUSAGE_SELF, &now);
|
||||
if (get) {
|
||||
timersub(&now.ru_utime, &start, &elapsed);
|
||||
return elapsed.tv_sec + elapsed.tv_usec / 1000000.0;
|
||||
}
|
||||
start = now.ru_utime;
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
int
|
||||
setup_ui(void)
|
||||
{
|
||||
ui_method = UI_create_method("OpenSSL application user interface");
|
||||
UI_method_set_opener(ui_method, ui_open);
|
||||
UI_method_set_reader(ui_method, ui_read);
|
||||
UI_method_set_writer(ui_method, ui_write);
|
||||
UI_method_set_closer(ui_method, ui_close);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_ui(void)
|
||||
{
|
||||
if (ui_method) {
|
||||
UI_destroy_method(ui_method);
|
||||
ui_method = NULL;
|
||||
}
|
||||
}
|
||||
@@ -1,470 +0,0 @@
|
||||
/* $OpenBSD: asn1pars.c,v 1.16 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
/* A nice addition from Dr Stephen Henson <steve@openssl.org> to
|
||||
* add the -strparse option which parses nested binary structures
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
char *derfile;
|
||||
int dump;
|
||||
char *genconf;
|
||||
char *genstr;
|
||||
int indent;
|
||||
char *infile;
|
||||
int informat;
|
||||
unsigned int length;
|
||||
int noout;
|
||||
int offset;
|
||||
char *oidfile;
|
||||
STACK_OF(OPENSSL_STRING) *osk;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
asn1pars_opt_dlimit(char *arg)
|
||||
{
|
||||
const char *errstr;
|
||||
|
||||
cfg.dump = strtonum(arg, 1, INT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
fprintf(stderr, "-dlimit must be from 1 to INT_MAX: %s\n",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
asn1pars_opt_length(char *arg)
|
||||
{
|
||||
const char *errstr;
|
||||
|
||||
cfg.length = strtonum(arg, 1, UINT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
fprintf(stderr, "-length must be from 1 to UINT_MAX: %s\n",
|
||||
errstr);
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
asn1pars_opt_strparse(char *arg)
|
||||
{
|
||||
if (sk_OPENSSL_STRING_push(cfg.osk, arg) == 0) {
|
||||
fprintf(stderr, "-strparse cannot add argument\n");
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option asn1pars_options[] = {
|
||||
{
|
||||
.name = "dump",
|
||||
.desc = "Dump unknown data in hex form",
|
||||
.type = OPTION_VALUE,
|
||||
.value = -1,
|
||||
.opt.value = &cfg.dump,
|
||||
},
|
||||
{
|
||||
.name = "dlimit",
|
||||
.argname = "num",
|
||||
.desc = "Dump the first num bytes of unknown data in hex form",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = asn1pars_opt_dlimit,
|
||||
},
|
||||
{
|
||||
.name = "genconf",
|
||||
.argname = "file",
|
||||
.desc = "File to generate ASN.1 structure from",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.genconf,
|
||||
},
|
||||
{
|
||||
.name = "genstr",
|
||||
.argname = "string",
|
||||
.desc = "String to generate ASN.1 structure from",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.genstr,
|
||||
},
|
||||
{
|
||||
.name = "i",
|
||||
.desc = "Indent output according to depth of structures",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.indent,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "The input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "fmt",
|
||||
.desc = "Input format (DER, TXT or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "length",
|
||||
.argname = "num",
|
||||
.desc = "Number of bytes to parse (default until EOF)",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = asn1pars_opt_length,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not produce any output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "offset",
|
||||
.argname = "num",
|
||||
.desc = "Offset to begin parsing",
|
||||
.type = OPTION_ARG_INT,
|
||||
.opt.value = &cfg.offset,
|
||||
},
|
||||
{
|
||||
.name = "oid",
|
||||
.argname = "file",
|
||||
.desc = "File containing additional object identifiers (OIDs)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.oidfile,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file in DER format",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.derfile,
|
||||
},
|
||||
{
|
||||
.name = "strparse",
|
||||
.argname = "offset",
|
||||
.desc = "Parse the content octets of ASN.1 object starting at"
|
||||
" offset",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = asn1pars_opt_strparse,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
asn1pars_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: asn1parse [-i] [-dlimit num] [-dump] [-genconf file] "
|
||||
"[-genstr string]\n"
|
||||
" [-in file] [-inform fmt] [-length num] [-noout] [-offset num] "
|
||||
"[-oid file]\n"
|
||||
" [-out file] [-strparse offset]\n\n");
|
||||
options_usage(asn1pars_options);
|
||||
}
|
||||
|
||||
static int do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf);
|
||||
|
||||
int
|
||||
asn1parse_main(int argc, char **argv)
|
||||
{
|
||||
int i, j, ret = 1;
|
||||
long num, tmplen;
|
||||
BIO *in = NULL, *out = NULL, *b64 = NULL, *derout = NULL;
|
||||
char *str = NULL;
|
||||
const char *errstr = NULL;
|
||||
unsigned char *tmpbuf;
|
||||
const unsigned char *ctmpbuf;
|
||||
BUF_MEM *buf = NULL;
|
||||
ASN1_TYPE *at = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
if ((cfg.osk = sk_OPENSSL_STRING_new_null()) == NULL) {
|
||||
BIO_printf(bio_err, "Memory allocation failure\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (options_parse(argc, argv, asn1pars_options, NULL, NULL) != 0) {
|
||||
asn1pars_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
|
||||
|
||||
if (cfg.oidfile != NULL) {
|
||||
if (BIO_read_filename(in, cfg.oidfile) <= 0) {
|
||||
BIO_printf(bio_err, "problems opening %s\n",
|
||||
cfg.oidfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
OBJ_create_objects(in);
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.derfile != NULL) {
|
||||
if ((derout = BIO_new_file(cfg.derfile, "wb")) == NULL) {
|
||||
BIO_printf(bio_err, "problems opening %s\n",
|
||||
cfg.derfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if ((buf = BUF_MEM_new()) == NULL)
|
||||
goto end;
|
||||
if (!BUF_MEM_grow(buf, BUFSIZ * 8))
|
||||
goto end;
|
||||
|
||||
if (cfg.genstr != NULL || cfg.genconf) {
|
||||
num = do_generate(bio_err, cfg.genstr, cfg.genconf, buf);
|
||||
if (num < 0) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (cfg.informat == FORMAT_PEM) {
|
||||
BIO *tmp;
|
||||
|
||||
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
|
||||
goto end;
|
||||
BIO_push(b64, in);
|
||||
tmp = in;
|
||||
in = b64;
|
||||
b64 = tmp;
|
||||
}
|
||||
num = 0;
|
||||
for (;;) {
|
||||
if (!BUF_MEM_grow(buf, (int) num + BUFSIZ))
|
||||
goto end;
|
||||
i = BIO_read(in, &(buf->data[num]), BUFSIZ);
|
||||
if (i <= 0)
|
||||
break;
|
||||
num += i;
|
||||
}
|
||||
}
|
||||
str = buf->data;
|
||||
|
||||
/* If any structs to parse go through in sequence */
|
||||
|
||||
if (sk_OPENSSL_STRING_num(cfg.osk) > 0) {
|
||||
tmpbuf = (unsigned char *) str;
|
||||
tmplen = num;
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.osk); i++) {
|
||||
ASN1_TYPE *atmp;
|
||||
int typ;
|
||||
j = strtonum(sk_OPENSSL_STRING_value(cfg.osk, i),
|
||||
1, INT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
BIO_printf(bio_err,
|
||||
"'%s' is an invalid number: %s\n",
|
||||
sk_OPENSSL_STRING_value(cfg.osk, i), errstr);
|
||||
continue;
|
||||
}
|
||||
tmpbuf += j;
|
||||
tmplen -= j;
|
||||
atmp = at;
|
||||
ctmpbuf = tmpbuf;
|
||||
at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
|
||||
ASN1_TYPE_free(atmp);
|
||||
if (!at) {
|
||||
BIO_printf(bio_err, "Error parsing structure\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
typ = ASN1_TYPE_get(at);
|
||||
if (typ == V_ASN1_BOOLEAN || typ == V_ASN1_NULL ||
|
||||
typ == V_ASN1_OBJECT) {
|
||||
BIO_printf(bio_err, "Can't parse %s type\n",
|
||||
ASN1_tag2str(typ));
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
/* hmm... this is a little evil but it works */
|
||||
tmpbuf = at->value.asn1_string->data;
|
||||
tmplen = at->value.asn1_string->length;
|
||||
}
|
||||
str = (char *) tmpbuf;
|
||||
num = tmplen;
|
||||
}
|
||||
if (cfg.offset >= num) {
|
||||
BIO_printf(bio_err, "Error: offset too large\n");
|
||||
goto end;
|
||||
}
|
||||
num -= cfg.offset;
|
||||
|
||||
if (cfg.length == 0 || (long)cfg.length > num)
|
||||
cfg.length = (unsigned int) num;
|
||||
if (derout != NULL) {
|
||||
if (BIO_write(derout, str + cfg.offset,
|
||||
cfg.length) != (int)cfg.length) {
|
||||
BIO_printf(bio_err, "Error writing output\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (!cfg.noout && !ASN1_parse_dump(out,
|
||||
(unsigned char *)&str[cfg.offset], cfg.length, cfg.indent, cfg.dump)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
BIO_free(derout);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
BIO_free(b64);
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
BUF_MEM_free(buf);
|
||||
ASN1_TYPE_free(at);
|
||||
sk_OPENSSL_STRING_free(cfg.osk);
|
||||
OBJ_cleanup();
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
do_generate(BIO *bio, char *genstr, char *genconf, BUF_MEM *buf)
|
||||
{
|
||||
CONF *cnf = NULL;
|
||||
int len;
|
||||
long errline;
|
||||
unsigned char *p;
|
||||
ASN1_TYPE *atyp = NULL;
|
||||
|
||||
if (genconf) {
|
||||
cnf = NCONF_new(NULL);
|
||||
if (!NCONF_load(cnf, genconf, &errline))
|
||||
goto conferr;
|
||||
if (!genstr)
|
||||
genstr = NCONF_get_string(cnf, "default", "asn1");
|
||||
if (!genstr) {
|
||||
BIO_printf(bio, "Can't find 'asn1' in '%s'\n", genconf);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
atyp = ASN1_generate_nconf(genstr, cnf);
|
||||
NCONF_free(cnf);
|
||||
cnf = NULL;
|
||||
|
||||
if (!atyp)
|
||||
return -1;
|
||||
|
||||
len = i2d_ASN1_TYPE(atyp, NULL);
|
||||
if (len <= 0)
|
||||
goto err;
|
||||
|
||||
if (!BUF_MEM_grow(buf, len))
|
||||
goto err;
|
||||
|
||||
p = (unsigned char *) buf->data;
|
||||
|
||||
i2d_ASN1_TYPE(atyp, &p);
|
||||
|
||||
ASN1_TYPE_free(atyp);
|
||||
return len;
|
||||
|
||||
conferr:
|
||||
|
||||
if (errline > 0)
|
||||
BIO_printf(bio, "Error on line %ld of config file '%s'\n",
|
||||
errline, genconf);
|
||||
else
|
||||
BIO_printf(bio, "Error loading config file '%s'\n", genconf);
|
||||
|
||||
err:
|
||||
NCONF_free(cnf);
|
||||
ASN1_TYPE_free(atyp);
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
3042
apps/openssl/ca.c
3042
apps/openssl/ca.c
File diff suppressed because it is too large
Load Diff
@@ -1,691 +0,0 @@
|
||||
/* $OpenBSD: certhash.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014, 2015 Joel Sing <jsing@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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
static struct {
|
||||
int dryrun;
|
||||
int verbose;
|
||||
} cfg;
|
||||
|
||||
static const struct option certhash_options[] = {
|
||||
{
|
||||
.name = "n",
|
||||
.desc = "Perform a dry-run - do not make any changes",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.dryrun,
|
||||
},
|
||||
{
|
||||
.name = "v",
|
||||
.desc = "Verbose",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.verbose,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
struct hashinfo {
|
||||
char *filename;
|
||||
char *target;
|
||||
unsigned long hash;
|
||||
unsigned int index;
|
||||
unsigned char fingerprint[EVP_MAX_MD_SIZE];
|
||||
int is_crl;
|
||||
int is_dup;
|
||||
int exists;
|
||||
int changed;
|
||||
struct hashinfo *reference;
|
||||
struct hashinfo *next;
|
||||
};
|
||||
|
||||
static struct hashinfo *
|
||||
hashinfo(const char *filename, unsigned long hash, unsigned char *fingerprint)
|
||||
{
|
||||
struct hashinfo *hi;
|
||||
|
||||
if ((hi = calloc(1, sizeof(*hi))) == NULL)
|
||||
return (NULL);
|
||||
if (filename != NULL) {
|
||||
if ((hi->filename = strdup(filename)) == NULL) {
|
||||
free(hi);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
hi->hash = hash;
|
||||
if (fingerprint != NULL)
|
||||
memcpy(hi->fingerprint, fingerprint, sizeof(hi->fingerprint));
|
||||
|
||||
return (hi);
|
||||
}
|
||||
|
||||
static void
|
||||
hashinfo_free(struct hashinfo *hi)
|
||||
{
|
||||
if (hi == NULL)
|
||||
return;
|
||||
|
||||
free(hi->filename);
|
||||
free(hi->target);
|
||||
free(hi);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
hashinfo_print(struct hashinfo *hi)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("hashinfo %s %08lx %u %i\n", hi->filename, hi->hash,
|
||||
hi->index, hi->is_crl);
|
||||
for (i = 0; i < (int)EVP_MAX_MD_SIZE; i++) {
|
||||
printf("%02X%c", hi->fingerprint[i],
|
||||
(i + 1 == (int)EVP_MAX_MD_SIZE) ? '\n' : ':');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
hashinfo_compare(const void *a, const void *b)
|
||||
{
|
||||
struct hashinfo *hia = *(struct hashinfo **)a;
|
||||
struct hashinfo *hib = *(struct hashinfo **)b;
|
||||
int rv;
|
||||
|
||||
rv = hia->hash < hib->hash ? -1 : hia->hash > hib->hash;
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
rv = memcmp(hia->fingerprint, hib->fingerprint,
|
||||
sizeof(hia->fingerprint));
|
||||
if (rv != 0)
|
||||
return (rv);
|
||||
return strcmp(hia->filename, hib->filename);
|
||||
}
|
||||
|
||||
static struct hashinfo *
|
||||
hashinfo_chain(struct hashinfo *head, struct hashinfo *entry)
|
||||
{
|
||||
struct hashinfo *hi = head;
|
||||
|
||||
if (hi == NULL)
|
||||
return (entry);
|
||||
while (hi->next != NULL)
|
||||
hi = hi->next;
|
||||
hi->next = entry;
|
||||
|
||||
return (head);
|
||||
}
|
||||
|
||||
static void
|
||||
hashinfo_chain_free(struct hashinfo *hi)
|
||||
{
|
||||
struct hashinfo *next;
|
||||
|
||||
while (hi != NULL) {
|
||||
next = hi->next;
|
||||
hashinfo_free(hi);
|
||||
hi = next;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
hashinfo_chain_length(struct hashinfo *hi)
|
||||
{
|
||||
int len = 0;
|
||||
|
||||
while (hi != NULL) {
|
||||
len++;
|
||||
hi = hi->next;
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
static int
|
||||
hashinfo_chain_sort(struct hashinfo **head)
|
||||
{
|
||||
struct hashinfo **list, *entry;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if (*head == NULL)
|
||||
return (0);
|
||||
|
||||
len = hashinfo_chain_length(*head);
|
||||
if ((list = reallocarray(NULL, len, sizeof(struct hashinfo *))) == NULL)
|
||||
return (-1);
|
||||
|
||||
for (entry = *head, i = 0; entry != NULL; entry = entry->next, i++)
|
||||
list[i] = entry;
|
||||
qsort(list, len, sizeof(struct hashinfo *), hashinfo_compare);
|
||||
|
||||
*head = entry = list[0];
|
||||
for (i = 1; i < len; i++) {
|
||||
entry->next = list[i];
|
||||
entry = list[i];
|
||||
}
|
||||
entry->next = NULL;
|
||||
|
||||
free(list);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static char *
|
||||
hashinfo_linkname(struct hashinfo *hi)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
if (asprintf(&filename, "%08lx.%s%u", hi->hash,
|
||||
(hi->is_crl ? "r" : ""), hi->index) == -1)
|
||||
return (NULL);
|
||||
|
||||
return (filename);
|
||||
}
|
||||
|
||||
static int
|
||||
filename_is_hash(const char *filename)
|
||||
{
|
||||
const char *p = filename;
|
||||
|
||||
while ((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f'))
|
||||
p++;
|
||||
if (*p++ != '.')
|
||||
return (0);
|
||||
if (*p == 'r') /* CRL format. */
|
||||
p++;
|
||||
while (*p >= '0' && *p <= '9')
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
filename_is_pem(const char *filename)
|
||||
{
|
||||
const char *q, *p = filename;
|
||||
|
||||
if ((q = strchr(p, '\0')) == NULL)
|
||||
return (0);
|
||||
if ((q - p) < 4)
|
||||
return (0);
|
||||
if (strncmp((q - 4), ".pem", 4) != 0)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static struct hashinfo *
|
||||
hashinfo_from_linkname(const char *linkname, const char *target)
|
||||
{
|
||||
struct hashinfo *hi = NULL;
|
||||
const char *errstr;
|
||||
char *l, *p, *ep;
|
||||
long long val;
|
||||
|
||||
if ((l = strdup(linkname)) == NULL)
|
||||
goto err;
|
||||
if ((p = strchr(l, '.')) == NULL)
|
||||
goto err;
|
||||
*p++ = '\0';
|
||||
|
||||
if ((hi = hashinfo(linkname, 0, NULL)) == NULL)
|
||||
goto err;
|
||||
if ((hi->target = strdup(target)) == NULL)
|
||||
goto err;
|
||||
|
||||
errno = 0;
|
||||
val = strtoll(l, &ep, 16);
|
||||
if (l[0] == '\0' || *ep != '\0')
|
||||
goto err;
|
||||
if (errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN))
|
||||
goto err;
|
||||
if (val < 0 || val > ULONG_MAX)
|
||||
goto err;
|
||||
hi->hash = (unsigned long)val;
|
||||
|
||||
if (*p == 'r') {
|
||||
hi->is_crl = 1;
|
||||
p++;
|
||||
}
|
||||
|
||||
val = strtonum(p, 0, 0xffffffff, &errstr);
|
||||
if (errstr != NULL)
|
||||
goto err;
|
||||
|
||||
hi->index = (unsigned int)val;
|
||||
|
||||
goto done;
|
||||
|
||||
err:
|
||||
hashinfo_free(hi);
|
||||
hi = NULL;
|
||||
|
||||
done:
|
||||
free(l);
|
||||
|
||||
return (hi);
|
||||
}
|
||||
|
||||
static struct hashinfo *
|
||||
certhash_cert(BIO *bio, const char *filename)
|
||||
{
|
||||
unsigned char fingerprint[EVP_MAX_MD_SIZE];
|
||||
struct hashinfo *hi = NULL;
|
||||
const EVP_MD *digest;
|
||||
X509 *cert = NULL;
|
||||
unsigned long hash;
|
||||
unsigned int len;
|
||||
|
||||
if ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL)
|
||||
goto err;
|
||||
|
||||
hash = X509_subject_name_hash(cert);
|
||||
|
||||
digest = EVP_sha256();
|
||||
if (X509_digest(cert, digest, fingerprint, &len) != 1) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
hi = hashinfo(filename, hash, fingerprint);
|
||||
|
||||
err:
|
||||
X509_free(cert);
|
||||
|
||||
return (hi);
|
||||
}
|
||||
|
||||
static struct hashinfo *
|
||||
certhash_crl(BIO *bio, const char *filename)
|
||||
{
|
||||
unsigned char fingerprint[EVP_MAX_MD_SIZE];
|
||||
struct hashinfo *hi = NULL;
|
||||
const EVP_MD *digest;
|
||||
X509_CRL *crl = NULL;
|
||||
unsigned long hash;
|
||||
unsigned int len;
|
||||
|
||||
if ((crl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
hash = X509_NAME_hash(X509_CRL_get_issuer(crl));
|
||||
|
||||
digest = EVP_sha256();
|
||||
if (X509_CRL_digest(crl, digest, fingerprint, &len) != 1) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
hi = hashinfo(filename, hash, fingerprint);
|
||||
|
||||
err:
|
||||
X509_CRL_free(crl);
|
||||
|
||||
return (hi);
|
||||
}
|
||||
|
||||
static int
|
||||
certhash_addlink(struct hashinfo **links, struct hashinfo *hi)
|
||||
{
|
||||
struct hashinfo *link = NULL;
|
||||
|
||||
if ((link = hashinfo(NULL, hi->hash, hi->fingerprint)) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((link->filename = hashinfo_linkname(hi)) == NULL)
|
||||
goto err;
|
||||
|
||||
link->reference = hi;
|
||||
link->changed = 1;
|
||||
*links = hashinfo_chain(*links, link);
|
||||
hi->reference = link;
|
||||
|
||||
return (0);
|
||||
|
||||
err:
|
||||
hashinfo_free(link);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
certhash_findlink(struct hashinfo *links, struct hashinfo *hi)
|
||||
{
|
||||
struct hashinfo *link;
|
||||
|
||||
for (link = links; link != NULL; link = link->next) {
|
||||
if (link->is_crl == hi->is_crl &&
|
||||
link->hash == hi->hash &&
|
||||
link->index == hi->index &&
|
||||
link->reference == NULL) {
|
||||
link->reference = hi;
|
||||
if (link->target == NULL ||
|
||||
strcmp(link->target, hi->filename) != 0)
|
||||
link->changed = 1;
|
||||
hi->reference = link;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
certhash_index(struct hashinfo *head, const char *name)
|
||||
{
|
||||
struct hashinfo *last, *entry;
|
||||
int index = 0;
|
||||
|
||||
last = NULL;
|
||||
for (entry = head; entry != NULL; entry = entry->next) {
|
||||
if (last != NULL) {
|
||||
if (entry->hash == last->hash) {
|
||||
if (memcmp(entry->fingerprint,
|
||||
last->fingerprint,
|
||||
sizeof(entry->fingerprint)) == 0) {
|
||||
fprintf(stderr, "WARNING: duplicate %s "
|
||||
"in %s (using %s), ignoring...\n",
|
||||
name, entry->filename,
|
||||
last->filename);
|
||||
entry->is_dup = 1;
|
||||
continue;
|
||||
}
|
||||
index++;
|
||||
} else {
|
||||
index = 0;
|
||||
}
|
||||
}
|
||||
entry->index = index;
|
||||
last = entry;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
certhash_merge(struct hashinfo **links, struct hashinfo **certs,
|
||||
struct hashinfo **crls)
|
||||
{
|
||||
struct hashinfo *cert, *crl;
|
||||
|
||||
/* Pass 1 - sort and index entries. */
|
||||
if (hashinfo_chain_sort(certs) == -1)
|
||||
return (-1);
|
||||
if (hashinfo_chain_sort(crls) == -1)
|
||||
return (-1);
|
||||
certhash_index(*certs, "certificate");
|
||||
certhash_index(*crls, "CRL");
|
||||
|
||||
/* Pass 2 - map to existing links. */
|
||||
for (cert = *certs; cert != NULL; cert = cert->next) {
|
||||
if (cert->is_dup == 1)
|
||||
continue;
|
||||
certhash_findlink(*links, cert);
|
||||
}
|
||||
for (crl = *crls; crl != NULL; crl = crl->next) {
|
||||
if (crl->is_dup == 1)
|
||||
continue;
|
||||
certhash_findlink(*links, crl);
|
||||
}
|
||||
|
||||
/* Pass 3 - determine missing links. */
|
||||
for (cert = *certs; cert != NULL; cert = cert->next) {
|
||||
if (cert->is_dup == 1 || cert->reference != NULL)
|
||||
continue;
|
||||
if (certhash_addlink(links, cert) == -1)
|
||||
return (-1);
|
||||
}
|
||||
for (crl = *crls; crl != NULL; crl = crl->next) {
|
||||
if (crl->is_dup == 1 || crl->reference != NULL)
|
||||
continue;
|
||||
if (certhash_addlink(links, crl) == -1)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
certhash_link(struct dirent *dep, struct hashinfo **links)
|
||||
{
|
||||
struct hashinfo *hi = NULL;
|
||||
char target[PATH_MAX];
|
||||
struct stat sb;
|
||||
int n;
|
||||
|
||||
if (lstat(dep->d_name, &sb) == -1) {
|
||||
fprintf(stderr, "failed to stat %s\n", dep->d_name);
|
||||
return (-1);
|
||||
}
|
||||
if (!S_ISLNK(sb.st_mode))
|
||||
return (0);
|
||||
|
||||
n = readlink(dep->d_name, target, sizeof(target) - 1);
|
||||
if (n == -1) {
|
||||
fprintf(stderr, "failed to readlink %s\n", dep->d_name);
|
||||
return (-1);
|
||||
}
|
||||
if (n >= sizeof(target) - 1) {
|
||||
fprintf(stderr, "symbolic link is too long %s\n", dep->d_name);
|
||||
return (-1);
|
||||
}
|
||||
target[n] = '\0';
|
||||
|
||||
hi = hashinfo_from_linkname(dep->d_name, target);
|
||||
if (hi == NULL) {
|
||||
fprintf(stderr, "failed to get hash info %s\n", dep->d_name);
|
||||
return (-1);
|
||||
}
|
||||
hi->exists = 1;
|
||||
*links = hashinfo_chain(*links, hi);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
certhash_file(struct dirent *dep, struct hashinfo **certs,
|
||||
struct hashinfo **crls)
|
||||
{
|
||||
struct hashinfo *hi = NULL;
|
||||
int has_cert, has_crl;
|
||||
int ret = -1;
|
||||
BIO *bio = NULL;
|
||||
FILE *f;
|
||||
|
||||
has_cert = has_crl = 0;
|
||||
|
||||
if ((f = fopen(dep->d_name, "r")) == NULL) {
|
||||
fprintf(stderr, "failed to fopen %s\n", dep->d_name);
|
||||
goto err;
|
||||
}
|
||||
if ((bio = BIO_new_fp(f, BIO_CLOSE)) == NULL) {
|
||||
fprintf(stderr, "failed to create bio\n");
|
||||
fclose(f);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((hi = certhash_cert(bio, dep->d_name)) != NULL) {
|
||||
has_cert = 1;
|
||||
*certs = hashinfo_chain(*certs, hi);
|
||||
}
|
||||
|
||||
if (BIO_reset(bio) != 0) {
|
||||
fprintf(stderr, "BIO_reset failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((hi = certhash_crl(bio, dep->d_name)) != NULL) {
|
||||
has_crl = hi->is_crl = 1;
|
||||
*crls = hashinfo_chain(*crls, hi);
|
||||
}
|
||||
|
||||
if (!has_cert && !has_crl)
|
||||
fprintf(stderr, "PEM file %s does not contain a certificate "
|
||||
"or CRL, ignoring...\n", dep->d_name);
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
BIO_free(bio);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
certhash_directory(const char *path)
|
||||
{
|
||||
struct hashinfo *links = NULL, *certs = NULL, *crls = NULL, *link;
|
||||
int ret = 0;
|
||||
struct dirent *dep;
|
||||
DIR *dip = NULL;
|
||||
|
||||
if ((dip = opendir(".")) == NULL) {
|
||||
fprintf(stderr, "failed to open directory %s\n", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cfg.verbose)
|
||||
fprintf(stdout, "scanning directory %s\n", path);
|
||||
|
||||
/* Create lists of existing hash links, certs and CRLs. */
|
||||
while ((dep = readdir(dip)) != NULL) {
|
||||
if (filename_is_hash(dep->d_name)) {
|
||||
if (certhash_link(dep, &links) == -1)
|
||||
goto err;
|
||||
}
|
||||
if (filename_is_pem(dep->d_name)) {
|
||||
if (certhash_file(dep, &certs, &crls) == -1)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (certhash_merge(&links, &certs, &crls) == -1) {
|
||||
fprintf(stderr, "certhash merge failed\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Remove spurious links. */
|
||||
for (link = links; link != NULL; link = link->next) {
|
||||
if (link->exists == 0 ||
|
||||
(link->reference != NULL && link->changed == 0))
|
||||
continue;
|
||||
if (cfg.verbose)
|
||||
fprintf(stdout, "%s link %s -> %s\n",
|
||||
(cfg.dryrun ? "would remove" :
|
||||
"removing"), link->filename, link->target);
|
||||
if (cfg.dryrun)
|
||||
continue;
|
||||
if (unlink(link->filename) == -1) {
|
||||
fprintf(stderr, "failed to remove link %s\n",
|
||||
link->filename);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create missing links. */
|
||||
for (link = links; link != NULL; link = link->next) {
|
||||
if (link->exists == 1 && link->changed == 0)
|
||||
continue;
|
||||
if (cfg.verbose)
|
||||
fprintf(stdout, "%s link %s -> %s\n",
|
||||
(cfg.dryrun ? "would create" :
|
||||
"creating"), link->filename,
|
||||
link->reference->filename);
|
||||
if (cfg.dryrun)
|
||||
continue;
|
||||
if (symlink(link->reference->filename, link->filename) == -1) {
|
||||
fprintf(stderr, "failed to create link %s -> %s\n",
|
||||
link->filename, link->reference->filename);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
goto done;
|
||||
|
||||
err:
|
||||
ret = 1;
|
||||
|
||||
done:
|
||||
hashinfo_chain_free(certs);
|
||||
hashinfo_chain_free(crls);
|
||||
hashinfo_chain_free(links);
|
||||
|
||||
if (dip != NULL)
|
||||
closedir(dip);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
certhash_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: certhash [-nv] dir ...\n");
|
||||
options_usage(certhash_options);
|
||||
}
|
||||
|
||||
int
|
||||
certhash_main(int argc, char **argv)
|
||||
{
|
||||
int argsused;
|
||||
int i, cwdfd, ret = 0;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, certhash_options, NULL, &argsused) != 0) {
|
||||
certhash_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((cwdfd = open(".", O_RDONLY)) == -1) {
|
||||
perror("failed to open current directory");
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = argsused; i < argc; i++) {
|
||||
if (chdir(argv[i]) == -1) {
|
||||
fprintf(stderr,
|
||||
"failed to change to directory %s: %s\n",
|
||||
argv[i], strerror(errno));
|
||||
ret = 1;
|
||||
continue;
|
||||
}
|
||||
ret |= certhash_directory(argv[i]);
|
||||
if (fchdir(cwdfd) == -1) {
|
||||
perror("failed to restore current directory");
|
||||
ret = 1;
|
||||
break; /* can't continue safely */
|
||||
}
|
||||
}
|
||||
close(cwdfd);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,200 +0,0 @@
|
||||
/* $OpenBSD: ciphers.c,v 1.18 2023/03/06 14:32:05 tb Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2014 Joel Sing <jsing@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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
static struct {
|
||||
int usage;
|
||||
int use_supported;
|
||||
int verbose;
|
||||
int version;
|
||||
} cfg;
|
||||
|
||||
static const struct option ciphers_options[] = {
|
||||
{
|
||||
.name = "h",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.usage,
|
||||
},
|
||||
{
|
||||
.name = "?",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.usage,
|
||||
},
|
||||
{
|
||||
.name = "s",
|
||||
.desc = "Only list ciphers that are supported by the TLS method",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.use_supported,
|
||||
},
|
||||
{
|
||||
.name = "tls1",
|
||||
.desc = "Use TLS protocol version 1",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.version,
|
||||
.value = TLS1_VERSION,
|
||||
},
|
||||
{
|
||||
.name = "tls1_1",
|
||||
.desc = "Use TLS protocol version 1.1",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.version,
|
||||
.value = TLS1_1_VERSION,
|
||||
},
|
||||
{
|
||||
.name = "tls1_2",
|
||||
.desc = "Use TLS protocol version 1.2",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.version,
|
||||
.value = TLS1_2_VERSION,
|
||||
},
|
||||
{
|
||||
.name = "tls1_3",
|
||||
.desc = "Use TLS protocol version 1.3",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.version,
|
||||
.value = TLS1_3_VERSION,
|
||||
},
|
||||
{
|
||||
.name = "v",
|
||||
.desc = "Provide cipher listing",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.verbose,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "V",
|
||||
.desc = "Provide cipher listing with cipher suite values",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.verbose,
|
||||
.value = 2,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
ciphers_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: ciphers [-hsVv] [-tls1] [-tls1_1] [-tls1_2] "
|
||||
"[-tls1_3] [cipherlist]\n");
|
||||
options_usage(ciphers_options);
|
||||
}
|
||||
|
||||
int
|
||||
ciphers_main(int argc, char **argv)
|
||||
{
|
||||
char *cipherlist = NULL;
|
||||
STACK_OF(SSL_CIPHER) *ciphers;
|
||||
STACK_OF(SSL_CIPHER) *supported_ciphers = NULL;
|
||||
const SSL_CIPHER *cipher;
|
||||
SSL_CTX *ssl_ctx = NULL;
|
||||
SSL *ssl = NULL;
|
||||
uint16_t value;
|
||||
int i, rv = 0;
|
||||
char *desc;
|
||||
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, ciphers_options, &cipherlist,
|
||||
NULL) != 0) {
|
||||
ciphers_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (cfg.usage) {
|
||||
ciphers_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((ssl_ctx = SSL_CTX_new(TLS_method())) == NULL)
|
||||
goto err;
|
||||
|
||||
if (cfg.version != 0) {
|
||||
if (!SSL_CTX_set_min_proto_version(ssl_ctx,
|
||||
cfg.version))
|
||||
goto err;
|
||||
if (!SSL_CTX_set_max_proto_version(ssl_ctx,
|
||||
cfg.version))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cipherlist != NULL) {
|
||||
if (SSL_CTX_set_cipher_list(ssl_ctx, cipherlist) == 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((ssl = SSL_new(ssl_ctx)) == NULL)
|
||||
goto err;
|
||||
|
||||
if (cfg.use_supported) {
|
||||
if ((supported_ciphers =
|
||||
SSL_get1_supported_ciphers(ssl)) == NULL)
|
||||
goto err;
|
||||
ciphers = supported_ciphers;
|
||||
} else {
|
||||
if ((ciphers = SSL_get_ciphers(ssl)) == NULL)
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) {
|
||||
cipher = sk_SSL_CIPHER_value(ciphers, i);
|
||||
if (cfg.verbose == 0) {
|
||||
fprintf(stdout, "%s%s", (i ? ":" : ""),
|
||||
SSL_CIPHER_get_name(cipher));
|
||||
continue;
|
||||
}
|
||||
if (cfg.verbose > 1) {
|
||||
value = SSL_CIPHER_get_value(cipher);
|
||||
fprintf(stdout, "%-*s0x%02X,0x%02X - ", 10, "",
|
||||
((value >> 8) & 0xff), (value & 0xff));
|
||||
}
|
||||
desc = SSL_CIPHER_description(cipher, NULL, 0);
|
||||
if (strcmp(desc, "OPENSSL_malloc Error") == 0) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
goto err;
|
||||
}
|
||||
fprintf(stdout, "%s", desc);
|
||||
free(desc);
|
||||
}
|
||||
if (cfg.verbose == 0)
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
goto done;
|
||||
|
||||
err:
|
||||
ERR_print_errors_fp(stderr);
|
||||
rv = 1;
|
||||
|
||||
done:
|
||||
sk_SSL_CIPHER_free(supported_ciphers);
|
||||
SSL_CTX_free(ssl_ctx);
|
||||
SSL_free(ssl);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
1961
apps/openssl/cms.c
1961
apps/openssl/cms.c
File diff suppressed because it is too large
Load Diff
@@ -1,482 +0,0 @@
|
||||
/* $OpenBSD: crl.c,v 1.17 2023/03/06 14:32:05 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static struct {
|
||||
char *cafile;
|
||||
char *capath;
|
||||
int crlnumber;
|
||||
int fingerprint;
|
||||
int hash;
|
||||
int hash_old;
|
||||
char *infile;
|
||||
int informat;
|
||||
int issuer;
|
||||
int lastupdate;
|
||||
char *nameopt;
|
||||
int nextupdate;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
int verify;
|
||||
} cfg;
|
||||
|
||||
static const struct option crl_options[] = {
|
||||
{
|
||||
.name = "CAfile",
|
||||
.argname = "file",
|
||||
.desc = "Verify the CRL using certificates in the given file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.cafile,
|
||||
},
|
||||
{
|
||||
.name = "CApath",
|
||||
.argname = "path",
|
||||
.desc = "Verify the CRL using certificates in the given path",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.capath,
|
||||
},
|
||||
{
|
||||
.name = "crlnumber",
|
||||
.desc = "Print the CRL number",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.crlnumber,
|
||||
},
|
||||
{
|
||||
.name = "fingerprint",
|
||||
.desc = "Print the CRL fingerprint",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.fingerprint,
|
||||
},
|
||||
{
|
||||
.name = "hash",
|
||||
.desc = "Print the hash of the issuer name",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.hash,
|
||||
},
|
||||
{
|
||||
.name = "hash_old",
|
||||
.desc = "Print an old-style (MD5) hash of the issuer name",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.hash_old,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file to read from (stdin if unspecified)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "issuer",
|
||||
.desc = "Print the issuer name",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.issuer,
|
||||
},
|
||||
{
|
||||
.name = "lastupdate",
|
||||
.desc = "Print the lastUpdate field",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.lastupdate,
|
||||
},
|
||||
{
|
||||
.name = "nameopt",
|
||||
.argname = "options",
|
||||
.desc = "Specify certificate name options",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.nameopt,
|
||||
},
|
||||
{
|
||||
.name = "nextupdate",
|
||||
.desc = "Print the nextUpdate field",
|
||||
.type = OPTION_FLAG_ORD,
|
||||
.opt.flag = &cfg.nextupdate,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not output the encoded version of the CRL",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file to write to (stdout if unspecified)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print out the CRL in text form",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.desc = "Verify the signature on the CRL",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.verify,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
crl_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: crl [-CAfile file] [-CApath dir] [-fingerprint] [-hash]\n"
|
||||
" [-in file] [-inform DER | PEM] [-issuer] [-lastupdate]\n"
|
||||
" [-nextupdate] [-noout] [-out file] [-outform DER | PEM]\n"
|
||||
" [-text]\n\n");
|
||||
options_usage(crl_options);
|
||||
}
|
||||
|
||||
static X509_CRL *load_crl(char *file, int format);
|
||||
static BIO *bio_out = NULL;
|
||||
|
||||
int
|
||||
crl_main(int argc, char **argv)
|
||||
{
|
||||
unsigned long nmflag = 0;
|
||||
X509_CRL *x = NULL;
|
||||
int ret = 1, i;
|
||||
BIO *out = NULL;
|
||||
X509_STORE *store = NULL;
|
||||
X509_STORE_CTX *ctx = NULL;
|
||||
X509_LOOKUP *lookup = NULL;
|
||||
X509_OBJECT *xobj = NULL;
|
||||
EVP_PKEY *pkey;
|
||||
const EVP_MD *digest;
|
||||
char *digest_name = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (bio_out == NULL) {
|
||||
if ((bio_out = BIO_new(BIO_s_file())) != NULL) {
|
||||
BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
|
||||
}
|
||||
}
|
||||
|
||||
digest = EVP_sha256();
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, crl_options, &digest_name, NULL) != 0) {
|
||||
crl_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.cafile != NULL || cfg.capath != NULL)
|
||||
cfg.verify = 1;
|
||||
|
||||
if (cfg.nameopt != NULL) {
|
||||
if (set_name_ex(&nmflag, cfg.nameopt) != 1) {
|
||||
fprintf(stderr,
|
||||
"Invalid -nameopt argument '%s'\n",
|
||||
cfg.nameopt);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (digest_name != NULL) {
|
||||
if ((digest = EVP_get_digestbyname(digest_name)) == NULL) {
|
||||
fprintf(stderr,
|
||||
"Unknown message digest algorithm '%s'\n",
|
||||
digest_name);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
x = load_crl(cfg.infile, cfg.informat);
|
||||
if (x == NULL)
|
||||
goto end;
|
||||
|
||||
if (cfg.verify) {
|
||||
store = X509_STORE_new();
|
||||
if (store == NULL)
|
||||
goto end;
|
||||
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
|
||||
if (lookup == NULL)
|
||||
goto end;
|
||||
if (!X509_LOOKUP_load_file(lookup, cfg.cafile,
|
||||
X509_FILETYPE_PEM))
|
||||
X509_LOOKUP_load_file(lookup, NULL,
|
||||
X509_FILETYPE_DEFAULT);
|
||||
|
||||
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
|
||||
if (lookup == NULL)
|
||||
goto end;
|
||||
if (!X509_LOOKUP_add_dir(lookup, cfg.capath,
|
||||
X509_FILETYPE_PEM))
|
||||
X509_LOOKUP_add_dir(lookup, NULL,
|
||||
X509_FILETYPE_DEFAULT);
|
||||
ERR_clear_error();
|
||||
|
||||
if ((ctx = X509_STORE_CTX_new()) == NULL)
|
||||
goto end;
|
||||
if ((xobj = X509_OBJECT_new()) == NULL)
|
||||
goto end;
|
||||
|
||||
if (!X509_STORE_CTX_init(ctx, store, NULL, NULL)) {
|
||||
BIO_printf(bio_err,
|
||||
"Error initialising X509 store\n");
|
||||
goto end;
|
||||
}
|
||||
i = X509_STORE_get_by_subject(ctx, X509_LU_X509,
|
||||
X509_CRL_get_issuer(x), xobj);
|
||||
if (i <= 0) {
|
||||
BIO_printf(bio_err,
|
||||
"Error getting CRL issuer certificate\n");
|
||||
goto end;
|
||||
}
|
||||
pkey = X509_get_pubkey(X509_OBJECT_get0_X509(xobj));
|
||||
X509_OBJECT_free(xobj);
|
||||
xobj = NULL;
|
||||
if (!pkey) {
|
||||
BIO_printf(bio_err,
|
||||
"Error getting CRL issuer public key\n");
|
||||
goto end;
|
||||
}
|
||||
i = X509_CRL_verify(x, pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (i < 0)
|
||||
goto end;
|
||||
if (i == 0)
|
||||
BIO_printf(bio_err, "verify failure\n");
|
||||
else
|
||||
BIO_printf(bio_err, "verify OK\n");
|
||||
}
|
||||
|
||||
/* Print requested information the order that the flags were given. */
|
||||
for (i = 1; i <= argc; i++) {
|
||||
if (cfg.issuer == i) {
|
||||
print_name(bio_out, "issuer=",
|
||||
X509_CRL_get_issuer(x), nmflag);
|
||||
}
|
||||
if (cfg.crlnumber == i) {
|
||||
ASN1_INTEGER *crlnum;
|
||||
crlnum = X509_CRL_get_ext_d2i(x,
|
||||
NID_crl_number, NULL, NULL);
|
||||
BIO_printf(bio_out, "crlNumber=");
|
||||
if (crlnum) {
|
||||
i2a_ASN1_INTEGER(bio_out, crlnum);
|
||||
ASN1_INTEGER_free(crlnum);
|
||||
} else
|
||||
BIO_puts(bio_out, "<NONE>");
|
||||
BIO_printf(bio_out, "\n");
|
||||
}
|
||||
if (cfg.hash == i) {
|
||||
BIO_printf(bio_out, "%08lx\n",
|
||||
X509_NAME_hash(X509_CRL_get_issuer(x)));
|
||||
}
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
if (cfg.hash_old == i) {
|
||||
BIO_printf(bio_out, "%08lx\n",
|
||||
X509_NAME_hash_old(X509_CRL_get_issuer(x)));
|
||||
}
|
||||
#endif
|
||||
if (cfg.lastupdate == i) {
|
||||
BIO_printf(bio_out, "lastUpdate=");
|
||||
ASN1_TIME_print(bio_out,
|
||||
X509_CRL_get_lastUpdate(x));
|
||||
BIO_printf(bio_out, "\n");
|
||||
}
|
||||
if (cfg.nextupdate == i) {
|
||||
BIO_printf(bio_out, "nextUpdate=");
|
||||
if (X509_CRL_get_nextUpdate(x))
|
||||
ASN1_TIME_print(bio_out,
|
||||
X509_CRL_get_nextUpdate(x));
|
||||
else
|
||||
BIO_printf(bio_out, "NONE");
|
||||
BIO_printf(bio_out, "\n");
|
||||
}
|
||||
if (cfg.fingerprint == i) {
|
||||
int j;
|
||||
unsigned int n;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
|
||||
if (!X509_CRL_digest(x, digest, md, &n)) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_out, "%s Fingerprint=",
|
||||
OBJ_nid2sn(EVP_MD_type(digest)));
|
||||
for (j = 0; j < (int) n; j++) {
|
||||
BIO_printf(bio_out, "%02X%c", md[j],
|
||||
(j + 1 == (int)n) ? '\n' : ':');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.text)
|
||||
X509_CRL_print(out, x);
|
||||
|
||||
if (cfg.noout) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = (int) i2d_X509_CRL_bio(out, x);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_X509_CRL(out, x);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write CRL\n");
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free_all(out);
|
||||
BIO_free_all(bio_out);
|
||||
bio_out = NULL;
|
||||
X509_CRL_free(x);
|
||||
X509_STORE_CTX_free(ctx);
|
||||
X509_STORE_free(store);
|
||||
X509_OBJECT_free(xobj);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static X509_CRL *
|
||||
load_crl(char *infile, int format)
|
||||
{
|
||||
X509_CRL *x = NULL;
|
||||
BIO *in = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, infile) <= 0) {
|
||||
perror(infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (format == FORMAT_ASN1)
|
||||
x = d2i_X509_CRL_bio(in, NULL);
|
||||
else if (format == FORMAT_PEM)
|
||||
x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad input format specified for input crl\n");
|
||||
goto end;
|
||||
}
|
||||
if (x == NULL) {
|
||||
BIO_printf(bio_err, "unable to load CRL\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (x);
|
||||
}
|
||||
@@ -1,331 +0,0 @@
|
||||
/* $OpenBSD: crl2p7.c,v 1.11 2023/03/06 14:32:05 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
/* This was written by Gordon Chaffee <chaffee@plateau.cs.berkeley.edu>
|
||||
* and donated 'to the cause' along with lots and lots of other fixes to
|
||||
* the library. */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static int add_certs_from_file(STACK_OF(X509) * stack, char *certfile);
|
||||
|
||||
static struct {
|
||||
STACK_OF(OPENSSL_STRING) *certflst;
|
||||
char *infile;
|
||||
int informat;
|
||||
int nocrl;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
crl2p7_opt_certfile(char *arg)
|
||||
{
|
||||
if (cfg.certflst == NULL)
|
||||
cfg.certflst = sk_OPENSSL_STRING_new_null();
|
||||
if (cfg.certflst == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return (1);
|
||||
}
|
||||
if (!sk_OPENSSL_STRING_push(cfg.certflst, arg)) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option crl2p7_options[] = {
|
||||
{
|
||||
.name = "certfile",
|
||||
.argname = "file",
|
||||
.desc = "Chain of PEM certificates to a trusted CA",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = crl2p7_opt_certfile,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "nocrl",
|
||||
.desc = "Do not read CRL from input or include CRL in output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.nocrl,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
crl2p7_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: crl2p7 [-certfile file] [-in file] [-inform DER | PEM]\n"
|
||||
" [-nocrl] [-out file] [-outform DER | PEM]\n\n");
|
||||
options_usage(crl2p7_options);
|
||||
}
|
||||
|
||||
int
|
||||
crl2pkcs7_main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *certfile;
|
||||
PKCS7 *p7 = NULL;
|
||||
PKCS7_SIGNED *p7s = NULL;
|
||||
X509_CRL *crl = NULL;
|
||||
STACK_OF(X509_CRL) *crl_stack = NULL;
|
||||
STACK_OF(X509) *cert_stack = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, crl2p7_options, NULL, NULL) != 0) {
|
||||
crl2p7_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (!cfg.nocrl) {
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.informat == FORMAT_ASN1)
|
||||
crl = d2i_X509_CRL_bio(in, NULL);
|
||||
else if (cfg.informat == FORMAT_PEM)
|
||||
crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad input format specified for input crl\n");
|
||||
goto end;
|
||||
}
|
||||
if (crl == NULL) {
|
||||
BIO_printf(bio_err, "unable to load CRL\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if ((p7 = PKCS7_new()) == NULL)
|
||||
goto end;
|
||||
if ((p7s = PKCS7_SIGNED_new()) == NULL)
|
||||
goto end;
|
||||
p7->type = OBJ_nid2obj(NID_pkcs7_signed);
|
||||
p7->d.sign = p7s;
|
||||
p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data);
|
||||
|
||||
if (!ASN1_INTEGER_set(p7s->version, 1))
|
||||
goto end;
|
||||
if ((crl_stack = sk_X509_CRL_new_null()) == NULL)
|
||||
goto end;
|
||||
p7s->crl = crl_stack;
|
||||
if (crl != NULL) {
|
||||
sk_X509_CRL_push(crl_stack, crl);
|
||||
crl = NULL; /* now part of p7 for freeing */
|
||||
}
|
||||
if ((cert_stack = sk_X509_new_null()) == NULL)
|
||||
goto end;
|
||||
p7s->cert = cert_stack;
|
||||
|
||||
if (cfg.certflst) {
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(cfg.certflst); i++) {
|
||||
certfile = sk_OPENSSL_STRING_value(cfg.certflst, i);
|
||||
if (add_certs_from_file(cert_stack, certfile) < 0) {
|
||||
BIO_printf(bio_err,
|
||||
"error loading certificates\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sk_OPENSSL_STRING_free(cfg.certflst);
|
||||
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_PKCS7_bio(out, p7);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_PKCS7(out, p7);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write pkcs7 object\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
if (in != NULL)
|
||||
BIO_free(in);
|
||||
if (out != NULL)
|
||||
BIO_free_all(out);
|
||||
if (p7 != NULL)
|
||||
PKCS7_free(p7);
|
||||
if (crl != NULL)
|
||||
X509_CRL_free(crl);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
add_certs_from_file(STACK_OF(X509) *stack, char *certfile)
|
||||
{
|
||||
BIO *in = NULL;
|
||||
int count = 0;
|
||||
int ret = -1;
|
||||
STACK_OF(X509_INFO) *sk = NULL;
|
||||
X509_INFO *xi;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL || BIO_read_filename(in, certfile) <= 0) {
|
||||
BIO_printf(bio_err, "error opening the file, %s\n", certfile);
|
||||
goto end;
|
||||
}
|
||||
/* This loads from a file, a stack of x509/crl/pkey sets */
|
||||
sk = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
|
||||
if (sk == NULL) {
|
||||
BIO_printf(bio_err, "error reading the file, %s\n", certfile);
|
||||
goto end;
|
||||
}
|
||||
/* scan over it and pull out the CRL's */
|
||||
while (sk_X509_INFO_num(sk)) {
|
||||
xi = sk_X509_INFO_shift(sk);
|
||||
if (xi->x509 != NULL) {
|
||||
sk_X509_push(stack, xi->x509);
|
||||
xi->x509 = NULL;
|
||||
count++;
|
||||
}
|
||||
X509_INFO_free(xi);
|
||||
}
|
||||
|
||||
ret = count;
|
||||
|
||||
end:
|
||||
/* never need to free x */
|
||||
if (in != NULL)
|
||||
BIO_free(in);
|
||||
if (sk != NULL)
|
||||
sk_X509_INFO_free(sk);
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,671 +0,0 @@
|
||||
/* $OpenBSD: dgst.c,v 1.21 2023/03/06 14:32:05 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#define BUFSIZE 1024*8
|
||||
|
||||
int
|
||||
do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
|
||||
EVP_PKEY * key, unsigned char *sigin, int siglen,
|
||||
const char *sig_name, const char *md_name,
|
||||
const char *file, BIO * bmd);
|
||||
|
||||
static struct {
|
||||
int argsused;
|
||||
int debug;
|
||||
int do_verify;
|
||||
char *hmac_key;
|
||||
char *keyfile;
|
||||
int keyform;
|
||||
const EVP_MD *m;
|
||||
char *mac_name;
|
||||
STACK_OF(OPENSSL_STRING) *macopts;
|
||||
const EVP_MD *md;
|
||||
int out_bin;
|
||||
char *outfile;
|
||||
char *passargin;
|
||||
int separator;
|
||||
char *sigfile;
|
||||
STACK_OF(OPENSSL_STRING) *sigopts;
|
||||
int want_pub;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
dgst_opt_macopt(char *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return (1);
|
||||
|
||||
if (cfg.macopts == NULL &&
|
||||
(cfg.macopts = sk_OPENSSL_STRING_new_null()) == NULL)
|
||||
return (1);
|
||||
|
||||
if (!sk_OPENSSL_STRING_push(cfg.macopts, arg))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dgst_opt_md(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.m = EVP_get_digestbyname(name)) == NULL)
|
||||
return (1);
|
||||
|
||||
cfg.md = cfg.m;
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dgst_opt_prverify(char *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return (1);
|
||||
|
||||
cfg.keyfile = arg;
|
||||
cfg.do_verify = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dgst_opt_sigopt(char *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return (1);
|
||||
|
||||
if (cfg.sigopts == NULL &&
|
||||
(cfg.sigopts = sk_OPENSSL_STRING_new_null()) == NULL)
|
||||
return (1);
|
||||
|
||||
if (!sk_OPENSSL_STRING_push(cfg.sigopts, arg))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
dgst_opt_verify(char *arg)
|
||||
{
|
||||
if (arg == NULL)
|
||||
return (1);
|
||||
|
||||
cfg.keyfile = arg;
|
||||
cfg.want_pub = 1;
|
||||
cfg.do_verify = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option dgst_options[] = {
|
||||
{
|
||||
.name = "binary",
|
||||
.desc = "Output the digest or signature in binary form",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.out_bin,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "c",
|
||||
.desc = "Print the digest in two-digit groups separated by colons",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.separator,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "d",
|
||||
.desc = "Print BIO debugging information",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.debug,
|
||||
},
|
||||
{
|
||||
.name = "hex",
|
||||
.desc = "Output as hex dump",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.out_bin,
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.name = "hmac",
|
||||
.argname = "key",
|
||||
.desc = "Create hashed MAC with key",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.hmac_key,
|
||||
},
|
||||
{
|
||||
.name = "keyform",
|
||||
.argname = "format",
|
||||
.desc = "Key file format (PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.keyform,
|
||||
},
|
||||
{
|
||||
.name = "mac",
|
||||
.argname = "algorithm",
|
||||
.desc = "Create MAC (not necessarily HMAC)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.mac_name,
|
||||
},
|
||||
{
|
||||
.name = "macopt",
|
||||
.argname = "nm:v",
|
||||
.desc = "MAC algorithm parameters or key",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = dgst_opt_macopt,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output to file rather than stdout",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "arg",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "prverify",
|
||||
.argname = "file",
|
||||
.desc = "Verify a signature using private key in file",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = dgst_opt_prverify,
|
||||
},
|
||||
{
|
||||
.name = "r",
|
||||
.desc = "Output the digest in coreutils format",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.separator,
|
||||
.value = 2,
|
||||
},
|
||||
{
|
||||
.name = "sign",
|
||||
.argname = "file",
|
||||
.desc = "Sign digest using private key in file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keyfile,
|
||||
},
|
||||
{
|
||||
.name = "signature",
|
||||
.argname = "file",
|
||||
.desc = "Signature to verify",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.sigfile,
|
||||
},
|
||||
{
|
||||
.name = "sigopt",
|
||||
.argname = "nm:v",
|
||||
.desc = "Signature parameter",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = dgst_opt_sigopt,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.argname = "file",
|
||||
.desc = "Verify a signature using public key in file",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = dgst_opt_verify,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.desc = "",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = dgst_opt_md,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
|
||||
{
|
||||
const char *mname;
|
||||
/* Skip aliases */
|
||||
if (!m)
|
||||
return;
|
||||
mname = OBJ_nid2ln(EVP_MD_type(m));
|
||||
/* Skip shortnames */
|
||||
if (strcmp(from, mname))
|
||||
return;
|
||||
if (strchr(mname, ' '))
|
||||
mname = EVP_MD_name(m);
|
||||
BIO_printf(arg, " -%-17s To use the %s message digest algorithm\n",
|
||||
mname, mname);
|
||||
}
|
||||
|
||||
static void
|
||||
dgst_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: dgst [-cdr] [-binary] [-digest] [-hex]");
|
||||
fprintf(stderr, " [-hmac key] [-keyform fmt]\n");
|
||||
fprintf(stderr, " [-mac algorithm] [-macopt nm:v] [-out file]");
|
||||
fprintf(stderr, " [-passin arg]\n");
|
||||
fprintf(stderr, " [-prverify file] [-sign file]");
|
||||
fprintf(stderr, " [-signature file]\n");
|
||||
fprintf(stderr, " [-sigopt nm:v] [-verify file] [file ...]\n\n");
|
||||
options_usage(dgst_options);
|
||||
EVP_MD_do_all_sorted(list_md_fn, bio_err);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
dgst_main(int argc, char **argv)
|
||||
{
|
||||
unsigned char *buf = NULL;
|
||||
int i, err = 1;
|
||||
BIO *in = NULL, *inp;
|
||||
BIO *bmd = NULL;
|
||||
BIO *out = NULL;
|
||||
#define PROG_NAME_SIZE 39
|
||||
char pname[PROG_NAME_SIZE + 1];
|
||||
EVP_PKEY *sigkey = NULL;
|
||||
unsigned char *sigbuf = NULL;
|
||||
int siglen = 0;
|
||||
char *passin = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((buf = malloc(BUFSIZE)) == NULL) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.keyform = FORMAT_PEM;
|
||||
cfg.out_bin = -1;
|
||||
|
||||
/* first check the program name */
|
||||
program_name(argv[0], pname, sizeof pname);
|
||||
|
||||
cfg.md = EVP_get_digestbyname(pname);
|
||||
|
||||
if (options_parse(argc, argv, dgst_options, NULL,
|
||||
&cfg.argsused) != 0) {
|
||||
dgst_usage();
|
||||
goto end;
|
||||
}
|
||||
argc -= cfg.argsused;
|
||||
argv += cfg.argsused;
|
||||
|
||||
if (cfg.do_verify && !cfg.sigfile) {
|
||||
BIO_printf(bio_err,
|
||||
"No signature to verify: use the -signature option\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
bmd = BIO_new(BIO_f_md());
|
||||
if (in == NULL || bmd == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.debug) {
|
||||
BIO_set_callback(in, BIO_debug_callback);
|
||||
/* needed for windows 3.1 */
|
||||
BIO_set_callback_arg(in, (char *) bio_err);
|
||||
}
|
||||
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.out_bin == -1) {
|
||||
if (cfg.keyfile)
|
||||
cfg.out_bin = 1;
|
||||
else
|
||||
cfg.out_bin = 0;
|
||||
}
|
||||
|
||||
if (cfg.outfile) {
|
||||
if (cfg.out_bin)
|
||||
out = BIO_new_file(cfg.outfile, "wb");
|
||||
else
|
||||
out = BIO_new_file(cfg.outfile, "w");
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
BIO_printf(bio_err, "Error opening output file %s\n",
|
||||
cfg.outfile ? cfg.outfile : "(stdout)");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if ((!!cfg.mac_name + !!cfg.keyfile +
|
||||
!!cfg.hmac_key) > 1) {
|
||||
BIO_printf(bio_err,
|
||||
"MAC and Signing key cannot both be specified\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.keyfile) {
|
||||
if (cfg.want_pub)
|
||||
sigkey = load_pubkey(bio_err, cfg.keyfile,
|
||||
cfg.keyform, 0, NULL, "key file");
|
||||
else
|
||||
sigkey = load_key(bio_err, cfg.keyfile,
|
||||
cfg.keyform, 0, passin, "key file");
|
||||
if (!sigkey) {
|
||||
/*
|
||||
* load_[pub]key() has already printed an appropriate
|
||||
* message
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.mac_name) {
|
||||
EVP_PKEY_CTX *mac_ctx = NULL;
|
||||
int r = 0;
|
||||
if (!init_gen_str(bio_err, &mac_ctx, cfg.mac_name, 0))
|
||||
goto mac_end;
|
||||
if (cfg.macopts) {
|
||||
char *macopt;
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(
|
||||
cfg.macopts); i++) {
|
||||
macopt = sk_OPENSSL_STRING_value(
|
||||
cfg.macopts, i);
|
||||
if (pkey_ctrl_string(mac_ctx, macopt) <= 0) {
|
||||
BIO_printf(bio_err,
|
||||
"MAC parameter error \"%s\"\n",
|
||||
macopt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto mac_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (EVP_PKEY_keygen(mac_ctx, &sigkey) <= 0) {
|
||||
BIO_puts(bio_err, "Error generating key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto mac_end;
|
||||
}
|
||||
r = 1;
|
||||
mac_end:
|
||||
EVP_PKEY_CTX_free(mac_ctx);
|
||||
if (r == 0)
|
||||
goto end;
|
||||
}
|
||||
if (cfg.hmac_key) {
|
||||
sigkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
|
||||
(unsigned char *) cfg.hmac_key, -1);
|
||||
if (!sigkey)
|
||||
goto end;
|
||||
}
|
||||
if (sigkey) {
|
||||
EVP_MD_CTX *mctx = NULL;
|
||||
EVP_PKEY_CTX *pctx = NULL;
|
||||
int r;
|
||||
if (!BIO_get_md_ctx(bmd, &mctx)) {
|
||||
BIO_printf(bio_err, "Error getting context\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.do_verify)
|
||||
r = EVP_DigestVerifyInit(mctx, &pctx, cfg.md,
|
||||
NULL, sigkey);
|
||||
else
|
||||
r = EVP_DigestSignInit(mctx, &pctx, cfg.md,
|
||||
NULL, sigkey);
|
||||
if (!r) {
|
||||
BIO_printf(bio_err, "Error setting context\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.sigopts) {
|
||||
char *sigopt;
|
||||
for (i = 0; i < sk_OPENSSL_STRING_num(
|
||||
cfg.sigopts); i++) {
|
||||
sigopt = sk_OPENSSL_STRING_value(
|
||||
cfg.sigopts, i);
|
||||
if (pkey_ctrl_string(pctx, sigopt) <= 0) {
|
||||
BIO_printf(bio_err,
|
||||
"parameter error \"%s\"\n",
|
||||
sigopt);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* we use md as a filter, reading from 'in' */
|
||||
else {
|
||||
if (cfg.md == NULL)
|
||||
cfg.md = EVP_sha256();
|
||||
if (!BIO_set_md(bmd, cfg.md)) {
|
||||
BIO_printf(bio_err, "Error setting digest %s\n", pname);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.sigfile && sigkey) {
|
||||
BIO *sigbio;
|
||||
siglen = EVP_PKEY_size(sigkey);
|
||||
sigbuf = malloc(siglen);
|
||||
if (sigbuf == NULL) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
sigbio = BIO_new_file(cfg.sigfile, "rb");
|
||||
if (!sigbio) {
|
||||
BIO_printf(bio_err, "Error opening signature file %s\n",
|
||||
cfg.sigfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
siglen = BIO_read(sigbio, sigbuf, siglen);
|
||||
BIO_free(sigbio);
|
||||
if (siglen <= 0) {
|
||||
BIO_printf(bio_err, "Error reading signature file %s\n",
|
||||
cfg.sigfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
inp = BIO_push(bmd, in);
|
||||
|
||||
if (cfg.md == NULL) {
|
||||
EVP_MD_CTX *tctx;
|
||||
BIO_get_md_ctx(bmd, &tctx);
|
||||
cfg.md = EVP_MD_CTX_md(tctx);
|
||||
}
|
||||
if (argc == 0) {
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
err = do_fp(out, buf, inp, cfg.separator,
|
||||
cfg.out_bin, sigkey, sigbuf, siglen, NULL, NULL,
|
||||
"stdin", bmd);
|
||||
} else {
|
||||
const char *md_name = NULL, *sig_name = NULL;
|
||||
if (!cfg.out_bin) {
|
||||
if (sigkey) {
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = EVP_PKEY_get0_asn1(sigkey);
|
||||
if (ameth)
|
||||
EVP_PKEY_asn1_get0_info(NULL, NULL,
|
||||
NULL, NULL, &sig_name, ameth);
|
||||
}
|
||||
md_name = EVP_MD_name(cfg.md);
|
||||
}
|
||||
err = 0;
|
||||
for (i = 0; i < argc; i++) {
|
||||
int r;
|
||||
if (BIO_read_filename(in, argv[i]) <= 0) {
|
||||
perror(argv[i]);
|
||||
err++;
|
||||
continue;
|
||||
} else {
|
||||
r = do_fp(out, buf, inp, cfg.separator,
|
||||
cfg.out_bin, sigkey, sigbuf, siglen,
|
||||
sig_name, md_name, argv[i], bmd);
|
||||
}
|
||||
if (r)
|
||||
err = r;
|
||||
(void) BIO_reset(bmd);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
freezero(buf, BUFSIZE);
|
||||
BIO_free(in);
|
||||
free(passin);
|
||||
BIO_free_all(out);
|
||||
EVP_PKEY_free(sigkey);
|
||||
sk_OPENSSL_STRING_free(cfg.sigopts);
|
||||
sk_OPENSSL_STRING_free(cfg.macopts);
|
||||
free(sigbuf);
|
||||
BIO_free(bmd);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
int
|
||||
do_fp(BIO * out, unsigned char *buf, BIO * bp, int sep, int binout,
|
||||
EVP_PKEY * key, unsigned char *sigin, int siglen,
|
||||
const char *sig_name, const char *md_name,
|
||||
const char *file, BIO * bmd)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
for (;;) {
|
||||
i = BIO_read(bp, (char *) buf, BUFSIZE);
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "Read Error in %s\n", file);
|
||||
ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
if (sigin) {
|
||||
EVP_MD_CTX *ctx;
|
||||
BIO_get_md_ctx(bp, &ctx);
|
||||
i = EVP_DigestVerifyFinal(ctx, sigin, (unsigned int) siglen);
|
||||
if (i > 0)
|
||||
BIO_printf(out, "Verified OK\n");
|
||||
else if (i == 0) {
|
||||
BIO_printf(out, "Verification Failure\n");
|
||||
return 1;
|
||||
} else {
|
||||
BIO_printf(bio_err, "Error Verifying Data\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (key) {
|
||||
EVP_MD_CTX *ctx;
|
||||
BIO_get_md_ctx(bp, &ctx);
|
||||
len = BUFSIZE;
|
||||
if (!EVP_DigestSignFinal(ctx, buf, &len)) {
|
||||
BIO_printf(bio_err, "Error Signing Data\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
len = BIO_gets(bp, (char *) buf, BUFSIZE);
|
||||
if ((int) len < 0) {
|
||||
ERR_print_errors(bio_err);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (binout)
|
||||
BIO_write(out, buf, len);
|
||||
else if (sep == 2) {
|
||||
for (i = 0; i < (int) len; i++)
|
||||
BIO_printf(out, "%02x", buf[i]);
|
||||
BIO_printf(out, " *%s\n", file);
|
||||
} else {
|
||||
if (sig_name)
|
||||
BIO_printf(out, "%s-%s(%s)= ", sig_name, md_name, file);
|
||||
else if (md_name)
|
||||
BIO_printf(out, "%s(%s)= ", md_name, file);
|
||||
else
|
||||
BIO_printf(out, "(%s)= ", file);
|
||||
for (i = 0; i < (int) len; i++) {
|
||||
if (sep && (i != 0))
|
||||
BIO_printf(out, ":");
|
||||
BIO_printf(out, "%02x", buf[i]);
|
||||
}
|
||||
BIO_printf(out, "\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,298 +0,0 @@
|
||||
/* $OpenBSD: dh.c,v 1.15 2023/03/06 14:32:05 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
int C;
|
||||
int check;
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option dh_options[] = {
|
||||
{
|
||||
.name = "C",
|
||||
.desc = "Convert DH parameters into C code",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.C,
|
||||
},
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Check the DH parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "No output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print a text form of the DH parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
dh_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: dh [-C] [-check] [-in file] [-inform format]\n"
|
||||
" [-noout] [-out file] [-outform format] [-text]\n\n");
|
||||
options_usage(dh_options);
|
||||
}
|
||||
|
||||
int
|
||||
dh_main(int argc, char **argv)
|
||||
{
|
||||
DH *dh = NULL;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, dh_options, NULL, NULL) != 0) {
|
||||
dh_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.informat == FORMAT_ASN1)
|
||||
dh = d2i_DHparams_bio(in, NULL);
|
||||
else if (cfg.informat == FORMAT_PEM)
|
||||
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad input format specified\n");
|
||||
goto end;
|
||||
}
|
||||
if (dh == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.text) {
|
||||
DHparams_print(out, dh);
|
||||
}
|
||||
if (cfg.check) {
|
||||
if (!DH_check(dh, &i)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (i & DH_CHECK_P_NOT_PRIME)
|
||||
printf("p value is not prime\n");
|
||||
if (i & DH_CHECK_P_NOT_SAFE_PRIME)
|
||||
printf("p value is not a safe prime\n");
|
||||
if (i & DH_UNABLE_TO_CHECK_GENERATOR)
|
||||
printf("unable to check the generator value\n");
|
||||
if (i & DH_NOT_SUITABLE_GENERATOR)
|
||||
printf("the g value is not a generator\n");
|
||||
if (i == 0)
|
||||
printf("DH parameters appear to be ok.\n");
|
||||
}
|
||||
if (cfg.C) {
|
||||
unsigned char *data;
|
||||
int len, l, bits;
|
||||
|
||||
len = BN_num_bytes(DH_get0_p(dh));
|
||||
bits = BN_num_bits(DH_get0_p(dh));
|
||||
data = malloc(len);
|
||||
if (data == NULL) {
|
||||
perror("malloc");
|
||||
goto end;
|
||||
}
|
||||
l = BN_bn2bin(DH_get0_p(dh), data);
|
||||
printf("static unsigned char dh%d_p[] = {", bits);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t};\n");
|
||||
|
||||
l = BN_bn2bin(DH_get0_g(dh), data);
|
||||
printf("static unsigned char dh%d_g[] = {", bits);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t};\n\n");
|
||||
|
||||
printf("DH *get_dh%d()\n\t{\n", bits);
|
||||
printf("\tDH *dh;\n");
|
||||
printf("\tBIGNUM *p = NULL, *g = NULL;\n\n");
|
||||
printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
|
||||
printf("\tp = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
|
||||
bits, bits);
|
||||
printf("\tg = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
|
||||
bits, bits);
|
||||
printf("\tif (p == NULL || g == NULL)\n");
|
||||
printf("\t\t{ BN_free(p); BN_free(q); DH_free(dh); return(NULL); }\n");
|
||||
printf("\tDH_set0_pqg(dh, p, NULL, g);\n");
|
||||
printf("\treturn(dh);\n\t}\n");
|
||||
free(data);
|
||||
}
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_DHparams_bio(out, dh);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_DHparams(out, dh);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
DH_free(dh);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
@@ -1,502 +0,0 @@
|
||||
/* $OpenBSD: dhparam.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DH */
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <openssl/dsa.h>
|
||||
|
||||
#define DEFBITS 2048
|
||||
|
||||
static struct {
|
||||
int C;
|
||||
int check;
|
||||
int dsaparam;
|
||||
int g;
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option dhparam_options[] = {
|
||||
{
|
||||
.name = "2",
|
||||
.desc = "Generate DH parameters with a generator value of 2 "
|
||||
"(default)",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.g,
|
||||
.value = 2,
|
||||
},
|
||||
{
|
||||
.name = "5",
|
||||
.desc = "Generate DH parameters with a generator value of 5",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.g,
|
||||
.value = 5,
|
||||
},
|
||||
{
|
||||
.name = "C",
|
||||
.desc = "Convert DH parameters into C code",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.C,
|
||||
},
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Check the DH parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "dsaparam",
|
||||
.desc = "Read or generate DSA parameters and convert to DH",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.dsaparam,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not output encoded version of DH parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print DH parameters in plain text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
dhparam_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: dhparam [-2 | -5] [-C] [-check] [-dsaparam]\n"
|
||||
" [-in file] [-inform DER | PEM] [-noout] [-out file]\n"
|
||||
" [-outform DER | PEM] [-text] [numbits]\n\n");
|
||||
options_usage(dhparam_options);
|
||||
}
|
||||
|
||||
static int dh_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
int
|
||||
dhparam_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
BN_GENCB *cb = NULL;
|
||||
char *num_bits = NULL;
|
||||
DH *dh = NULL;
|
||||
int num = 0;
|
||||
int ret = 1;
|
||||
int i;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) {
|
||||
dhparam_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (num_bits != NULL) {
|
||||
if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) {
|
||||
BIO_printf(bio_err, "invalid number of bits: %s\n",
|
||||
num_bits);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.g && !num)
|
||||
num = DEFBITS;
|
||||
|
||||
if (cfg.dsaparam) {
|
||||
if (cfg.g) {
|
||||
BIO_printf(bio_err, "generator may not be chosen for DSA parameters\n");
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
/* DH parameters */
|
||||
if (num && !cfg.g)
|
||||
cfg.g = 2;
|
||||
}
|
||||
|
||||
if (num) {
|
||||
if ((cb = BN_GENCB_new()) == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Error allocating BN_GENCB object\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
BN_GENCB_set(cb, dh_cb, bio_err);
|
||||
if (cfg.dsaparam) {
|
||||
DSA *dsa = DSA_new();
|
||||
|
||||
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
|
||||
if (!dsa || !DSA_generate_parameters_ex(dsa, num,
|
||||
NULL, 0, NULL, NULL, cb)) {
|
||||
DSA_free(dsa);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
dh = DSA_dup_DH(dsa);
|
||||
DSA_free(dsa);
|
||||
if (dh == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
dh = DH_new();
|
||||
BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, cfg.g);
|
||||
BIO_printf(bio_err, "This is going to take a long time\n");
|
||||
if (!dh || !DH_generate_parameters_ex(dh, num, cfg.g, cb)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.informat != FORMAT_ASN1 &&
|
||||
cfg.informat != FORMAT_PEM) {
|
||||
BIO_printf(bio_err, "bad input format specified\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.dsaparam) {
|
||||
DSA *dsa;
|
||||
|
||||
if (cfg.informat == FORMAT_ASN1)
|
||||
dsa = d2i_DSAparams_bio(in, NULL);
|
||||
else /* informat == FORMAT_PEM */
|
||||
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
|
||||
|
||||
if (dsa == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
dh = DSA_dup_DH(dsa);
|
||||
DSA_free(dsa);
|
||||
if (dh == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
{
|
||||
if (cfg.informat == FORMAT_ASN1)
|
||||
dh = d2i_DHparams_bio(in, NULL);
|
||||
else /* informat == FORMAT_PEM */
|
||||
dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);
|
||||
|
||||
if (dh == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* dh != NULL */
|
||||
}
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cfg.text) {
|
||||
DHparams_print(out, dh);
|
||||
}
|
||||
if (cfg.check) {
|
||||
if (!DH_check(dh, &i)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (i & DH_CHECK_P_NOT_PRIME)
|
||||
printf("p value is not prime\n");
|
||||
if (i & DH_CHECK_P_NOT_SAFE_PRIME)
|
||||
printf("p value is not a safe prime\n");
|
||||
if (i & DH_UNABLE_TO_CHECK_GENERATOR)
|
||||
printf("unable to check the generator value\n");
|
||||
if (i & DH_NOT_SUITABLE_GENERATOR)
|
||||
printf("the g value is not a generator\n");
|
||||
if (i == 0)
|
||||
printf("DH parameters appear to be ok.\n");
|
||||
}
|
||||
if (cfg.C) {
|
||||
unsigned char *data;
|
||||
int len, l, bits;
|
||||
|
||||
len = BN_num_bytes(DH_get0_p(dh));
|
||||
bits = BN_num_bits(DH_get0_p(dh));
|
||||
data = malloc(len);
|
||||
if (data == NULL) {
|
||||
perror("malloc");
|
||||
goto end;
|
||||
}
|
||||
printf("#ifndef HEADER_DH_H\n"
|
||||
"#include <openssl/dh.h>\n"
|
||||
"#endif\n");
|
||||
printf("DH *get_dh%d()\n\t{\n", bits);
|
||||
|
||||
l = BN_bn2bin(DH_get0_p(dh), data);
|
||||
printf("\tstatic unsigned char dh%d_p[] = {", bits);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t\t};\n");
|
||||
|
||||
l = BN_bn2bin(DH_get0_g(dh), data);
|
||||
printf("\tstatic unsigned char dh%d_g[] = {", bits);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t\t};\n");
|
||||
|
||||
printf("\tDH *dh;\n");
|
||||
printf("\tBIGNUM *p = NULL, *g = NULL;\n\n");
|
||||
printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
|
||||
printf("\tp = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
|
||||
bits, bits);
|
||||
printf("\tg = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
|
||||
bits, bits);
|
||||
printf("\tif (p == NULL || g == NULL)\n");
|
||||
printf("\t\t{ BN_free(p); BN_free(g); DH_free(dh); return(NULL); }\n");
|
||||
printf("\tDH_set0_pqg(dh, p, NULL, g);\n");
|
||||
if (DH_get_length(dh) > 0)
|
||||
printf("\tDH_set_length(dh, %ld);\n", DH_get_length(dh));
|
||||
printf("\treturn(dh);\n\t}\n");
|
||||
free(data);
|
||||
}
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_DHparams_bio(out, dh);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_DHparams(out, dh);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write DH parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
BN_GENCB_free(cb);
|
||||
DH_free(dh);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* dh_cb is identical to dsa_cb in apps/dsaparam.c */
|
||||
static int
|
||||
dh_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void) BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,365 +0,0 @@
|
||||
/* $OpenBSD: dsa.c,v 1.18 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
const EVP_CIPHER *enc;
|
||||
char *infile;
|
||||
int informat;
|
||||
int modulus;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
char *passargin;
|
||||
char *passargout;
|
||||
int pubin;
|
||||
int pubout;
|
||||
int pvk_encr;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
dsa_opt_enc(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static const struct option dsa_options[] = {
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (PEM (default) or any other supported"
|
||||
" format)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "modulus",
|
||||
.desc = "Print the DSA public value",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.modulus,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "No output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER, MSBLOB, PEM (default) or PVK)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "source",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "source",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Read a public key from the input file instead of"
|
||||
" private key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubin,
|
||||
},
|
||||
{
|
||||
.name = "pubout",
|
||||
.desc = "Output a public key instead of private key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubout,
|
||||
},
|
||||
{
|
||||
.name = "pvk-none",
|
||||
.desc = "PVK encryption level",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 0,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "pvk-strong",
|
||||
.desc = "PVK encryption level (default)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 2,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "pvk-weak",
|
||||
.desc = "PVK encryption level",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print the key in text form",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = dsa_opt_enc,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
dsa_usage(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: dsa [-in file] [-inform format] [-modulus] [-noout]\n"
|
||||
" [-out file] [-outform format] [-passin src] [-passout src]\n"
|
||||
" [-pubin] [-pubout] [-pvk-none | -pvk-strong | -pvk-weak]\n"
|
||||
" [-text] [-ciphername]\n\n");
|
||||
options_usage(dsa_options);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Valid ciphername values:\n\n");
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
dsa_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
DSA *dsa = NULL;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.pvk_encr = 2;
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, dsa_options, NULL, NULL) != 0) {
|
||||
dsa_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
|
||||
&passin, &passout)) {
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "read DSA key\n");
|
||||
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (cfg.pubin)
|
||||
pkey = load_pubkey(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "Public Key");
|
||||
else
|
||||
pkey = load_key(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "Private Key");
|
||||
|
||||
if (pkey) {
|
||||
dsa = EVP_PKEY_get1_DSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
}
|
||||
if (dsa == NULL) {
|
||||
BIO_printf(bio_err, "unable to load Key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.text) {
|
||||
if (!DSA_print(out, dsa, 0)) {
|
||||
perror(cfg.outfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.modulus) {
|
||||
fprintf(stdout, "Public Key=");
|
||||
BN_print(out, DSA_get0_pub_key(dsa));
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
if (cfg.noout)
|
||||
goto end;
|
||||
BIO_printf(bio_err, "writing DSA key\n");
|
||||
if (cfg.outformat == FORMAT_ASN1) {
|
||||
if (cfg.pubin || cfg.pubout)
|
||||
i = i2d_DSA_PUBKEY_bio(out, dsa);
|
||||
else
|
||||
i = i2d_DSAPrivateKey_bio(out, dsa);
|
||||
} else if (cfg.outformat == FORMAT_PEM) {
|
||||
if (cfg.pubin || cfg.pubout)
|
||||
i = PEM_write_bio_DSA_PUBKEY(out, dsa);
|
||||
else
|
||||
i = PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc,
|
||||
NULL, 0, NULL, passout);
|
||||
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_RC4)
|
||||
} else if (cfg.outformat == FORMAT_MSBLOB ||
|
||||
cfg.outformat == FORMAT_PVK) {
|
||||
EVP_PKEY *pk;
|
||||
pk = EVP_PKEY_new();
|
||||
EVP_PKEY_set1_DSA(pk, dsa);
|
||||
if (cfg.outformat == FORMAT_PVK)
|
||||
i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
|
||||
passout);
|
||||
else if (cfg.pubin || cfg.pubout)
|
||||
i = i2b_PublicKey_bio(out, pk);
|
||||
else
|
||||
i = i2b_PrivateKey_bio(out, pk);
|
||||
EVP_PKEY_free(pk);
|
||||
#endif
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (i <= 0) {
|
||||
BIO_printf(bio_err, "unable to write private key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
} else
|
||||
ret = 0;
|
||||
end:
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
DSA_free(dsa);
|
||||
free(passin);
|
||||
free(passout);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
/* $OpenBSD: dsaparam.c,v 1.15 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
|
||||
|
||||
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
|
||||
* deprecated functions for openssl-internal code */
|
||||
#ifdef OPENSSL_NO_DEPRECATED
|
||||
#undef OPENSSL_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
int C;
|
||||
int genkey;
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option dsaparam_options[] = {
|
||||
{
|
||||
.name = "C",
|
||||
.desc = "Convert DSA parameters into C code",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.C,
|
||||
},
|
||||
{
|
||||
.name = "genkey",
|
||||
.desc = "Generate a DSA key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.genkey,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "No output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print as text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
dsaparam_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: dsaparam [-C] [-genkey] [-in file]\n"
|
||||
" [-inform format] [-noout] [-out file] [-outform format]\n"
|
||||
" [-text] [numbits]\n\n");
|
||||
options_usage(dsaparam_options);
|
||||
}
|
||||
|
||||
static int dsa_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
int
|
||||
dsaparam_main(int argc, char **argv)
|
||||
{
|
||||
DSA *dsa = NULL;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
BN_GENCB *cb = NULL;
|
||||
int ret = 1;
|
||||
int numbits = -1;
|
||||
char *strbits = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, dsaparam_options, &strbits, NULL) != 0) {
|
||||
dsaparam_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strbits != NULL) {
|
||||
const char *errstr;
|
||||
numbits = strtonum(strbits, 0, INT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
fprintf(stderr, "Invalid number of bits: %s", errstr);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (numbits > 0) {
|
||||
if ((cb = BN_GENCB_new()) == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"Error allocating BN_GENCB object\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
BN_GENCB_set(cb, dsa_cb, bio_err);
|
||||
|
||||
dsa = DSA_new();
|
||||
if (!dsa) {
|
||||
BIO_printf(bio_err, "Error allocating DSA object\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", numbits);
|
||||
BIO_printf(bio_err, "This could take some time\n");
|
||||
if (!DSA_generate_parameters_ex(dsa, numbits, NULL, 0, NULL, NULL, cb)) {
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_printf(bio_err, "Error, DSA key generation failed\n");
|
||||
goto end;
|
||||
}
|
||||
} else if (cfg.informat == FORMAT_ASN1)
|
||||
dsa = d2i_DSAparams_bio(in, NULL);
|
||||
else if (cfg.informat == FORMAT_PEM)
|
||||
dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad input format specified\n");
|
||||
goto end;
|
||||
}
|
||||
if (dsa == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.text) {
|
||||
DSAparams_print(out, dsa);
|
||||
}
|
||||
if (cfg.C) {
|
||||
unsigned char *data;
|
||||
int l, len, bits_p;
|
||||
|
||||
len = BN_num_bytes(DSA_get0_p(dsa));
|
||||
bits_p = BN_num_bits(DSA_get0_p(dsa));
|
||||
data = malloc(len + 20);
|
||||
if (data == NULL) {
|
||||
perror("malloc");
|
||||
goto end;
|
||||
}
|
||||
l = BN_bn2bin(DSA_get0_p(dsa), data);
|
||||
printf("static unsigned char dsa%d_p[] = {", bits_p);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t};\n");
|
||||
|
||||
l = BN_bn2bin(DSA_get0_q(dsa), data);
|
||||
printf("static unsigned char dsa%d_q[] = {", bits_p);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
printf("\n\t};\n");
|
||||
|
||||
l = BN_bn2bin(DSA_get0_g(dsa), data);
|
||||
printf("static unsigned char dsa%d_g[] = {", bits_p);
|
||||
for (i = 0; i < l; i++) {
|
||||
if ((i % 12) == 0)
|
||||
printf("\n\t");
|
||||
printf("0x%02X, ", data[i]);
|
||||
}
|
||||
free(data);
|
||||
printf("\n\t};\n\n");
|
||||
|
||||
printf("DSA *get_dsa%d()\n\t{\n", bits_p);
|
||||
printf("\tBIGNUM *p = NULL, *q = NULL, *g = NULL;\n");
|
||||
printf("\tDSA *dsa;\n\n");
|
||||
printf("\tif ((dsa = DSA_new()) == NULL) return(NULL);\n");
|
||||
printf("\tp = BN_bin2bn(dsa%d_p, sizeof(dsa%d_p), NULL);\n",
|
||||
bits_p, bits_p);
|
||||
printf("\tq = BN_bin2bn(dsa%d_q, sizeof(dsa%d_q), NULL);\n",
|
||||
bits_p, bits_p);
|
||||
printf("\tg = BN_bin2bn(dsa%d_g, sizeof(dsa%d_g), NULL);\n",
|
||||
bits_p, bits_p);
|
||||
printf("\tif (p == NULL || q == NULL || g == NULL)\n");
|
||||
printf("\t\t{ BN_free(p); BN_free(q); BN_free(g); DSA_free(dsa); return(NULL); }\n");
|
||||
printf("\tDSA_set0_pqg(dsa, p, q, g);\n");
|
||||
printf("\treturn(dsa);\n\t}\n");
|
||||
}
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_DSAparams_bio(out, dsa);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_DSAparams(out, dsa);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write DSA parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.genkey) {
|
||||
DSA *dsakey;
|
||||
|
||||
if ((dsakey = DSAparams_dup(dsa)) == NULL)
|
||||
goto end;
|
||||
if (!DSA_generate_key(dsakey)) {
|
||||
ERR_print_errors(bio_err);
|
||||
DSA_free(dsakey);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_DSAPrivateKey_bio(out, dsakey);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_DSAPrivateKey(out, dsakey, NULL, NULL, 0, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
DSA_free(dsakey);
|
||||
goto end;
|
||||
}
|
||||
DSA_free(dsakey);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
BN_GENCB_free(cb);
|
||||
DSA_free(dsa);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
dsa_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void) BIO_flush(BN_GENCB_get_arg(cb));
|
||||
#ifdef GENCB_TEST
|
||||
if (stop_keygen_flag)
|
||||
return 0;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -1,392 +0,0 @@
|
||||
/* $OpenBSD: ec.c,v 1.16 2023/03/06 14:32:06 tb Exp $ */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static struct {
|
||||
int asn1_flag;
|
||||
const EVP_CIPHER *enc;
|
||||
point_conversion_form_t form;
|
||||
char *infile;
|
||||
int informat;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int new_asn1_flag;
|
||||
int new_form;
|
||||
int noout;
|
||||
int param_out;
|
||||
char *passargin;
|
||||
char *passargout;
|
||||
int pubin;
|
||||
int pubout;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
ec_opt_enc(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.enc = EVP_get_cipherbyname(name)) != NULL) {
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ec_opt_form(char *arg)
|
||||
{
|
||||
if (strcmp(arg, "compressed") == 0)
|
||||
cfg.form = POINT_CONVERSION_COMPRESSED;
|
||||
else if (strcmp(arg, "uncompressed") == 0)
|
||||
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
else if (strcmp(arg, "hybrid") == 0)
|
||||
cfg.form = POINT_CONVERSION_HYBRID;
|
||||
else {
|
||||
fprintf(stderr, "Invalid point conversion: %s\n", arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
cfg.new_form = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ec_opt_named(char *arg)
|
||||
{
|
||||
if (strcmp(arg, "named_curve") == 0)
|
||||
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
|
||||
else if (strcmp(arg, "explicit") == 0)
|
||||
cfg.asn1_flag = 0;
|
||||
else {
|
||||
fprintf(stderr, "Invalid curve type: %s\n", arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
cfg.new_asn1_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option ec_options[] = {
|
||||
{
|
||||
.name = "conv_form",
|
||||
.argname = "form",
|
||||
.desc = "Specify the point conversion form (default"
|
||||
" \"named_curve\")",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = ec_opt_form,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "No output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "param_enc",
|
||||
.argname = "type",
|
||||
.desc = "Specify the way the ec parameters are encoded"
|
||||
" (default \"uncompressed\")",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = ec_opt_named,
|
||||
},
|
||||
{
|
||||
.name = "param_out",
|
||||
.desc = "Print the elliptic curve parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.param_out,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "source",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "source",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Read public key instead of private key from input",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubin,
|
||||
},
|
||||
{
|
||||
.name = "pubout",
|
||||
.desc = "Output public key instead of private key in output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubout,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print the public/private key components and parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.desc = "Cipher to encrypt the output if using PEM format",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = ec_opt_enc,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
ec_usage(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: ec [-conv_form form] [-in file]\n"
|
||||
" [-inform format] [-noout] [-out file] [-outform format]\n"
|
||||
" [-param_enc type] [-param_out] [-passin file]\n"
|
||||
" [-passout file] [-pubin] [-pubout] [-text] [-ciphername]\n\n");
|
||||
options_usage(ec_options);
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Valid ciphername values:\n\n");
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
ec_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
EC_KEY *eckey = NULL;
|
||||
const EC_GROUP *group;
|
||||
int i;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
|
||||
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, ec_options, NULL, NULL) != 0) {
|
||||
ec_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
|
||||
&passin, &passout)) {
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "read EC key\n");
|
||||
if (cfg.informat == FORMAT_ASN1) {
|
||||
if (cfg.pubin)
|
||||
eckey = d2i_EC_PUBKEY_bio(in, NULL);
|
||||
else
|
||||
eckey = d2i_ECPrivateKey_bio(in, NULL);
|
||||
} else if (cfg.informat == FORMAT_PEM) {
|
||||
if (cfg.pubin)
|
||||
eckey = PEM_read_bio_EC_PUBKEY(in, NULL, NULL,
|
||||
NULL);
|
||||
else
|
||||
eckey = PEM_read_bio_ECPrivateKey(in, NULL, NULL,
|
||||
passin);
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad input format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
if (eckey == NULL) {
|
||||
BIO_printf(bio_err, "unable to load Key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
group = EC_KEY_get0_group(eckey);
|
||||
|
||||
if (cfg.new_form)
|
||||
EC_KEY_set_conv_form(eckey, cfg.form);
|
||||
|
||||
if (cfg.new_asn1_flag)
|
||||
EC_KEY_set_asn1_flag(eckey, cfg.asn1_flag);
|
||||
|
||||
if (cfg.text)
|
||||
if (!EC_KEY_print(out, eckey, 0)) {
|
||||
perror(cfg.outfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.noout) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_err, "writing EC key\n");
|
||||
if (cfg.outformat == FORMAT_ASN1) {
|
||||
if (cfg.param_out)
|
||||
i = i2d_ECPKParameters_bio(out, group);
|
||||
else if (cfg.pubin || cfg.pubout)
|
||||
i = i2d_EC_PUBKEY_bio(out, eckey);
|
||||
else
|
||||
i = i2d_ECPrivateKey_bio(out, eckey);
|
||||
} else if (cfg.outformat == FORMAT_PEM) {
|
||||
if (cfg.param_out)
|
||||
i = PEM_write_bio_ECPKParameters(out, group);
|
||||
else if (cfg.pubin || cfg.pubout)
|
||||
i = PEM_write_bio_EC_PUBKEY(out, eckey);
|
||||
else
|
||||
i = PEM_write_bio_ECPrivateKey(out, eckey,
|
||||
cfg.enc, NULL, 0, NULL, passout);
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad output format specified for "
|
||||
"outfile\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write private key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
} else
|
||||
ret = 0;
|
||||
end:
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
EC_KEY_free(eckey);
|
||||
free(passin);
|
||||
free(passout);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
@@ -1,606 +0,0 @@
|
||||
/* $OpenBSD: ecparam.c,v 1.23 2023/03/06 14:32:06 tb Exp $ */
|
||||
/*
|
||||
* Written by Nils Larsch for the OpenSSL project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
|
||||
*
|
||||
* Portions of the attached software ("Contribution") are developed by
|
||||
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
|
||||
*
|
||||
* The Contribution is licensed pursuant to the OpenSSL open source
|
||||
* license provided above.
|
||||
*
|
||||
* The elliptic curve binary polynomial software is originally written by
|
||||
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static int ecparam_print_var(BIO *, BIGNUM *, const char *, int,
|
||||
unsigned char *);
|
||||
|
||||
static struct {
|
||||
int C;
|
||||
int asn1_flag;
|
||||
int check;
|
||||
char *curve_name;
|
||||
point_conversion_form_t form;
|
||||
int genkey;
|
||||
char *infile;
|
||||
int informat;
|
||||
int list_curves;
|
||||
int new_asn1_flag;
|
||||
int new_form;
|
||||
int no_seed;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
ecparam_opt_form(char *arg)
|
||||
{
|
||||
if (strcmp(arg, "compressed") == 0)
|
||||
cfg.form = POINT_CONVERSION_COMPRESSED;
|
||||
else if (strcmp(arg, "uncompressed") == 0)
|
||||
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
else if (strcmp(arg, "hybrid") == 0)
|
||||
cfg.form = POINT_CONVERSION_HYBRID;
|
||||
else
|
||||
return (1);
|
||||
|
||||
cfg.new_form = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
ecparam_opt_enctype(char *arg)
|
||||
{
|
||||
if (strcmp(arg, "explicit") == 0)
|
||||
cfg.asn1_flag = 0;
|
||||
else if (strcmp(arg, "named_curve") == 0)
|
||||
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
|
||||
else
|
||||
return (1);
|
||||
|
||||
cfg.new_asn1_flag = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option ecparam_options[] = {
|
||||
{
|
||||
.name = "C",
|
||||
.desc = "Convert the EC parameters into C code",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.C,
|
||||
},
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Validate the elliptic curve parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "conv_form",
|
||||
.argname = "form",
|
||||
.desc = "Specify point conversion form:\n"
|
||||
" compressed, uncompressed (default), hybrid",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = ecparam_opt_form,
|
||||
},
|
||||
{
|
||||
.name = "genkey",
|
||||
.desc = "Generate an EC private key using the specified "
|
||||
"parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.genkey,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file to read parameters from (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "list_curves",
|
||||
.desc = "Print list of all currently implemented EC "
|
||||
"parameter names",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.list_curves,
|
||||
},
|
||||
{
|
||||
.name = "name",
|
||||
.argname = "curve",
|
||||
.desc = "Use the EC parameters with the specified name",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.curve_name,
|
||||
},
|
||||
{
|
||||
.name = "no_seed",
|
||||
.desc = "Do not output seed with explicit parameter encoding",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.no_seed,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not output encoded version of EC parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file to write parameters to (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "param_enc",
|
||||
.argname = "type",
|
||||
.desc = "Specify EC parameter ASN.1 encoding type:\n"
|
||||
" explicit, named_curve (default)",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = ecparam_opt_enctype,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print out the EC parameters in human readable form",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
ecparam_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: ecparam [-C] [-check] [-conv_form arg] "
|
||||
" [-genkey]\n"
|
||||
" [-in file] [-inform DER | PEM] [-list_curves] [-name arg]\n"
|
||||
" [-no_seed] [-noout] [-out file] [-outform DER | PEM]\n"
|
||||
" [-param_enc arg] [-text]\n\n");
|
||||
options_usage(ecparam_options);
|
||||
}
|
||||
|
||||
int
|
||||
ecparam_main(int argc, char **argv)
|
||||
{
|
||||
BIGNUM *ec_p = NULL, *ec_a = NULL, *ec_b = NULL, *ec_gen = NULL;
|
||||
BIGNUM *ec_order = NULL, *ec_cofactor = NULL;
|
||||
EC_GROUP *group = NULL;
|
||||
unsigned char *buffer = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
int i, ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.asn1_flag = OPENSSL_EC_NAMED_CURVE;
|
||||
cfg.form = POINT_CONVERSION_UNCOMPRESSED;
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, ecparam_options, NULL, NULL) != 0) {
|
||||
ecparam_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if ((in == NULL) || (out == NULL)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.list_curves) {
|
||||
EC_builtin_curve *curves = NULL;
|
||||
size_t crv_len = 0;
|
||||
size_t n = 0;
|
||||
|
||||
crv_len = EC_get_builtin_curves(NULL, 0);
|
||||
|
||||
curves = reallocarray(NULL, crv_len, sizeof(EC_builtin_curve));
|
||||
if (curves == NULL)
|
||||
goto end;
|
||||
|
||||
if (!EC_get_builtin_curves(curves, crv_len)) {
|
||||
free(curves);
|
||||
goto end;
|
||||
}
|
||||
for (n = 0; n < crv_len; n++) {
|
||||
const char *comment;
|
||||
const char *sname;
|
||||
comment = curves[n].comment;
|
||||
sname = OBJ_nid2sn(curves[n].nid);
|
||||
if (comment == NULL)
|
||||
comment = "CURVE DESCRIPTION NOT AVAILABLE";
|
||||
if (sname == NULL)
|
||||
sname = "";
|
||||
|
||||
BIO_printf(out, " %-10s: ", sname);
|
||||
BIO_printf(out, "%s\n", comment);
|
||||
}
|
||||
|
||||
free(curves);
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (cfg.curve_name != NULL) {
|
||||
int nid;
|
||||
|
||||
/*
|
||||
* workaround for the SECG curve names secp192r1 and
|
||||
* secp256r1 (which are the same as the curves prime192v1 and
|
||||
* prime256v1 defined in X9.62)
|
||||
*/
|
||||
if (!strcmp(cfg.curve_name, "secp192r1")) {
|
||||
BIO_printf(bio_err, "using curve name prime192v1 "
|
||||
"instead of secp192r1\n");
|
||||
nid = NID_X9_62_prime192v1;
|
||||
} else if (!strcmp(cfg.curve_name, "secp256r1")) {
|
||||
BIO_printf(bio_err, "using curve name prime256v1 "
|
||||
"instead of secp256r1\n");
|
||||
nid = NID_X9_62_prime256v1;
|
||||
} else
|
||||
nid = OBJ_sn2nid(cfg.curve_name);
|
||||
|
||||
if (nid == 0)
|
||||
nid = EC_curve_nist2nid(cfg.curve_name);
|
||||
|
||||
if (nid == 0) {
|
||||
BIO_printf(bio_err, "unknown curve name (%s)\n",
|
||||
cfg.curve_name);
|
||||
goto end;
|
||||
}
|
||||
group = EC_GROUP_new_by_curve_name(nid);
|
||||
if (group == NULL) {
|
||||
BIO_printf(bio_err, "unable to create curve (%s)\n",
|
||||
cfg.curve_name);
|
||||
goto end;
|
||||
}
|
||||
EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
|
||||
EC_GROUP_set_point_conversion_form(group, cfg.form);
|
||||
} else if (cfg.informat == FORMAT_ASN1) {
|
||||
group = d2i_ECPKParameters_bio(in, NULL);
|
||||
} else if (cfg.informat == FORMAT_PEM) {
|
||||
group = PEM_read_bio_ECPKParameters(in, NULL, NULL, NULL);
|
||||
} else {
|
||||
BIO_printf(bio_err, "bad input format specified\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (group == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"unable to load elliptic curve parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.new_form)
|
||||
EC_GROUP_set_point_conversion_form(group, cfg.form);
|
||||
|
||||
if (cfg.new_asn1_flag)
|
||||
EC_GROUP_set_asn1_flag(group, cfg.asn1_flag);
|
||||
|
||||
if (cfg.no_seed)
|
||||
EC_GROUP_set_seed(group, NULL, 0);
|
||||
|
||||
if (cfg.text) {
|
||||
if (!ECPKParameters_print(out, group, 0))
|
||||
goto end;
|
||||
}
|
||||
if (cfg.check) {
|
||||
BIO_printf(bio_err, "checking elliptic curve parameters: ");
|
||||
if (!EC_GROUP_check(group, NULL)) {
|
||||
BIO_printf(bio_err, "failed\n");
|
||||
ERR_print_errors(bio_err);
|
||||
} else
|
||||
BIO_printf(bio_err, "ok\n");
|
||||
|
||||
}
|
||||
if (cfg.C) {
|
||||
size_t buf_len = 0, tmp_len = 0;
|
||||
const EC_POINT *point;
|
||||
int is_prime, len = 0;
|
||||
const EC_METHOD *meth = EC_GROUP_method_of(group);
|
||||
|
||||
if ((ec_p = BN_new()) == NULL || (ec_a = BN_new()) == NULL ||
|
||||
(ec_b = BN_new()) == NULL || (ec_gen = BN_new()) == NULL ||
|
||||
(ec_order = BN_new()) == NULL ||
|
||||
(ec_cofactor = BN_new()) == NULL) {
|
||||
perror("malloc");
|
||||
goto end;
|
||||
}
|
||||
is_prime = (EC_METHOD_get_field_type(meth) ==
|
||||
NID_X9_62_prime_field);
|
||||
|
||||
if (!EC_GROUP_get_curve(group, ec_p, ec_a, ec_b, NULL))
|
||||
goto end;
|
||||
|
||||
if ((point = EC_GROUP_get0_generator(group)) == NULL)
|
||||
goto end;
|
||||
if (!EC_POINT_point2bn(group, point,
|
||||
EC_GROUP_get_point_conversion_form(group), ec_gen,
|
||||
NULL))
|
||||
goto end;
|
||||
if (!EC_GROUP_get_order(group, ec_order, NULL))
|
||||
goto end;
|
||||
if (!EC_GROUP_get_cofactor(group, ec_cofactor, NULL))
|
||||
goto end;
|
||||
|
||||
len = BN_num_bits(ec_order);
|
||||
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_p)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_a)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_b)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_gen)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_order)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
if ((tmp_len = (size_t) BN_num_bytes(ec_cofactor)) > buf_len)
|
||||
buf_len = tmp_len;
|
||||
|
||||
buffer = malloc(buf_len);
|
||||
|
||||
if (buffer == NULL) {
|
||||
perror("malloc");
|
||||
goto end;
|
||||
}
|
||||
ecparam_print_var(out, ec_p, "ec_p", len, buffer);
|
||||
ecparam_print_var(out, ec_a, "ec_a", len, buffer);
|
||||
ecparam_print_var(out, ec_b, "ec_b", len, buffer);
|
||||
ecparam_print_var(out, ec_gen, "ec_gen", len, buffer);
|
||||
ecparam_print_var(out, ec_order, "ec_order", len, buffer);
|
||||
ecparam_print_var(out, ec_cofactor, "ec_cofactor", len,
|
||||
buffer);
|
||||
|
||||
BIO_printf(out, "\n\n");
|
||||
|
||||
BIO_printf(out, "EC_GROUP *get_ec_group_%d(void)\n\t{\n", len);
|
||||
BIO_printf(out, "\tint ok=0;\n");
|
||||
BIO_printf(out, "\tEC_GROUP *group = NULL;\n");
|
||||
BIO_printf(out, "\tEC_POINT *point = NULL;\n");
|
||||
BIO_printf(out, "\tBIGNUM *tmp_1 = NULL, *tmp_2 = NULL, "
|
||||
"*tmp_3 = NULL;\n\n");
|
||||
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_p_%d, "
|
||||
"sizeof(ec_p_%d), NULL)) == NULL)\n\t\t"
|
||||
"goto err;\n", len, len);
|
||||
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_a_%d, "
|
||||
"sizeof(ec_a_%d), NULL)) == NULL)\n\t\t"
|
||||
"goto err;\n", len, len);
|
||||
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_b_%d, "
|
||||
"sizeof(ec_b_%d), NULL)) == NULL)\n\t\t"
|
||||
"goto err;\n", len, len);
|
||||
if (is_prime) {
|
||||
BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
|
||||
"GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
|
||||
"\n\t\tgoto err;\n\n");
|
||||
} else {
|
||||
BIO_printf(out, "\tif ((group = EC_GROUP_new_curve_"
|
||||
"GF2m(tmp_1, tmp_2, tmp_3, NULL)) == NULL)"
|
||||
"\n\t\tgoto err;\n\n");
|
||||
}
|
||||
BIO_printf(out, "\t/* build generator */\n");
|
||||
BIO_printf(out, "\tif ((tmp_1 = BN_bin2bn(ec_gen_%d, "
|
||||
"sizeof(ec_gen_%d), tmp_1)) == NULL)"
|
||||
"\n\t\tgoto err;\n", len, len);
|
||||
BIO_printf(out, "\tpoint = EC_POINT_bn2point(group, tmp_1, "
|
||||
"NULL, NULL);\n");
|
||||
BIO_printf(out, "\tif (point == NULL)\n\t\tgoto err;\n");
|
||||
BIO_printf(out, "\tif ((tmp_2 = BN_bin2bn(ec_order_%d, "
|
||||
"sizeof(ec_order_%d), tmp_2)) == NULL)"
|
||||
"\n\t\tgoto err;\n", len, len);
|
||||
BIO_printf(out, "\tif ((tmp_3 = BN_bin2bn(ec_cofactor_%d, "
|
||||
"sizeof(ec_cofactor_%d), tmp_3)) == NULL)"
|
||||
"\n\t\tgoto err;\n", len, len);
|
||||
BIO_printf(out, "\tif (!EC_GROUP_set_generator(group, point,"
|
||||
" tmp_2, tmp_3))\n\t\tgoto err;\n");
|
||||
BIO_printf(out, "\n\tok=1;\n");
|
||||
BIO_printf(out, "err:\n");
|
||||
BIO_printf(out, "\tif (tmp_1)\n\t\tBN_free(tmp_1);\n");
|
||||
BIO_printf(out, "\tif (tmp_2)\n\t\tBN_free(tmp_2);\n");
|
||||
BIO_printf(out, "\tif (tmp_3)\n\t\tBN_free(tmp_3);\n");
|
||||
BIO_printf(out, "\tif (point)\n\t\tEC_POINT_free(point);\n");
|
||||
BIO_printf(out, "\tif (!ok)\n");
|
||||
BIO_printf(out, "\t\t{\n");
|
||||
BIO_printf(out, "\t\tEC_GROUP_free(group);\n");
|
||||
BIO_printf(out, "\t\tgroup = NULL;\n");
|
||||
BIO_printf(out, "\t\t}\n");
|
||||
BIO_printf(out, "\treturn(group);\n\t}\n");
|
||||
}
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_ECPKParameters_bio(out, group);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_ECPKParameters(out, group);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for"
|
||||
" outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write elliptic "
|
||||
"curve parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.genkey) {
|
||||
EC_KEY *eckey = EC_KEY_new();
|
||||
|
||||
if (eckey == NULL)
|
||||
goto end;
|
||||
|
||||
if (EC_KEY_set_group(eckey, group) == 0) {
|
||||
EC_KEY_free(eckey);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!EC_KEY_generate_key(eckey)) {
|
||||
EC_KEY_free(eckey);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_ECPrivateKey_bio(out, eckey);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_ECPrivateKey(out, eckey, NULL,
|
||||
NULL, 0, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified "
|
||||
"for outfile\n");
|
||||
EC_KEY_free(eckey);
|
||||
goto end;
|
||||
}
|
||||
EC_KEY_free(eckey);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BN_free(ec_p);
|
||||
BN_free(ec_a);
|
||||
BN_free(ec_b);
|
||||
BN_free(ec_gen);
|
||||
BN_free(ec_order);
|
||||
BN_free(ec_cofactor);
|
||||
|
||||
free(buffer);
|
||||
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
EC_GROUP_free(group);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
ecparam_print_var(BIO * out, BIGNUM * in, const char *var,
|
||||
int len, unsigned char *buffer)
|
||||
{
|
||||
BIO_printf(out, "static unsigned char %s_%d[] = {", var, len);
|
||||
if (BN_is_zero(in))
|
||||
BIO_printf(out, "\n\t0x00");
|
||||
else {
|
||||
int i, l;
|
||||
|
||||
l = BN_bn2bin(in, buffer);
|
||||
for (i = 0; i < l - 1; i++) {
|
||||
if ((i % 12) == 0)
|
||||
BIO_printf(out, "\n\t");
|
||||
BIO_printf(out, "0x%02X,", buffer[i]);
|
||||
}
|
||||
if ((i % 12) == 0)
|
||||
BIO_printf(out, "\n\t");
|
||||
BIO_printf(out, "0x%02X", buffer[i]);
|
||||
}
|
||||
BIO_printf(out, "\n\t};\n\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -1,783 +0,0 @@
|
||||
/* $OpenBSD: enc.c,v 1.31 2023/07/29 17:15:45 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
int set_hex(char *in, unsigned char *out, int size);
|
||||
|
||||
#define SIZE (512)
|
||||
#define BSIZE (8*1024)
|
||||
|
||||
static struct {
|
||||
int base64;
|
||||
char *bufsize;
|
||||
const EVP_CIPHER *cipher;
|
||||
int debug;
|
||||
int enc;
|
||||
char *hiv;
|
||||
char *hkey;
|
||||
char *hsalt;
|
||||
char *inf;
|
||||
int iter;
|
||||
char *keyfile;
|
||||
char *keystr;
|
||||
char *md;
|
||||
int nopad;
|
||||
int nosalt;
|
||||
int olb64;
|
||||
char *outf;
|
||||
char *passarg;
|
||||
int pbkdf2;
|
||||
int printkey;
|
||||
int verbose;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
enc_opt_cipher(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if (strcmp(name, "none") == 0) {
|
||||
cfg.cipher = NULL;
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static const struct option enc_options[] = {
|
||||
{
|
||||
.name = "A",
|
||||
.desc = "Process base64 data on one line (requires -a)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.olb64,
|
||||
},
|
||||
{
|
||||
.name = "a",
|
||||
.desc = "Perform base64 encoding/decoding (alias -base64)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.base64,
|
||||
},
|
||||
{
|
||||
.name = "base64",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.base64,
|
||||
},
|
||||
{
|
||||
.name = "bufsize",
|
||||
.argname = "size",
|
||||
.desc = "Specify the buffer size to use for I/O",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.bufsize,
|
||||
},
|
||||
{
|
||||
.name = "d",
|
||||
.desc = "Decrypt the input data",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.enc,
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.name = "debug",
|
||||
.desc = "Print debugging information",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.debug,
|
||||
},
|
||||
{
|
||||
.name = "e",
|
||||
.desc = "Encrypt the input data (default)",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.enc,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file to read from (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.inf,
|
||||
},
|
||||
{
|
||||
.name = "iter",
|
||||
.argname = "iterations",
|
||||
.desc = "Specify iteration count and force use of PBKDF2",
|
||||
.type = OPTION_ARG_INT,
|
||||
.opt.value = &cfg.iter,
|
||||
},
|
||||
{
|
||||
.name = "iv",
|
||||
.argname = "IV",
|
||||
.desc = "IV to use, specified as a hexadecimal string",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.hiv,
|
||||
},
|
||||
{
|
||||
.name = "K",
|
||||
.argname = "key",
|
||||
.desc = "Key to use, specified as a hexadecimal string",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.hkey,
|
||||
},
|
||||
{
|
||||
.name = "k", /* Superseded by -pass. */
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keystr,
|
||||
},
|
||||
{
|
||||
.name = "kfile", /* Superseded by -pass. */
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keyfile,
|
||||
},
|
||||
{
|
||||
.name = "md",
|
||||
.argname = "digest",
|
||||
.desc = "Digest to use to create a key from the passphrase",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.md,
|
||||
},
|
||||
{
|
||||
.name = "none",
|
||||
.desc = "Use NULL cipher (no encryption or decryption)",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = enc_opt_cipher,
|
||||
},
|
||||
{
|
||||
.name = "nopad",
|
||||
.desc = "Disable standard block padding",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.nopad,
|
||||
},
|
||||
{
|
||||
.name = "nosalt",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.nosalt,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file to write to (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outf,
|
||||
},
|
||||
{
|
||||
.name = "P",
|
||||
.desc = "Print out the salt, key and IV used, then exit\n"
|
||||
" (no encryption or decryption is performed)",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.printkey,
|
||||
.value = 2,
|
||||
},
|
||||
{
|
||||
.name = "p",
|
||||
.desc = "Print out the salt, key and IV used",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.printkey,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "pass",
|
||||
.argname = "source",
|
||||
.desc = "Password source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passarg,
|
||||
},
|
||||
{
|
||||
.name = "pbkdf2",
|
||||
.desc = "Use the pbkdf2 key derivation function",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pbkdf2,
|
||||
},
|
||||
{
|
||||
.name = "S",
|
||||
.argname = "salt",
|
||||
.desc = "Salt to use, specified as a hexadecimal string",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.hsalt,
|
||||
},
|
||||
{
|
||||
.name = "salt",
|
||||
.desc = "Use a salt in the key derivation routines (default)",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.nosalt,
|
||||
.value = 0,
|
||||
},
|
||||
{
|
||||
.name = "v",
|
||||
.desc = "Verbose",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.verbose,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = enc_opt_cipher,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
skip_aead_and_xts(const OBJ_NAME *name, void *arg)
|
||||
{
|
||||
const EVP_CIPHER *cipher;
|
||||
|
||||
if ((cipher = EVP_get_cipherbyname(name->name)) == NULL)
|
||||
return;
|
||||
|
||||
if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0)
|
||||
return;
|
||||
if (EVP_CIPHER_mode(cipher) == EVP_CIPH_XTS_MODE)
|
||||
return;
|
||||
|
||||
show_cipher(name, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
enc_usage(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
fprintf(stderr, "usage: enc -ciphername [-AadePp] [-base64] "
|
||||
"[-bufsize number] [-debug]\n"
|
||||
" [-in file] [-iter iterations] [-iv IV] [-K key] "
|
||||
"[-k password]\n"
|
||||
" [-kfile file] [-md digest] [-none] [-nopad] [-nosalt]\n"
|
||||
" [-out file] [-pass source] [-pbkdf2] [-S salt] [-salt]\n\n");
|
||||
options_usage(enc_options);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Valid ciphername values:\n\n");
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, skip_aead_and_xts, &n);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
enc_main(int argc, char **argv)
|
||||
{
|
||||
static const char magic[] = "Salted__";
|
||||
char mbuf[sizeof magic - 1];
|
||||
char *strbuf = NULL, *pass = NULL;
|
||||
unsigned char *buff = NULL;
|
||||
int bsize = BSIZE;
|
||||
int ret = 1, inl;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char salt[PKCS5_SALT_LEN];
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
const EVP_MD *dgst = NULL;
|
||||
BIO *in = NULL, *out = NULL, *b64 = NULL, *benc = NULL;
|
||||
BIO *rbio = NULL, *wbio = NULL;
|
||||
#define PROG_NAME_SIZE 39
|
||||
char pname[PROG_NAME_SIZE + 1];
|
||||
int i;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.enc = 1;
|
||||
|
||||
/* first check the program name */
|
||||
program_name(argv[0], pname, sizeof(pname));
|
||||
|
||||
if (strcmp(pname, "base64") == 0)
|
||||
cfg.base64 = 1;
|
||||
|
||||
cfg.cipher = EVP_get_cipherbyname(pname);
|
||||
|
||||
if (!cfg.base64 && cfg.cipher == NULL && strcmp(pname, "enc") != 0) {
|
||||
BIO_printf(bio_err, "%s is an unknown cipher\n", pname);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (options_parse(argc, argv, enc_options, NULL, NULL) != 0) {
|
||||
enc_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.keyfile != NULL) {
|
||||
static char buf[128];
|
||||
FILE *infile;
|
||||
|
||||
infile = fopen(cfg.keyfile, "r");
|
||||
if (infile == NULL) {
|
||||
BIO_printf(bio_err, "unable to read key from '%s'\n",
|
||||
cfg.keyfile);
|
||||
goto end;
|
||||
}
|
||||
buf[0] = '\0';
|
||||
if (!fgets(buf, sizeof buf, infile)) {
|
||||
BIO_printf(bio_err, "unable to read key from '%s'\n",
|
||||
cfg.keyfile);
|
||||
fclose(infile);
|
||||
goto end;
|
||||
}
|
||||
fclose(infile);
|
||||
i = strlen(buf);
|
||||
if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
|
||||
buf[--i] = '\0';
|
||||
if (i > 0 && (buf[i - 1] == '\n' || buf[i - 1] == '\r'))
|
||||
buf[--i] = '\0';
|
||||
if (i < 1) {
|
||||
BIO_printf(bio_err, "zero length password\n");
|
||||
goto end;
|
||||
}
|
||||
cfg.keystr = buf;
|
||||
}
|
||||
|
||||
if (cfg.cipher != NULL &&
|
||||
(EVP_CIPHER_flags(cfg.cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) {
|
||||
BIO_printf(bio_err, "enc does not support AEAD ciphers\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.cipher != NULL &&
|
||||
EVP_CIPHER_mode(cfg.cipher) == EVP_CIPH_XTS_MODE) {
|
||||
BIO_printf(bio_err, "enc does not support XTS mode\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.md != NULL &&
|
||||
(dgst = EVP_get_digestbyname(cfg.md)) == NULL) {
|
||||
BIO_printf(bio_err,
|
||||
"%s is an unsupported message digest type\n",
|
||||
cfg.md);
|
||||
goto end;
|
||||
}
|
||||
if (dgst == NULL)
|
||||
dgst = EVP_sha256();
|
||||
|
||||
if (cfg.bufsize != NULL) {
|
||||
char *p = cfg.bufsize;
|
||||
unsigned long n;
|
||||
|
||||
/* XXX - provide an OPTION_ARG_DISKUNIT. */
|
||||
for (n = 0; *p != '\0'; p++) {
|
||||
i = *p;
|
||||
if ((i <= '9') && (i >= '0'))
|
||||
n = n * 10 + i - '0';
|
||||
else if (i == 'k') {
|
||||
n *= 1024;
|
||||
p++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*p != '\0') {
|
||||
BIO_printf(bio_err, "invalid 'bufsize' specified.\n");
|
||||
goto end;
|
||||
}
|
||||
/* It must be large enough for a base64 encoded line. */
|
||||
if (cfg.base64 && n < 80)
|
||||
n = 80;
|
||||
|
||||
bsize = (int)n;
|
||||
if (cfg.verbose)
|
||||
BIO_printf(bio_err, "bufsize=%d\n", bsize);
|
||||
}
|
||||
strbuf = malloc(SIZE);
|
||||
buff = malloc(EVP_ENCODE_LENGTH(bsize));
|
||||
if (buff == NULL || strbuf == NULL) {
|
||||
BIO_printf(bio_err, "malloc failure %ld\n", (long) EVP_ENCODE_LENGTH(bsize));
|
||||
goto end;
|
||||
}
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (in == NULL || out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.debug) {
|
||||
BIO_set_callback(in, BIO_debug_callback);
|
||||
BIO_set_callback(out, BIO_debug_callback);
|
||||
BIO_set_callback_arg(in, (char *) bio_err);
|
||||
BIO_set_callback_arg(out, (char *) bio_err);
|
||||
}
|
||||
if (cfg.inf == NULL) {
|
||||
if (cfg.bufsize != NULL)
|
||||
setvbuf(stdin, (char *) NULL, _IONBF, 0);
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_read_filename(in, cfg.inf) <= 0) {
|
||||
perror(cfg.inf);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cfg.keystr && cfg.passarg) {
|
||||
if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
cfg.keystr = pass;
|
||||
}
|
||||
if (cfg.keystr == NULL && cfg.cipher != NULL && cfg.hkey == NULL) {
|
||||
for (;;) {
|
||||
char buf[200];
|
||||
int retval;
|
||||
|
||||
retval = snprintf(buf, sizeof buf,
|
||||
"enter %s %s password:",
|
||||
OBJ_nid2ln(EVP_CIPHER_nid(cfg.cipher)),
|
||||
cfg.enc ? "encryption" : "decryption");
|
||||
if ((size_t)retval >= sizeof buf) {
|
||||
BIO_printf(bio_err,
|
||||
"Password prompt too long\n");
|
||||
goto end;
|
||||
}
|
||||
strbuf[0] = '\0';
|
||||
i = EVP_read_pw_string((char *)strbuf, SIZE, buf,
|
||||
cfg.enc);
|
||||
if (i == 0) {
|
||||
if (strbuf[0] == '\0') {
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
cfg.keystr = strbuf;
|
||||
break;
|
||||
}
|
||||
if (i < 0) {
|
||||
BIO_printf(bio_err, "bad password read\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg.outf == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
if (cfg.bufsize != NULL)
|
||||
setvbuf(stdout, (char *)NULL, _IONBF, 0);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outf) <= 0) {
|
||||
perror(cfg.outf);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
rbio = in;
|
||||
wbio = out;
|
||||
|
||||
if (cfg.base64) {
|
||||
if ((b64 = BIO_new(BIO_f_base64())) == NULL)
|
||||
goto end;
|
||||
if (cfg.debug) {
|
||||
BIO_set_callback(b64, BIO_debug_callback);
|
||||
BIO_set_callback_arg(b64, (char *) bio_err);
|
||||
}
|
||||
if (cfg.olb64)
|
||||
BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
|
||||
if (cfg.enc)
|
||||
wbio = BIO_push(b64, wbio);
|
||||
else
|
||||
rbio = BIO_push(b64, rbio);
|
||||
}
|
||||
if (cfg.cipher != NULL) {
|
||||
/*
|
||||
* Note that keystr is NULL if a key was passed on the command
|
||||
* line, so we get no salt in that case. Is this a bug?
|
||||
*/
|
||||
if (cfg.keystr != NULL) {
|
||||
/*
|
||||
* Salt handling: if encrypting generate a salt and
|
||||
* write to output BIO. If decrypting read salt from
|
||||
* input BIO.
|
||||
*/
|
||||
unsigned char *sptr;
|
||||
if (cfg.nosalt)
|
||||
sptr = NULL;
|
||||
else {
|
||||
if (cfg.enc) {
|
||||
if (cfg.hsalt) {
|
||||
if (!set_hex(cfg.hsalt, salt, sizeof salt)) {
|
||||
BIO_printf(bio_err,
|
||||
"invalid hex salt value\n");
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
arc4random_buf(salt,
|
||||
sizeof(salt));
|
||||
/*
|
||||
* If -P option then don't bother
|
||||
* writing
|
||||
*/
|
||||
if ((cfg.printkey != 2)
|
||||
&& (BIO_write(wbio, magic,
|
||||
sizeof magic - 1) != sizeof magic - 1
|
||||
|| BIO_write(wbio,
|
||||
(char *) salt,
|
||||
sizeof salt) != sizeof salt)) {
|
||||
BIO_printf(bio_err, "error writing output file\n");
|
||||
goto end;
|
||||
}
|
||||
} else if (BIO_read(rbio, mbuf, sizeof mbuf) != sizeof mbuf
|
||||
|| BIO_read(rbio,
|
||||
(unsigned char *) salt,
|
||||
sizeof salt) != sizeof salt) {
|
||||
BIO_printf(bio_err, "error reading input file\n");
|
||||
goto end;
|
||||
} else if (memcmp(mbuf, magic, sizeof magic - 1)) {
|
||||
BIO_printf(bio_err, "bad magic number\n");
|
||||
goto end;
|
||||
}
|
||||
sptr = salt;
|
||||
}
|
||||
if (cfg.pbkdf2 == 1 || cfg.iter > 0) {
|
||||
/*
|
||||
* derive key and default iv
|
||||
* concatenated into a temporary buffer
|
||||
*/
|
||||
unsigned char tmpkeyiv[EVP_MAX_KEY_LENGTH + EVP_MAX_IV_LENGTH];
|
||||
int iklen = EVP_CIPHER_key_length(cfg.cipher);
|
||||
int ivlen = EVP_CIPHER_iv_length(cfg.cipher);
|
||||
/* not needed if HASH_UPDATE() is fixed : */
|
||||
int islen = (sptr != NULL ? sizeof(salt) : 0);
|
||||
|
||||
if (cfg.iter == 0)
|
||||
cfg.iter = 10000;
|
||||
|
||||
if (!PKCS5_PBKDF2_HMAC(cfg.keystr,
|
||||
strlen(cfg.keystr), sptr, islen,
|
||||
cfg.iter, dgst, iklen+ivlen, tmpkeyiv)) {
|
||||
BIO_printf(bio_err, "PKCS5_PBKDF2_HMAC failed\n");
|
||||
goto end;
|
||||
}
|
||||
/* split and move data back to global buffer */
|
||||
memcpy(key, tmpkeyiv, iklen);
|
||||
memcpy(iv, tmpkeyiv + iklen, ivlen);
|
||||
explicit_bzero(tmpkeyiv, sizeof tmpkeyiv);
|
||||
} else {
|
||||
EVP_BytesToKey(cfg.cipher, dgst, sptr,
|
||||
(unsigned char *)cfg.keystr,
|
||||
strlen(cfg.keystr), 1, key, iv);
|
||||
}
|
||||
|
||||
/*
|
||||
* zero the complete buffer or the string passed from
|
||||
* the command line bug picked up by Larry J. Hughes
|
||||
* Jr. <hughes@indiana.edu>
|
||||
*/
|
||||
if (cfg.keystr == strbuf)
|
||||
explicit_bzero(cfg.keystr, SIZE);
|
||||
else
|
||||
explicit_bzero(cfg.keystr,
|
||||
strlen(cfg.keystr));
|
||||
}
|
||||
if (cfg.hiv != NULL && !set_hex(cfg.hiv, iv, sizeof iv)) {
|
||||
BIO_printf(bio_err, "invalid hex iv value\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.hiv == NULL && cfg.keystr == NULL &&
|
||||
EVP_CIPHER_iv_length(cfg.cipher) != 0) {
|
||||
/*
|
||||
* No IV was explicitly set and no IV was generated
|
||||
* during EVP_BytesToKey. Hence the IV is undefined,
|
||||
* making correct decryption impossible.
|
||||
*/
|
||||
BIO_printf(bio_err, "iv undefined\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.hkey != NULL && !set_hex(cfg.hkey, key, sizeof key)) {
|
||||
BIO_printf(bio_err, "invalid hex key value\n");
|
||||
goto end;
|
||||
}
|
||||
if ((benc = BIO_new(BIO_f_cipher())) == NULL)
|
||||
goto end;
|
||||
|
||||
/*
|
||||
* Since we may be changing parameters work on the encryption
|
||||
* context rather than calling BIO_set_cipher().
|
||||
*/
|
||||
|
||||
BIO_get_cipher_ctx(benc, &ctx);
|
||||
|
||||
if (!EVP_CipherInit_ex(ctx, cfg.cipher, NULL, NULL,
|
||||
NULL, cfg.enc)) {
|
||||
BIO_printf(bio_err, "Error setting cipher %s\n",
|
||||
EVP_CIPHER_name(cfg.cipher));
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.nopad)
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
|
||||
if (!EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, cfg.enc)) {
|
||||
BIO_printf(bio_err, "Error setting cipher %s\n",
|
||||
EVP_CIPHER_name(cfg.cipher));
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.debug) {
|
||||
BIO_set_callback(benc, BIO_debug_callback);
|
||||
BIO_set_callback_arg(benc, (char *) bio_err);
|
||||
}
|
||||
if (cfg.printkey) {
|
||||
int key_len, iv_len;
|
||||
|
||||
if (!cfg.nosalt) {
|
||||
printf("salt=");
|
||||
for (i = 0; i < (int) sizeof(salt); i++)
|
||||
printf("%02X", salt[i]);
|
||||
printf("\n");
|
||||
}
|
||||
key_len = EVP_CIPHER_key_length(cfg.cipher);
|
||||
if (key_len > 0) {
|
||||
printf("key=");
|
||||
for (i = 0; i < key_len; i++)
|
||||
printf("%02X", key[i]);
|
||||
printf("\n");
|
||||
}
|
||||
iv_len = EVP_CIPHER_iv_length(cfg.cipher);
|
||||
if (iv_len > 0) {
|
||||
printf("iv =");
|
||||
for (i = 0; i < iv_len; i++)
|
||||
printf("%02X", iv[i]);
|
||||
printf("\n");
|
||||
}
|
||||
if (cfg.printkey == 2) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Only encrypt/decrypt as we write the file */
|
||||
if (benc != NULL)
|
||||
wbio = BIO_push(benc, wbio);
|
||||
|
||||
for (;;) {
|
||||
inl = BIO_read(rbio, (char *) buff, bsize);
|
||||
if (inl <= 0)
|
||||
break;
|
||||
if (BIO_write(wbio, (char *) buff, inl) != inl) {
|
||||
BIO_printf(bio_err, "error writing output file\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (!BIO_flush(wbio)) {
|
||||
BIO_printf(bio_err, "bad decrypt\n");
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
if (cfg.verbose) {
|
||||
BIO_printf(bio_err, "bytes read :%8ld\n", BIO_number_read(in));
|
||||
BIO_printf(bio_err, "bytes written:%8ld\n", BIO_number_written(out));
|
||||
}
|
||||
end:
|
||||
ERR_print_errors(bio_err);
|
||||
free(strbuf);
|
||||
free(buff);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
BIO_free(benc);
|
||||
BIO_free(b64);
|
||||
free(pass);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int
|
||||
set_hex(char *in, unsigned char *out, int size)
|
||||
{
|
||||
int i, n;
|
||||
unsigned char j;
|
||||
|
||||
n = strlen(in);
|
||||
if (n > (size * 2)) {
|
||||
BIO_printf(bio_err, "hex string is too long\n");
|
||||
return (0);
|
||||
}
|
||||
memset(out, 0, size);
|
||||
for (i = 0; i < n; i++) {
|
||||
j = (unsigned char) *in;
|
||||
*(in++) = '\0';
|
||||
if (j == 0)
|
||||
break;
|
||||
if (j >= '0' && j <= '9')
|
||||
j -= '0';
|
||||
else if (j >= 'A' && j <= 'F')
|
||||
j = j - 'A' + 10;
|
||||
else if (j >= 'a' && j <= 'f')
|
||||
j = j - 'a' + 10;
|
||||
else {
|
||||
BIO_printf(bio_err, "non-hex digit\n");
|
||||
return (0);
|
||||
}
|
||||
if (i & 1)
|
||||
out[i / 2] |= j;
|
||||
else
|
||||
out[i / 2] = (j << 4);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
/* $OpenBSD: errstr.c,v 1.11 2023/07/23 11:20:11 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
static const struct option errstr_options[] = {
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
errstr_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: errstr errno ...\n");
|
||||
}
|
||||
|
||||
int
|
||||
errstr_main(int argc, char **argv)
|
||||
{
|
||||
unsigned long ulval;
|
||||
char *ularg, *ep;
|
||||
int argsused, i;
|
||||
char buf[256];
|
||||
int ret = 0;
|
||||
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options_parse(argc, argv, errstr_options, NULL, &argsused) != 0) {
|
||||
errstr_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
for (i = argsused; i < argc; i++) {
|
||||
errno = 0;
|
||||
ularg = argv[i];
|
||||
ulval = strtoul(ularg, &ep, 16);
|
||||
if (strchr(ularg, '-') != NULL ||
|
||||
(ularg[0] == '\0' || *ep != '\0') ||
|
||||
(errno == ERANGE && ulval == ULONG_MAX)) {
|
||||
printf("%s: bad error code\n", ularg);
|
||||
ret++;
|
||||
continue;
|
||||
}
|
||||
|
||||
ERR_error_string_n(ulval, buf, sizeof(buf));
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/* $OpenBSD: gendh.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
|
||||
* deprecated functions for openssl-internal code */
|
||||
#ifdef OPENSSL_NO_DEPRECATED
|
||||
#undef OPENSSL_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#define DEFBITS 512
|
||||
|
||||
static int dh_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
static struct {
|
||||
int g;
|
||||
char *outfile;
|
||||
} cfg;
|
||||
|
||||
static const struct option gendh_options[] = {
|
||||
{
|
||||
.name = "2",
|
||||
.desc = "Generate DH parameters with a generator value of 2 "
|
||||
"(default)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 2,
|
||||
.opt.value = &cfg.g,
|
||||
},
|
||||
{
|
||||
.name = "5",
|
||||
.desc = "Generate DH parameters with a generator value of 5",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 5,
|
||||
.opt.value = &cfg.g,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
gendh_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: gendh [-2 | -5] [-out file] [numbits]\n\n");
|
||||
options_usage(gendh_options);
|
||||
}
|
||||
|
||||
int
|
||||
gendh_main(int argc, char **argv)
|
||||
{
|
||||
BN_GENCB *cb = NULL;
|
||||
DH *dh = NULL;
|
||||
int ret = 1, numbits = DEFBITS;
|
||||
BIO *out = NULL;
|
||||
char *strbits = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((cb = BN_GENCB_new()) == NULL) {
|
||||
BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
BN_GENCB_set(cb, dh_cb, bio_err);
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.g = 2;
|
||||
|
||||
if (options_parse(argc, argv, gendh_options, &strbits, NULL) != 0) {
|
||||
gendh_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (strbits != NULL) {
|
||||
const char *errstr;
|
||||
numbits = strtonum(strbits, 0, INT_MAX, &errstr);
|
||||
if (errstr) {
|
||||
fprintf(stderr, "Invalid number of bits: %s\n", errstr);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime,"
|
||||
" generator %d\n", numbits, cfg.g);
|
||||
BIO_printf(bio_err, "This is going to take a long time\n");
|
||||
|
||||
if (((dh = DH_new()) == NULL) ||
|
||||
!DH_generate_parameters_ex(dh, numbits, cfg.g, cb))
|
||||
goto end;
|
||||
|
||||
if (!PEM_write_bio_DHparams(out, dh))
|
||||
goto end;
|
||||
ret = 0;
|
||||
end:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_free_all(out);
|
||||
BN_GENCB_free(cb);
|
||||
DH_free(dh);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
dh_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void) BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
@@ -1,296 +0,0 @@
|
||||
/* $OpenBSD: gendsa.c,v 1.17 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h> /* for OPENSSL_NO_DSA */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/dsa.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
const EVP_CIPHER *enc;
|
||||
char *outfile;
|
||||
char *passargout;
|
||||
} cfg;
|
||||
|
||||
static const EVP_CIPHER *get_cipher_by_name(char *name)
|
||||
{
|
||||
if (name == NULL || strcmp(name, "") == 0)
|
||||
return (NULL);
|
||||
#ifndef OPENSSL_NO_AES
|
||||
else if (strcmp(name, "aes128") == 0)
|
||||
return EVP_aes_128_cbc();
|
||||
else if (strcmp(name, "aes192") == 0)
|
||||
return EVP_aes_192_cbc();
|
||||
else if (strcmp(name, "aes256") == 0)
|
||||
return EVP_aes_256_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
else if (strcmp(name, "camellia128") == 0)
|
||||
return EVP_camellia_128_cbc();
|
||||
else if (strcmp(name, "camellia192") == 0)
|
||||
return EVP_camellia_192_cbc();
|
||||
else if (strcmp(name, "camellia256") == 0)
|
||||
return EVP_camellia_256_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
else if (strcmp(name, "des") == 0)
|
||||
return EVP_des_cbc();
|
||||
else if (strcmp(name, "des3") == 0)
|
||||
return EVP_des_ede3_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
else if (strcmp(name, "idea") == 0)
|
||||
return EVP_idea_cbc();
|
||||
#endif
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
set_enc(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.enc = get_cipher_by_name(name)) == NULL)
|
||||
return (1);
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option gendsa_options[] = {
|
||||
#ifndef OPENSSL_NO_AES
|
||||
{
|
||||
.name = "aes128",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "aes192",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "aes256",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
{
|
||||
.name = "camellia128",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "camellia192",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "camellia256",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{
|
||||
.name = "des",
|
||||
.desc = "Encrypt the generated key with DES in CBC mode",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "des3",
|
||||
.desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
{
|
||||
.name = "idea",
|
||||
.desc = "Encrypt the generated key with IDEA in CBC mode",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output the key to 'file'",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "src",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
gendsa_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: gendsa [-aes128 | -aes192 | -aes256 |\n");
|
||||
fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |\n");
|
||||
fprintf(stderr, " -des | -des3 | -idea] [-out file] [-passout src]");
|
||||
fprintf(stderr, " paramfile\n\n");
|
||||
options_usage(gendsa_options);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
gendsa_main(int argc, char **argv)
|
||||
{
|
||||
DSA *dsa = NULL;
|
||||
int ret = 1;
|
||||
char *dsaparams = NULL;
|
||||
char *passout = NULL;
|
||||
BIO *out = NULL, *in = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, gendsa_options, &dsaparams, NULL) != 0) {
|
||||
gendsa_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (dsaparams == NULL) {
|
||||
gendsa_usage();
|
||||
goto end;
|
||||
}
|
||||
if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
|
||||
&passout)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (!(BIO_read_filename(in, dsaparams))) {
|
||||
perror(dsaparams);
|
||||
goto end;
|
||||
}
|
||||
if ((dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL)) == NULL) {
|
||||
BIO_printf(bio_err, "unable to load DSA parameter file\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_free(in);
|
||||
in = NULL;
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL)
|
||||
goto end;
|
||||
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "Generating DSA key, %d bits\n",
|
||||
BN_num_bits(DSA_get0_p(dsa)));
|
||||
if (!DSA_generate_key(dsa))
|
||||
goto end;
|
||||
|
||||
if (!PEM_write_bio_DSAPrivateKey(out, dsa, cfg.enc, NULL, 0,
|
||||
NULL, passout))
|
||||
goto end;
|
||||
ret = 0;
|
||||
end:
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
DSA_free(dsa);
|
||||
free(passout);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,418 +0,0 @@
|
||||
/* $OpenBSD: genpkey.c,v 1.17 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static int init_keygen_file(BIO * err, EVP_PKEY_CTX **pctx, const char *file);
|
||||
static int genpkey_cb(EVP_PKEY_CTX * ctx);
|
||||
|
||||
static struct {
|
||||
const EVP_CIPHER *cipher;
|
||||
EVP_PKEY_CTX **ctx;
|
||||
int do_param;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
char *passarg;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
genpkey_opt_algorithm(char *arg)
|
||||
{
|
||||
if (!init_gen_str(bio_err, cfg.ctx, arg,
|
||||
cfg.do_param))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
genpkey_opt_cipher(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if (cfg.do_param == 1)
|
||||
return (1);
|
||||
|
||||
if (strcmp(name, "none") == 0) {
|
||||
cfg.cipher = NULL;
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if ((cfg.cipher = EVP_get_cipherbyname(name)) != NULL) {
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
genpkey_opt_paramfile(char *arg)
|
||||
{
|
||||
if (cfg.do_param == 1)
|
||||
return (1);
|
||||
if (!init_keygen_file(bio_err, cfg.ctx, arg))
|
||||
return (1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
genpkey_opt_pkeyopt(char *arg)
|
||||
{
|
||||
if (*cfg.ctx == NULL) {
|
||||
BIO_puts(bio_err, "No keytype specified\n");
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (pkey_ctrl_string(*cfg.ctx, arg) <= 0) {
|
||||
BIO_puts(bio_err, "parameter setting error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option genpkey_options[] = {
|
||||
{
|
||||
.name = "algorithm",
|
||||
.argname = "name",
|
||||
.desc = "Public key algorithm to use (must precede -pkeyopt)",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = genpkey_opt_algorithm,
|
||||
},
|
||||
{
|
||||
.name = "genparam",
|
||||
.desc = "Generate a set of parameters instead of a private key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.do_param,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file to write to (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "paramfile",
|
||||
.argname = "file",
|
||||
.desc = "File to load public key algorithm parameters from\n"
|
||||
"(must precede -pkeyopt)",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = genpkey_opt_paramfile,
|
||||
},
|
||||
{
|
||||
.name = "pass",
|
||||
.argname = "arg",
|
||||
.desc = "Output file password source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passarg,
|
||||
},
|
||||
{
|
||||
.name = "pkeyopt",
|
||||
.argname = "opt:value",
|
||||
.desc = "Set public key algorithm option to the given value",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = genpkey_opt_pkeyopt,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print the private/public key in human readable form",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = genpkey_opt_cipher,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
genpkey_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: genpkey [-algorithm alg] [cipher] [-genparam] [-out file]\n"
|
||||
" [-outform der | pem] [-paramfile file] [-pass arg]\n"
|
||||
" [-pkeyopt opt:value] [-text]\n\n");
|
||||
options_usage(genpkey_options);
|
||||
}
|
||||
|
||||
int
|
||||
genpkey_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char *pass = NULL;
|
||||
int ret = 1, rv;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.ctx = &ctx;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, genpkey_options, NULL, NULL) != 0) {
|
||||
genpkey_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ctx == NULL) {
|
||||
genpkey_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passarg, NULL, &pass, NULL)) {
|
||||
BIO_puts(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile != NULL) {
|
||||
if ((out = BIO_new_file(cfg.outfile, "wb")) ==
|
||||
NULL) {
|
||||
BIO_printf(bio_err, "Can't open output file %s\n",
|
||||
cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_set_cb(ctx, genpkey_cb);
|
||||
EVP_PKEY_CTX_set_app_data(ctx, bio_err);
|
||||
|
||||
if (cfg.do_param) {
|
||||
if (EVP_PKEY_paramgen(ctx, &pkey) <= 0) {
|
||||
BIO_puts(bio_err, "Error generating parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (EVP_PKEY_keygen(ctx, &pkey) <= 0) {
|
||||
BIO_puts(bio_err, "Error generating key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.do_param)
|
||||
rv = PEM_write_bio_Parameters(out, pkey);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
rv = PEM_write_bio_PrivateKey(out, pkey, cfg.cipher,
|
||||
NULL, 0, NULL, pass);
|
||||
else if (cfg.outformat == FORMAT_ASN1)
|
||||
rv = i2d_PrivateKey_bio(out, pkey);
|
||||
else {
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (rv <= 0) {
|
||||
BIO_puts(bio_err, "Error writing key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
if (cfg.text) {
|
||||
if (cfg.do_param)
|
||||
rv = EVP_PKEY_print_params(out, pkey, 0, NULL);
|
||||
else
|
||||
rv = EVP_PKEY_print_private(out, pkey, 0, NULL);
|
||||
|
||||
if (rv <= 0) {
|
||||
BIO_puts(bio_err, "Error printing key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
free(pass);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
init_keygen_file(BIO * err, EVP_PKEY_CTX ** pctx, const char *file)
|
||||
{
|
||||
BIO *pbio;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
if (*pctx) {
|
||||
BIO_puts(err, "Parameters already set!\n");
|
||||
return 0;
|
||||
}
|
||||
pbio = BIO_new_file(file, "r");
|
||||
if (!pbio) {
|
||||
BIO_printf(err, "Can't open parameter file %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
pkey = PEM_read_bio_Parameters(pbio, NULL);
|
||||
BIO_free(pbio);
|
||||
|
||||
if (!pkey) {
|
||||
BIO_printf(bio_err, "Error reading parameter file %s\n", file);
|
||||
return 0;
|
||||
}
|
||||
ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
if (!ctx)
|
||||
goto err;
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0)
|
||||
goto err;
|
||||
EVP_PKEY_free(pkey);
|
||||
*pctx = ctx;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BIO_puts(err, "Error initializing context\n");
|
||||
ERR_print_errors(err);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
init_gen_str(BIO * err, EVP_PKEY_CTX ** pctx, const char *algname, int do_param)
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
int pkey_id;
|
||||
|
||||
if (*pctx) {
|
||||
BIO_puts(err, "Algorithm already set!\n");
|
||||
return 0;
|
||||
}
|
||||
ameth = EVP_PKEY_asn1_find_str(NULL, algname, -1);
|
||||
|
||||
if (!ameth) {
|
||||
BIO_printf(bio_err, "Algorithm %s not found\n", algname);
|
||||
return 0;
|
||||
}
|
||||
ERR_clear_error();
|
||||
|
||||
EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, ameth);
|
||||
ctx = EVP_PKEY_CTX_new_id(pkey_id, NULL);
|
||||
|
||||
if (!ctx)
|
||||
goto err;
|
||||
if (do_param) {
|
||||
if (EVP_PKEY_paramgen_init(ctx) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
if (EVP_PKEY_keygen_init(ctx) <= 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pctx = ctx;
|
||||
return 1;
|
||||
|
||||
err:
|
||||
BIO_printf(err, "Error initializing %s context\n", algname);
|
||||
ERR_print_errors(err);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
genpkey_cb(EVP_PKEY_CTX * ctx)
|
||||
{
|
||||
char c = '*';
|
||||
BIO *b = EVP_PKEY_CTX_get_app_data(ctx);
|
||||
int p;
|
||||
p = EVP_PKEY_CTX_get_keygen_info(ctx, 0);
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(b, &c, 1);
|
||||
(void) BIO_flush(b);
|
||||
return 1;
|
||||
}
|
||||
@@ -1,389 +0,0 @@
|
||||
/* $OpenBSD: genrsa.c,v 1.22 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
/* Until the key-gen callbacks are modified to use newer prototypes, we allow
|
||||
* deprecated functions for openssl-internal code */
|
||||
#ifdef OPENSSL_NO_DEPRECATED
|
||||
#undef OPENSSL_NO_DEPRECATED
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#define DEFBITS 2048
|
||||
|
||||
static int genrsa_cb(int p, int n, BN_GENCB *cb);
|
||||
|
||||
static struct {
|
||||
const EVP_CIPHER *enc;
|
||||
unsigned long f4;
|
||||
char *outfile;
|
||||
char *passargout;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
set_public_exponent(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *option = argv[0];
|
||||
|
||||
if (strcmp(option, "-3") == 0)
|
||||
cfg.f4 = 3;
|
||||
else if (strcmp(option, "-f4") == 0 || strcmp(option, "-F4") == 0)
|
||||
cfg.f4 = RSA_F4;
|
||||
else
|
||||
return (1);
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const EVP_CIPHER *get_cipher_by_name(char *name)
|
||||
{
|
||||
if (name == NULL || strcmp(name, "") == 0)
|
||||
return (NULL);
|
||||
#ifndef OPENSSL_NO_AES
|
||||
else if (strcmp(name, "aes128") == 0)
|
||||
return EVP_aes_128_cbc();
|
||||
else if (strcmp(name, "aes192") == 0)
|
||||
return EVP_aes_192_cbc();
|
||||
else if (strcmp(name, "aes256") == 0)
|
||||
return EVP_aes_256_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
else if (strcmp(name, "camellia128") == 0)
|
||||
return EVP_camellia_128_cbc();
|
||||
else if (strcmp(name, "camellia192") == 0)
|
||||
return EVP_camellia_192_cbc();
|
||||
else if (strcmp(name, "camellia256") == 0)
|
||||
return EVP_camellia_256_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
else if (strcmp(name, "des") == 0)
|
||||
return EVP_des_cbc();
|
||||
else if (strcmp(name, "des3") == 0)
|
||||
return EVP_des_ede3_cbc();
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
else if (strcmp(name, "idea") == 0)
|
||||
return EVP_idea_cbc();
|
||||
#endif
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
set_enc(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.enc = get_cipher_by_name(name)) == NULL)
|
||||
return (1);
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option genrsa_options[] = {
|
||||
{
|
||||
.name = "3",
|
||||
.desc = "Use 3 for the E value",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_public_exponent,
|
||||
},
|
||||
{
|
||||
.name = "f4",
|
||||
.desc = "Use F4 (0x10001) for the E value",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_public_exponent,
|
||||
},
|
||||
{
|
||||
.name = "F4",
|
||||
.desc = "Use F4 (0x10001) for the E value",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_public_exponent,
|
||||
},
|
||||
#ifndef OPENSSL_NO_AES
|
||||
{
|
||||
.name = "aes128",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "aes192",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "aes256",
|
||||
.desc = "Encrypt PEM output with CBC AES",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
{
|
||||
.name = "camellia128",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "camellia192",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "camellia256",
|
||||
.desc = "Encrypt PEM output with CBC Camellia",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{
|
||||
.name = "des",
|
||||
.desc = "Encrypt the generated key with DES in CBC mode",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
{
|
||||
.name = "des3",
|
||||
.desc = "Encrypt the generated key with DES in EDE CBC mode (168 bit key)",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
{
|
||||
.name = "idea",
|
||||
.desc = "Encrypt the generated key with IDEA in CBC mode",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = set_enc,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output the key to 'file'",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "arg",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
genrsa_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: genrsa [-3 | -f4] [-aes128 | -aes192 |");
|
||||
fprintf(stderr, " -aes256 |\n");
|
||||
fprintf(stderr, " -camellia128 | -camellia192 | -camellia256 |");
|
||||
fprintf(stderr, " -des | -des3 | -idea]\n");
|
||||
fprintf(stderr, " [-out file] [-passout arg] [numbits]\n\n");
|
||||
options_usage(genrsa_options);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
genrsa_main(int argc, char **argv)
|
||||
{
|
||||
BN_GENCB *cb = NULL;
|
||||
int ret = 1;
|
||||
int num = DEFBITS;
|
||||
char *numbits = NULL;
|
||||
char *passout = NULL;
|
||||
BIO *out = NULL;
|
||||
BIGNUM *bn = NULL;
|
||||
RSA *rsa = NULL;
|
||||
char *rsa_e_hex = NULL, *rsa_e_dec = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((bn = BN_new()) == NULL)
|
||||
goto err;
|
||||
|
||||
if ((cb = BN_GENCB_new()) == NULL) {
|
||||
BIO_printf(bio_err, "Error allocating BN_GENCB object\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
BN_GENCB_set(cb, genrsa_cb, bio_err);
|
||||
|
||||
if ((out = BIO_new(BIO_s_file())) == NULL) {
|
||||
BIO_printf(bio_err, "unable to create BIO for output\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.f4 = RSA_F4;
|
||||
|
||||
if (options_parse(argc, argv, genrsa_options, &numbits, NULL) != 0) {
|
||||
genrsa_usage();
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((numbits != NULL) &&
|
||||
((sscanf(numbits, "%d", &num) == 0) || (num < 0))) {
|
||||
genrsa_usage();
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, NULL, cfg.passargout, NULL,
|
||||
&passout)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "Generating RSA private key, %d bit long modulus\n",
|
||||
num);
|
||||
rsa = RSA_new();
|
||||
if (!rsa)
|
||||
goto err;
|
||||
|
||||
if (!BN_set_word(bn, cfg.f4) ||
|
||||
!RSA_generate_key_ex(rsa, num, bn, cb))
|
||||
goto err;
|
||||
|
||||
if ((rsa_e_hex = BN_bn2hex(RSA_get0_e(rsa))) == NULL)
|
||||
goto err;
|
||||
if ((rsa_e_dec = BN_bn2dec(RSA_get0_e(rsa))) == NULL)
|
||||
goto err;
|
||||
|
||||
BIO_printf(bio_err, "e is %s (0x%s)\n", rsa_e_dec, rsa_e_hex);
|
||||
{
|
||||
PW_CB_DATA cb_data;
|
||||
cb_data.password = passout;
|
||||
cb_data.prompt_info = cfg.outfile;
|
||||
if (!PEM_write_bio_RSAPrivateKey(out, rsa, cfg.enc,
|
||||
NULL, 0, password_callback, &cb_data))
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
err:
|
||||
BN_free(bn);
|
||||
BN_GENCB_free(cb);
|
||||
RSA_free(rsa);
|
||||
BIO_free_all(out);
|
||||
free(rsa_e_dec);
|
||||
free(rsa_e_hex);
|
||||
free(passout);
|
||||
|
||||
if (ret != 0)
|
||||
ERR_print_errors(bio_err);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
genrsa_cb(int p, int n, BN_GENCB *cb)
|
||||
{
|
||||
char c = '*';
|
||||
|
||||
if (p == 0)
|
||||
c = '.';
|
||||
if (p == 1)
|
||||
c = '+';
|
||||
if (p == 2)
|
||||
c = '*';
|
||||
if (p == 3)
|
||||
c = '\n';
|
||||
BIO_write(BN_GENCB_get_arg(cb), &c, 1);
|
||||
(void) BIO_flush(BN_GENCB_get_arg(cb));
|
||||
return 1;
|
||||
}
|
||||
1532
apps/openssl/ocsp.c
1532
apps/openssl/ocsp.c
File diff suppressed because it is too large
Load Diff
@@ -1,736 +0,0 @@
|
||||
/* $OpenBSD: openssl.c,v 1.35 2023/06/11 13:02:10 jsg Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "progs.h"
|
||||
#include "s_apps.h"
|
||||
|
||||
#define FUNC_TYPE_GENERAL 1
|
||||
#define FUNC_TYPE_MD 2
|
||||
#define FUNC_TYPE_CIPHER 3
|
||||
#define FUNC_TYPE_PKEY 4
|
||||
#define FUNC_TYPE_MD_ALG 5
|
||||
#define FUNC_TYPE_CIPHER_ALG 6
|
||||
|
||||
typedef struct {
|
||||
int type;
|
||||
const char *name;
|
||||
int (*func)(int argc, char **argv);
|
||||
} FUNCTION;
|
||||
|
||||
DECLARE_LHASH_OF(FUNCTION);
|
||||
|
||||
FUNCTION functions[] = {
|
||||
|
||||
/* General functions. */
|
||||
{ FUNC_TYPE_GENERAL, "asn1parse", asn1parse_main },
|
||||
{ FUNC_TYPE_GENERAL, "ca", ca_main },
|
||||
{ FUNC_TYPE_GENERAL, "certhash", certhash_main },
|
||||
{ FUNC_TYPE_GENERAL, "ciphers", ciphers_main },
|
||||
#ifndef OPENSSL_NO_CMS
|
||||
{ FUNC_TYPE_GENERAL, "cms", cms_main },
|
||||
#endif
|
||||
{ FUNC_TYPE_GENERAL, "crl2pkcs7", crl2pkcs7_main },
|
||||
{ FUNC_TYPE_GENERAL, "crl", crl_main },
|
||||
{ FUNC_TYPE_GENERAL, "dgst", dgst_main },
|
||||
{ FUNC_TYPE_GENERAL, "enc", enc_main },
|
||||
{ FUNC_TYPE_GENERAL, "errstr", errstr_main },
|
||||
{ FUNC_TYPE_GENERAL, "genpkey", genpkey_main },
|
||||
#ifndef OPENSSL_NO_OCSP
|
||||
{ FUNC_TYPE_GENERAL, "ocsp", ocsp_main },
|
||||
#endif
|
||||
{ FUNC_TYPE_GENERAL, "passwd", passwd_main },
|
||||
{ FUNC_TYPE_GENERAL, "pkcs7", pkcs7_main },
|
||||
{ FUNC_TYPE_GENERAL, "pkcs8", pkcs8_main },
|
||||
#if !defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_SHA1)
|
||||
{ FUNC_TYPE_GENERAL, "pkcs12", pkcs12_main },
|
||||
#endif
|
||||
{ FUNC_TYPE_GENERAL, "pkey", pkey_main },
|
||||
{ FUNC_TYPE_GENERAL, "pkeyparam", pkeyparam_main },
|
||||
{ FUNC_TYPE_GENERAL, "pkeyutl", pkeyutl_main },
|
||||
{ FUNC_TYPE_GENERAL, "prime", prime_main },
|
||||
{ FUNC_TYPE_GENERAL, "rand", rand_main },
|
||||
{ FUNC_TYPE_GENERAL, "req", req_main },
|
||||
{ FUNC_TYPE_GENERAL, "s_client", s_client_main },
|
||||
{ FUNC_TYPE_GENERAL, "s_server", s_server_main },
|
||||
{ FUNC_TYPE_GENERAL, "s_time", s_time_main },
|
||||
{ FUNC_TYPE_GENERAL, "sess_id", sess_id_main },
|
||||
{ FUNC_TYPE_GENERAL, "smime", smime_main },
|
||||
#ifndef OPENSSL_NO_SPEED
|
||||
{ FUNC_TYPE_GENERAL, "speed", speed_main },
|
||||
#endif
|
||||
{ FUNC_TYPE_GENERAL, "spkac", spkac_main },
|
||||
{ FUNC_TYPE_GENERAL, "ts", ts_main },
|
||||
{ FUNC_TYPE_GENERAL, "verify", verify_main },
|
||||
{ FUNC_TYPE_GENERAL, "version", version_main },
|
||||
{ FUNC_TYPE_GENERAL, "x509", x509_main },
|
||||
|
||||
#ifndef OPENSSL_NO_DH
|
||||
{ FUNC_TYPE_GENERAL, "dh", dh_main },
|
||||
{ FUNC_TYPE_GENERAL, "dhparam", dhparam_main },
|
||||
{ FUNC_TYPE_GENERAL, "gendh", gendh_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
{ FUNC_TYPE_GENERAL, "dsa", dsa_main },
|
||||
{ FUNC_TYPE_GENERAL, "dsaparam", dsaparam_main },
|
||||
{ FUNC_TYPE_GENERAL, "gendsa", gendsa_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
{ FUNC_TYPE_GENERAL, "ec", ec_main },
|
||||
{ FUNC_TYPE_GENERAL, "ecparam", ecparam_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
{ FUNC_TYPE_GENERAL, "genrsa", genrsa_main },
|
||||
{ FUNC_TYPE_GENERAL, "rsa", rsa_main },
|
||||
{ FUNC_TYPE_GENERAL, "rsautl", rsautl_main },
|
||||
#endif
|
||||
|
||||
/* Message Digests. */
|
||||
#ifndef OPENSSL_NO_GOST
|
||||
{ FUNC_TYPE_MD, "gost-mac", dgst_main },
|
||||
{ FUNC_TYPE_MD, "md_gost94", dgst_main },
|
||||
{ FUNC_TYPE_MD, "streebog256", dgst_main },
|
||||
{ FUNC_TYPE_MD, "streebog512", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD4
|
||||
{ FUNC_TYPE_MD, "md4", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
{ FUNC_TYPE_MD, "md5", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RIPEMD160
|
||||
{ FUNC_TYPE_MD, "ripemd160", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA1
|
||||
{ FUNC_TYPE_MD, "sha1", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA224
|
||||
{ FUNC_TYPE_MD, "sha224", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA256
|
||||
{ FUNC_TYPE_MD, "sha256", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA384
|
||||
{ FUNC_TYPE_MD, "sha384", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SHA512
|
||||
{ FUNC_TYPE_MD, "sha512", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SM3
|
||||
{ FUNC_TYPE_MD, "sm3", dgst_main },
|
||||
{ FUNC_TYPE_MD, "sm3WithRSAEncryption", dgst_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_WHIRLPOOL
|
||||
{ FUNC_TYPE_MD, "whirlpool", dgst_main },
|
||||
#endif
|
||||
|
||||
/* Ciphers. */
|
||||
{ FUNC_TYPE_CIPHER, "base64", enc_main },
|
||||
#ifndef OPENSSL_NO_AES
|
||||
{ FUNC_TYPE_CIPHER, "aes-128-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "aes-128-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "aes-192-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "aes-192-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "aes-256-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "aes-256-ecb", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_BF
|
||||
{ FUNC_TYPE_CIPHER, "bf", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "bf-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "bf-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "bf-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "bf-ofb", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAMELLIA
|
||||
{ FUNC_TYPE_CIPHER, "camellia-128-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "camellia-128-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "camellia-192-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "camellia-192-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "camellia-256-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "camellia-256-ecb", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAST
|
||||
{ FUNC_TYPE_CIPHER, "cast", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "cast5-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "cast5-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "cast5-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "cast5-ofb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "cast-cbc", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CHACHA
|
||||
{ FUNC_TYPE_CIPHER, "chacha", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{ FUNC_TYPE_CIPHER, "des", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des3", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "desx", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede3", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede3-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede3-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ofb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede-ofb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "des-ede3-ofb", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
{ FUNC_TYPE_CIPHER, "idea", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "idea-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "idea-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "idea-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "idea-ofb", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC2
|
||||
{ FUNC_TYPE_CIPHER, "rc2", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-cfb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-ofb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-64-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc2-40-cbc", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
{ FUNC_TYPE_CIPHER, "rc4", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "rc4-40", enc_main },
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_SM4
|
||||
{ FUNC_TYPE_CIPHER, "sm4", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "sm4-ecb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "sm4-cbc", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "sm4-ofb", enc_main },
|
||||
{ FUNC_TYPE_CIPHER, "sm4-cfb", enc_main },
|
||||
#endif
|
||||
{ 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static void openssl_startup(void);
|
||||
static void openssl_shutdown(void);
|
||||
|
||||
/* The LHASH callbacks ("hash" & "cmp") have been replaced by functions with the
|
||||
* base prototypes (we cast each variable inside the function to the required
|
||||
* type of "FUNCTION*"). This removes the necessity for macro-generated wrapper
|
||||
* functions. */
|
||||
|
||||
static LHASH_OF(FUNCTION) *prog_init(void);
|
||||
static int do_cmd(LHASH_OF(FUNCTION) *prog, int argc, char *argv[]);
|
||||
static void print_help(void);
|
||||
static void list_pkey(BIO * out);
|
||||
static void list_cipher(BIO * out);
|
||||
static void list_md(BIO * out);
|
||||
char *default_config_file = NULL;
|
||||
|
||||
CONF *config = NULL;
|
||||
BIO *bio_err = NULL;
|
||||
|
||||
static void
|
||||
openssl_startup(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
SSL_library_init();
|
||||
SSL_load_error_strings();
|
||||
|
||||
setup_ui();
|
||||
}
|
||||
|
||||
static void
|
||||
openssl_shutdown(void)
|
||||
{
|
||||
CONF_modules_unload(1);
|
||||
destroy_ui();
|
||||
OBJ_cleanup();
|
||||
EVP_cleanup();
|
||||
CRYPTO_cleanup_all_ex_data();
|
||||
ERR_remove_thread_state(NULL);
|
||||
ERR_free_strings();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *to_free = NULL;
|
||||
int i, ret = 0;
|
||||
char *p;
|
||||
LHASH_OF(FUNCTION) * prog = NULL;
|
||||
long errline;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath inet dns proc flock tty", NULL) == -1) {
|
||||
fprintf(stderr, "openssl: pledge: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
|
||||
if (bio_err == NULL) {
|
||||
fprintf(stderr, "openssl: failed to initialise bio_err\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (BIO_sock_init() != 1) {
|
||||
BIO_printf(bio_err, "BIO_sock_init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
openssl_startup();
|
||||
|
||||
/* Lets load up our environment a little */
|
||||
p = getenv("OPENSSL_CONF");
|
||||
if (p == NULL) {
|
||||
p = to_free = make_config_name();
|
||||
if (p == NULL) {
|
||||
BIO_printf(bio_err, "error making config file name\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
default_config_file = p;
|
||||
|
||||
config = NCONF_new(NULL);
|
||||
i = NCONF_load(config, p, &errline);
|
||||
if (i == 0) {
|
||||
if (ERR_GET_REASON(ERR_peek_last_error()) ==
|
||||
CONF_R_NO_SUCH_FILE) {
|
||||
BIO_printf(bio_err,
|
||||
"WARNING: can't open config file: %s\n", p);
|
||||
ERR_clear_error();
|
||||
NCONF_free(config);
|
||||
config = NULL;
|
||||
} else {
|
||||
ERR_print_errors(bio_err);
|
||||
NCONF_free(config);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!load_config(bio_err, NULL)) {
|
||||
BIO_printf(bio_err, "failed to load configuration\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
prog = prog_init();
|
||||
|
||||
/*
|
||||
* ok, now check that there are not arguments, if there are, run with
|
||||
* them, shifting the executable name off the front
|
||||
*/
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (argc < 1) {
|
||||
print_help();
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = do_cmd(prog, argc, argv);
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
free(to_free);
|
||||
|
||||
if (config != NULL) {
|
||||
NCONF_free(config);
|
||||
config = NULL;
|
||||
}
|
||||
if (prog != NULL)
|
||||
lh_FUNCTION_free(prog);
|
||||
|
||||
openssl_shutdown();
|
||||
|
||||
if (bio_err != NULL) {
|
||||
BIO_free(bio_err);
|
||||
bio_err = NULL;
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#define LIST_STANDARD_COMMANDS "list-standard-commands"
|
||||
#define LIST_MESSAGE_DIGEST_COMMANDS "list-message-digest-commands"
|
||||
#define LIST_MESSAGE_DIGEST_ALGORITHMS "list-message-digest-algorithms"
|
||||
#define LIST_CIPHER_COMMANDS "list-cipher-commands"
|
||||
#define LIST_CIPHER_ALGORITHMS "list-cipher-algorithms"
|
||||
#define LIST_PUBLIC_KEY_ALGORITHMS "list-public-key-algorithms"
|
||||
|
||||
|
||||
static int
|
||||
do_cmd(LHASH_OF(FUNCTION) * prog, int argc, char *argv[])
|
||||
{
|
||||
FUNCTION f, *fp;
|
||||
int ret = 1;
|
||||
|
||||
if (argc <= 0 || argv[0] == NULL)
|
||||
return 0;
|
||||
|
||||
f.name = argv[0];
|
||||
fp = lh_FUNCTION_retrieve(prog, &f);
|
||||
if (fp == NULL) {
|
||||
if (EVP_get_digestbyname(argv[0])) {
|
||||
f.type = FUNC_TYPE_MD;
|
||||
f.func = dgst_main;
|
||||
fp = &f;
|
||||
} else if (EVP_get_cipherbyname(argv[0])) {
|
||||
f.type = FUNC_TYPE_CIPHER;
|
||||
f.func = enc_main;
|
||||
fp = &f;
|
||||
}
|
||||
}
|
||||
|
||||
if (fp != NULL)
|
||||
return fp->func(argc, argv);
|
||||
|
||||
if (strcmp(argv[0], "help") == 0) {
|
||||
print_help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((strncmp(argv[0], "no-", 3)) == 0) {
|
||||
BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
f.name = argv[0] + 3;
|
||||
ret = (lh_FUNCTION_retrieve(prog, &f) != NULL);
|
||||
if (!ret)
|
||||
BIO_printf(bio_stdout, "%s\n", argv[0]);
|
||||
else
|
||||
BIO_printf(bio_stdout, "%s\n", argv[0] + 3);
|
||||
BIO_free_all(bio_stdout);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0) ||
|
||||
(strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0) ||
|
||||
(strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0) ||
|
||||
(strcmp(argv[0], LIST_CIPHER_COMMANDS) == 0) ||
|
||||
(strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0) ||
|
||||
(strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)) {
|
||||
int list_type;
|
||||
BIO *bio_stdout;
|
||||
|
||||
if (strcmp(argv[0], LIST_STANDARD_COMMANDS) == 0)
|
||||
list_type = FUNC_TYPE_GENERAL;
|
||||
else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_COMMANDS) == 0)
|
||||
list_type = FUNC_TYPE_MD;
|
||||
else if (strcmp(argv[0], LIST_MESSAGE_DIGEST_ALGORITHMS) == 0)
|
||||
list_type = FUNC_TYPE_MD_ALG;
|
||||
else if (strcmp(argv[0], LIST_PUBLIC_KEY_ALGORITHMS) == 0)
|
||||
list_type = FUNC_TYPE_PKEY;
|
||||
else if (strcmp(argv[0], LIST_CIPHER_ALGORITHMS) == 0)
|
||||
list_type = FUNC_TYPE_CIPHER_ALG;
|
||||
else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
|
||||
list_type = FUNC_TYPE_CIPHER;
|
||||
bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
|
||||
if (list_type == FUNC_TYPE_PKEY)
|
||||
list_pkey(bio_stdout);
|
||||
if (list_type == FUNC_TYPE_MD_ALG)
|
||||
list_md(bio_stdout);
|
||||
if (list_type == FUNC_TYPE_CIPHER_ALG)
|
||||
list_cipher(bio_stdout);
|
||||
else {
|
||||
for (fp = functions; fp->name != NULL; fp++)
|
||||
if (fp->type == list_type)
|
||||
BIO_printf(bio_stdout, "%s\n",
|
||||
fp->name);
|
||||
}
|
||||
BIO_free_all(bio_stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIO_printf(bio_err,
|
||||
"openssl:Error: '%s' is an invalid command.\n",
|
||||
argv[0]);
|
||||
print_help();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_help(void)
|
||||
{
|
||||
FUNCTION *fp;
|
||||
int i = 0;
|
||||
int tp = 0;
|
||||
int nl;
|
||||
|
||||
BIO_printf(bio_err, "\nStandard commands");
|
||||
for (fp = functions; fp->name != NULL; fp++) {
|
||||
nl = 0;
|
||||
#ifdef OPENSSL_NO_CAMELLIA
|
||||
if (((i++) % 5) == 0)
|
||||
#else
|
||||
if (((i++) % 4) == 0)
|
||||
#endif
|
||||
{
|
||||
BIO_printf(bio_err, "\n");
|
||||
nl = 1;
|
||||
}
|
||||
if (fp->type != tp) {
|
||||
tp = fp->type;
|
||||
if (!nl)
|
||||
BIO_printf(bio_err, "\n");
|
||||
if (tp == FUNC_TYPE_MD) {
|
||||
i = 1;
|
||||
BIO_printf(bio_err,
|
||||
"\nMessage Digest commands (see the `dgst' command for more details)\n");
|
||||
} else if (tp == FUNC_TYPE_CIPHER) {
|
||||
i = 1;
|
||||
BIO_printf(bio_err, "\nCipher commands (see the `enc' command for more details)\n");
|
||||
}
|
||||
}
|
||||
#ifdef OPENSSL_NO_CAMELLIA
|
||||
BIO_printf(bio_err, "%-15s", fp->name);
|
||||
#else
|
||||
BIO_printf(bio_err, "%-18s", fp->name);
|
||||
#endif
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "\n\n");
|
||||
}
|
||||
|
||||
static int
|
||||
SortFnByName(const void *_f1, const void *_f2)
|
||||
{
|
||||
const FUNCTION *f1 = _f1;
|
||||
const FUNCTION *f2 = _f2;
|
||||
|
||||
if (f1->type != f2->type)
|
||||
return f1->type - f2->type;
|
||||
return strcmp(f1->name, f2->name);
|
||||
}
|
||||
|
||||
static void
|
||||
list_pkey(BIO * out)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
int pkey_id, pkey_base_id, pkey_flags;
|
||||
const char *pinfo, *pem_str;
|
||||
ameth = EVP_PKEY_asn1_get0(i);
|
||||
EVP_PKEY_asn1_get0_info(&pkey_id, &pkey_base_id, &pkey_flags,
|
||||
&pinfo, &pem_str, ameth);
|
||||
if (pkey_flags & ASN1_PKEY_ALIAS) {
|
||||
BIO_printf(out, "Name: %s\n",
|
||||
OBJ_nid2ln(pkey_id));
|
||||
BIO_printf(out, "\tType: Alias to %s\n",
|
||||
OBJ_nid2ln(pkey_base_id));
|
||||
} else {
|
||||
BIO_printf(out, "Name: %s\n", pinfo);
|
||||
BIO_printf(out, "\tType: %s Algorithm\n",
|
||||
pkey_flags & ASN1_PKEY_DYNAMIC ?
|
||||
"External" : "Builtin");
|
||||
BIO_printf(out, "\tOID: %s\n", OBJ_nid2ln(pkey_id));
|
||||
if (pem_str == NULL)
|
||||
pem_str = "(none)";
|
||||
BIO_printf(out, "\tPEM string: %s\n", pem_str);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
list_cipher_fn(const EVP_CIPHER * c, const char *from, const char *to,
|
||||
void *arg)
|
||||
{
|
||||
if (c)
|
||||
BIO_printf(arg, "%s\n", EVP_CIPHER_name(c));
|
||||
else {
|
||||
if (!from)
|
||||
from = "<undefined>";
|
||||
if (!to)
|
||||
to = "<undefined>";
|
||||
BIO_printf(arg, "%s => %s\n", from, to);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
list_cipher(BIO * out)
|
||||
{
|
||||
EVP_CIPHER_do_all_sorted(list_cipher_fn, out);
|
||||
}
|
||||
|
||||
static void
|
||||
list_md_fn(const EVP_MD * m, const char *from, const char *to, void *arg)
|
||||
{
|
||||
if (m)
|
||||
BIO_printf(arg, "%s\n", EVP_MD_name(m));
|
||||
else {
|
||||
if (!from)
|
||||
from = "<undefined>";
|
||||
if (!to)
|
||||
to = "<undefined>";
|
||||
BIO_printf(arg, "%s => %s\n", from, to);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
list_md(BIO * out)
|
||||
{
|
||||
EVP_MD_do_all_sorted(list_md_fn, out);
|
||||
}
|
||||
|
||||
static int
|
||||
function_cmp(const FUNCTION * a, const FUNCTION * b)
|
||||
{
|
||||
return strncmp(a->name, b->name, 8);
|
||||
}
|
||||
|
||||
static IMPLEMENT_LHASH_COMP_FN(function, FUNCTION)
|
||||
|
||||
static unsigned long
|
||||
function_hash(const FUNCTION * a)
|
||||
{
|
||||
return lh_strhash(a->name);
|
||||
}
|
||||
|
||||
static IMPLEMENT_LHASH_HASH_FN(function, FUNCTION)
|
||||
|
||||
static LHASH_OF(FUNCTION) *
|
||||
prog_init(void)
|
||||
{
|
||||
LHASH_OF(FUNCTION) * ret;
|
||||
FUNCTION *f;
|
||||
size_t i;
|
||||
|
||||
/* Purely so it looks nice when the user hits ? */
|
||||
for (i = 0, f = functions; f->name != NULL; ++f, ++i)
|
||||
;
|
||||
qsort(functions, i, sizeof *functions, SortFnByName);
|
||||
|
||||
if ((ret = lh_FUNCTION_new()) == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (f = functions; f->name != NULL; f++)
|
||||
(void) lh_FUNCTION_insert(ret, f);
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,524 +0,0 @@
|
||||
/* $OpenBSD: passwd.c,v 1.14 2023/03/06 14:32:06 tb Exp $ */
|
||||
|
||||
#if defined OPENSSL_NO_MD5
|
||||
#define NO_MD5CRYPT_1
|
||||
#endif
|
||||
|
||||
#if !defined(OPENSSL_NO_DES) || !defined(NO_MD5CRYPT_1)
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#ifndef OPENSSL_NO_DES
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
#ifndef NO_MD5CRYPT_1
|
||||
#include <openssl/md5.h>
|
||||
#endif
|
||||
|
||||
static unsigned const char cov_2char[64] = {
|
||||
/* from crypto/des/fcrypt.c */
|
||||
0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35,
|
||||
0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44,
|
||||
0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C,
|
||||
0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54,
|
||||
0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62,
|
||||
0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
|
||||
0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72,
|
||||
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A
|
||||
};
|
||||
|
||||
static int
|
||||
do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
|
||||
char *passwd, BIO * out, int quiet, int table, int reverse,
|
||||
size_t pw_maxlen, int usecrypt, int use1, int useapr1);
|
||||
|
||||
static struct {
|
||||
char *infile;
|
||||
int in_stdin;
|
||||
int noverify;
|
||||
int quiet;
|
||||
int reverse;
|
||||
char *salt;
|
||||
int table;
|
||||
int use1;
|
||||
int useapr1;
|
||||
int usecrypt;
|
||||
} cfg;
|
||||
|
||||
static const struct option passwd_options[] = {
|
||||
#ifndef NO_MD5CRYPT_1
|
||||
{
|
||||
.name = "1",
|
||||
.desc = "Use MD5 based BSD password algorithm 1",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.use1,
|
||||
},
|
||||
{
|
||||
.name = "apr1",
|
||||
.desc = "Use apr1 algorithm (Apache variant of BSD algorithm)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.useapr1,
|
||||
},
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DES
|
||||
{
|
||||
.name = "crypt",
|
||||
.desc = "Use crypt algorithm (default)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.usecrypt,
|
||||
},
|
||||
#endif
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Read passwords from specified file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "noverify",
|
||||
.desc = "Do not verify password",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noverify,
|
||||
},
|
||||
{
|
||||
.name = "quiet",
|
||||
.desc = "Do not output warnings",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.quiet,
|
||||
},
|
||||
{
|
||||
.name = "reverse",
|
||||
.desc = "Reverse table columns (requires -table)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.reverse,
|
||||
},
|
||||
{
|
||||
.name = "salt",
|
||||
.argname = "string",
|
||||
.desc = "Use specified salt",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.salt,
|
||||
},
|
||||
{
|
||||
.name = "stdin",
|
||||
.desc = "Read passwords from stdin",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.in_stdin,
|
||||
},
|
||||
{
|
||||
.name = "table",
|
||||
.desc = "Output cleartext and hashed passwords (tab separated)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.table,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
passwd_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: passwd [-1 | -apr1 | -crypt] [-in file] "
|
||||
"[-noverify] [-quiet]\n"
|
||||
" [-reverse] [-salt string] [-stdin] [-table] [password]\n\n");
|
||||
options_usage(passwd_options);
|
||||
}
|
||||
|
||||
int
|
||||
passwd_main(int argc, char **argv)
|
||||
{
|
||||
char *passwd = NULL, **passwds = NULL;
|
||||
char *salt_malloc = NULL, *passwd_malloc = NULL;
|
||||
size_t passwd_malloc_size = 0;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
int badopt = 0;
|
||||
int passed_salt = 0;
|
||||
size_t pw_maxlen = 0;
|
||||
int argsused;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, passwd_options, NULL, &argsused) != 0) {
|
||||
passwd_usage();
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (argsused < argc)
|
||||
passwds = &argv[argsused];
|
||||
if (cfg.salt != NULL)
|
||||
passed_salt = 1;
|
||||
|
||||
if (!cfg.usecrypt && !cfg.use1 &&
|
||||
!cfg.useapr1)
|
||||
cfg.usecrypt = 1; /* use default */
|
||||
if (cfg.usecrypt + cfg.use1 +
|
||||
cfg.useapr1 > 1)
|
||||
badopt = 1; /* conflicting options */
|
||||
|
||||
/* Reject unsupported algorithms */
|
||||
#ifdef OPENSSL_NO_DES
|
||||
if (cfg.usecrypt)
|
||||
badopt = 1;
|
||||
#endif
|
||||
#ifdef NO_MD5CRYPT_1
|
||||
if (cfg.use1 || cfg.useapr1)
|
||||
badopt = 1;
|
||||
#endif
|
||||
|
||||
if (badopt) {
|
||||
passwd_usage();
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((out = BIO_new(BIO_s_file())) == NULL)
|
||||
goto err;
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
|
||||
|
||||
if (cfg.infile != NULL || cfg.in_stdin) {
|
||||
if ((in = BIO_new(BIO_s_file())) == NULL)
|
||||
goto err;
|
||||
if (cfg.infile != NULL) {
|
||||
assert(cfg.in_stdin == 0);
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
assert(cfg.in_stdin);
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
}
|
||||
}
|
||||
if (cfg.usecrypt)
|
||||
pw_maxlen = 8;
|
||||
else if (cfg.use1 || cfg.useapr1)
|
||||
pw_maxlen = 256;/* arbitrary limit, should be enough for most
|
||||
* passwords */
|
||||
|
||||
if (passwds == NULL) {
|
||||
/* no passwords on the command line */
|
||||
|
||||
passwd_malloc_size = pw_maxlen + 2;
|
||||
/* longer than necessary so that we can warn about truncation */
|
||||
passwd = passwd_malloc = malloc(passwd_malloc_size);
|
||||
if (passwd_malloc == NULL)
|
||||
goto err;
|
||||
}
|
||||
if (in == NULL && passwds == NULL) {
|
||||
/* build a null-terminated list */
|
||||
static char *passwds_static[2] = {NULL, NULL};
|
||||
|
||||
passwds = passwds_static;
|
||||
if (in == NULL)
|
||||
if (EVP_read_pw_string(passwd_malloc,
|
||||
passwd_malloc_size, "Password: ",
|
||||
!(passed_salt || cfg.noverify)) != 0)
|
||||
goto err;
|
||||
passwds[0] = passwd_malloc;
|
||||
}
|
||||
if (in == NULL) {
|
||||
assert(passwds != NULL);
|
||||
assert(*passwds != NULL);
|
||||
|
||||
do { /* loop over list of passwords */
|
||||
passwd = *passwds++;
|
||||
if (!do_passwd(passed_salt, &cfg.salt,
|
||||
&salt_malloc, passwd, out, cfg.quiet,
|
||||
cfg.table, cfg.reverse,
|
||||
pw_maxlen, cfg.usecrypt,
|
||||
cfg.use1, cfg.useapr1))
|
||||
goto err;
|
||||
} while (*passwds != NULL);
|
||||
} else {
|
||||
int done;
|
||||
|
||||
assert(passwd != NULL);
|
||||
do {
|
||||
int r = BIO_gets(in, passwd, pw_maxlen + 1);
|
||||
if (r > 0) {
|
||||
char *c = (strchr(passwd, '\n'));
|
||||
if (c != NULL)
|
||||
*c = 0; /* truncate at newline */
|
||||
else {
|
||||
/* ignore rest of line */
|
||||
char trash[BUFSIZ];
|
||||
do
|
||||
r = BIO_gets(in, trash, sizeof trash);
|
||||
while ((r > 0) && (!strchr(trash, '\n')));
|
||||
}
|
||||
|
||||
if (!do_passwd(passed_salt, &cfg.salt,
|
||||
&salt_malloc, passwd, out,
|
||||
cfg.quiet, cfg.table,
|
||||
cfg.reverse, pw_maxlen,
|
||||
cfg.usecrypt, cfg.use1,
|
||||
cfg.useapr1))
|
||||
goto err;
|
||||
}
|
||||
done = (r <= 0);
|
||||
} while (!done);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
ERR_print_errors(bio_err);
|
||||
|
||||
free(salt_malloc);
|
||||
free(passwd_malloc);
|
||||
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_MD5CRYPT_1
|
||||
/* MD5-based password algorithm (should probably be available as a library
|
||||
* function; then the static buffer would not be acceptable).
|
||||
* For magic string "1", this should be compatible to the MD5-based BSD
|
||||
* password algorithm.
|
||||
* For 'magic' string "apr1", this is compatible to the MD5-based Apache
|
||||
* password algorithm.
|
||||
* (Apparently, the Apache password algorithm is identical except that the
|
||||
* 'magic' string was changed -- the laziest application of the NIH principle
|
||||
* I've ever encountered.)
|
||||
*/
|
||||
static char *
|
||||
md5crypt(const char *passwd, const char *magic, const char *salt)
|
||||
{
|
||||
static char out_buf[6 + 9 + 24 + 2]; /* "$apr1$..salt..$.......md5h
|
||||
* ash..........\0" */
|
||||
unsigned char buf[MD5_DIGEST_LENGTH];
|
||||
char *salt_out;
|
||||
int n;
|
||||
unsigned int i;
|
||||
EVP_MD_CTX *md = NULL, *md2 = NULL;
|
||||
size_t passwd_len, salt_len;
|
||||
|
||||
passwd_len = strlen(passwd);
|
||||
out_buf[0] = '$';
|
||||
out_buf[1] = 0;
|
||||
assert(strlen(magic) <= 4); /* "1" or "apr1" */
|
||||
strlcat(out_buf, magic, sizeof(out_buf));
|
||||
strlcat(out_buf, "$", sizeof(out_buf));
|
||||
strlcat(out_buf, salt, sizeof(out_buf));
|
||||
assert(strlen(out_buf) <= 6 + 8); /* "$apr1$..salt.." */
|
||||
salt_out = out_buf + 2 + strlen(magic);
|
||||
salt_len = strlen(salt_out);
|
||||
assert(salt_len <= 8);
|
||||
|
||||
if ((md = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!EVP_DigestInit_ex(md, EVP_md5(), NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md, passwd, passwd_len))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md, "$", 1))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md, magic, strlen(magic)))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md, "$", 1))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md, salt_out, salt_len))
|
||||
goto err;
|
||||
|
||||
if ((md2 = EVP_MD_CTX_new()) == NULL)
|
||||
goto err;
|
||||
if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md2, salt_out, salt_len))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(md2, buf, NULL))
|
||||
goto err;
|
||||
|
||||
for (i = passwd_len; i > sizeof buf; i -= sizeof buf) {
|
||||
if (!EVP_DigestUpdate(md, buf, sizeof buf))
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md, buf, i))
|
||||
goto err;
|
||||
|
||||
n = passwd_len;
|
||||
while (n) {
|
||||
if (!EVP_DigestUpdate(md, (n & 1) ? "\0" : passwd, 1))
|
||||
goto err;
|
||||
n >>= 1;
|
||||
}
|
||||
if (!EVP_DigestFinal_ex(md, buf, NULL))
|
||||
goto err;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
if (!EVP_DigestInit_ex(md2, EVP_md5(), NULL))
|
||||
goto err;
|
||||
if (!EVP_DigestUpdate(md2,
|
||||
(i & 1) ? (unsigned const char *) passwd : buf,
|
||||
(i & 1) ? passwd_len : sizeof buf))
|
||||
goto err;
|
||||
if (i % 3) {
|
||||
if (!EVP_DigestUpdate(md2, salt_out, salt_len))
|
||||
goto err;
|
||||
}
|
||||
if (i % 7) {
|
||||
if (!EVP_DigestUpdate(md2, passwd, passwd_len))
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_DigestUpdate(md2,
|
||||
(i & 1) ? buf : (unsigned const char *) passwd,
|
||||
(i & 1) ? sizeof buf : passwd_len))
|
||||
goto err;
|
||||
if (!EVP_DigestFinal_ex(md2, buf, NULL))
|
||||
goto err;
|
||||
}
|
||||
EVP_MD_CTX_free(md2);
|
||||
md2 = NULL;
|
||||
|
||||
{
|
||||
/* transform buf into output string */
|
||||
|
||||
unsigned char buf_perm[sizeof buf];
|
||||
int dest, source;
|
||||
char *output;
|
||||
|
||||
/* silly output permutation */
|
||||
for (dest = 0, source = 0; dest < 14; dest++, source = (source + 6) % 17)
|
||||
buf_perm[dest] = buf[source];
|
||||
buf_perm[14] = buf[5];
|
||||
buf_perm[15] = buf[11];
|
||||
assert(16 == sizeof buf_perm);
|
||||
|
||||
output = salt_out + salt_len;
|
||||
assert(output == out_buf + strlen(out_buf));
|
||||
|
||||
*output++ = '$';
|
||||
|
||||
for (i = 0; i < 15; i += 3) {
|
||||
*output++ = cov_2char[buf_perm[i + 2] & 0x3f];
|
||||
*output++ = cov_2char[((buf_perm[i + 1] & 0xf) << 2) |
|
||||
(buf_perm[i + 2] >> 6)];
|
||||
*output++ = cov_2char[((buf_perm[i] & 3) << 4) |
|
||||
(buf_perm[i + 1] >> 4)];
|
||||
*output++ = cov_2char[buf_perm[i] >> 2];
|
||||
}
|
||||
assert(i == 15);
|
||||
*output++ = cov_2char[buf_perm[i] & 0x3f];
|
||||
*output++ = cov_2char[buf_perm[i] >> 6];
|
||||
*output = 0;
|
||||
assert(strlen(out_buf) < sizeof(out_buf));
|
||||
}
|
||||
EVP_MD_CTX_free(md);
|
||||
|
||||
return out_buf;
|
||||
err:
|
||||
EVP_MD_CTX_free(md);
|
||||
EVP_MD_CTX_free(md2);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int
|
||||
do_passwd(int passed_salt, char **salt_p, char **salt_malloc_p,
|
||||
char *passwd, BIO * out, int quiet, int table, int reverse,
|
||||
size_t pw_maxlen, int usecrypt, int use1, int useapr1)
|
||||
{
|
||||
char *hash = NULL;
|
||||
|
||||
assert(salt_p != NULL);
|
||||
assert(salt_malloc_p != NULL);
|
||||
|
||||
/* first make sure we have a salt */
|
||||
if (!passed_salt) {
|
||||
#ifndef OPENSSL_NO_DES
|
||||
if (usecrypt) {
|
||||
if (*salt_malloc_p == NULL) {
|
||||
*salt_p = *salt_malloc_p = malloc(3);
|
||||
if (*salt_malloc_p == NULL)
|
||||
goto err;
|
||||
}
|
||||
arc4random_buf(*salt_p, 2);
|
||||
(*salt_p)[0] = cov_2char[(*salt_p)[0] & 0x3f]; /* 6 bits */
|
||||
(*salt_p)[1] = cov_2char[(*salt_p)[1] & 0x3f]; /* 6 bits */
|
||||
(*salt_p)[2] = 0;
|
||||
}
|
||||
#endif /* !OPENSSL_NO_DES */
|
||||
|
||||
#ifndef NO_MD5CRYPT_1
|
||||
if (use1 || useapr1) {
|
||||
int i;
|
||||
|
||||
if (*salt_malloc_p == NULL) {
|
||||
*salt_p = *salt_malloc_p = malloc(9);
|
||||
if (*salt_malloc_p == NULL)
|
||||
goto err;
|
||||
}
|
||||
arc4random_buf(*salt_p, 8);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
(*salt_p)[i] = cov_2char[(*salt_p)[i] & 0x3f]; /* 6 bits */
|
||||
(*salt_p)[8] = 0;
|
||||
}
|
||||
#endif /* !NO_MD5CRYPT_1 */
|
||||
}
|
||||
assert(*salt_p != NULL);
|
||||
|
||||
/* truncate password if necessary */
|
||||
if ((strlen(passwd) > pw_maxlen)) {
|
||||
if (!quiet)
|
||||
BIO_printf(bio_err,
|
||||
"Warning: truncating password to %zu characters\n",
|
||||
pw_maxlen);
|
||||
passwd[pw_maxlen] = 0;
|
||||
}
|
||||
assert(strlen(passwd) <= pw_maxlen);
|
||||
|
||||
/* now compute password hash */
|
||||
#ifndef OPENSSL_NO_DES
|
||||
if (usecrypt)
|
||||
hash = DES_crypt(passwd, *salt_p);
|
||||
#endif
|
||||
#ifndef NO_MD5CRYPT_1
|
||||
if (use1 || useapr1)
|
||||
if ((hash = md5crypt(passwd, (use1 ? "1" : "apr1"), *salt_p)) == NULL)
|
||||
goto err;
|
||||
#endif
|
||||
assert(hash != NULL);
|
||||
|
||||
if (table && !reverse)
|
||||
BIO_printf(out, "%s\t%s\n", passwd, hash);
|
||||
else if (table && reverse)
|
||||
BIO_printf(out, "%s\t%s\n", hash, passwd);
|
||||
else
|
||||
BIO_printf(out, "%s\n", hash);
|
||||
return 1;
|
||||
|
||||
err:
|
||||
free(*salt_malloc_p);
|
||||
*salt_malloc_p = NULL;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
int
|
||||
passwd_main(int argc, char **argv)
|
||||
{
|
||||
fputs("Program not available.\n", stderr)
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,291 +0,0 @@
|
||||
/* $OpenBSD: pkcs7.c,v 1.15 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int p7_print;
|
||||
int print_certs;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option pkcs7_options[] = {
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not output encoded version of PKCS#7 structure",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "print",
|
||||
.desc = "Output ASN.1 representation of PKCS#7 structure",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.p7_print,
|
||||
},
|
||||
{
|
||||
.name = "print_certs",
|
||||
.desc = "Print out any certificates or CRLs contained in file",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.print_certs,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print out full certificate details",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
pkcs7_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: pkcs7 [-in file] "
|
||||
"[-inform DER | PEM] [-noout]\n"
|
||||
" [-out file] [-outform DER | PEM] [-print_certs] [-text]\n\n");
|
||||
options_usage(pkcs7_options);
|
||||
}
|
||||
|
||||
int
|
||||
pkcs7_main(int argc, char **argv)
|
||||
{
|
||||
PKCS7 *p7 = NULL;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
int ret = 1;
|
||||
int i;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, pkcs7_options, NULL, NULL) != 0) {
|
||||
pkcs7_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
out = BIO_new(BIO_s_file());
|
||||
if ((in == NULL) || (out == NULL)) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, cfg.infile) <= 0) {
|
||||
perror(cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.informat == FORMAT_ASN1)
|
||||
p7 = d2i_PKCS7_bio(in, NULL);
|
||||
else if (cfg.informat == FORMAT_PEM)
|
||||
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad input format specified for pkcs7 object\n");
|
||||
goto end;
|
||||
}
|
||||
if (p7 == NULL) {
|
||||
BIO_printf(bio_err, "unable to load PKCS7 object\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.p7_print)
|
||||
PKCS7_print_ctx(out, p7, 0, NULL);
|
||||
|
||||
if (cfg.print_certs) {
|
||||
STACK_OF(X509) * certs = NULL;
|
||||
STACK_OF(X509_CRL) * crls = NULL;
|
||||
|
||||
i = OBJ_obj2nid(p7->type);
|
||||
switch (i) {
|
||||
case NID_pkcs7_signed:
|
||||
if (p7->d.sign != NULL) {
|
||||
certs = p7->d.sign->cert;
|
||||
crls = p7->d.sign->crl;
|
||||
}
|
||||
break;
|
||||
case NID_pkcs7_signedAndEnveloped:
|
||||
if (p7->d.signed_and_enveloped != NULL) {
|
||||
certs = p7->d.signed_and_enveloped->cert;
|
||||
crls = p7->d.signed_and_enveloped->crl;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (certs != NULL) {
|
||||
X509 *x;
|
||||
|
||||
for (i = 0; i < sk_X509_num(certs); i++) {
|
||||
x = sk_X509_value(certs, i);
|
||||
if (cfg.text)
|
||||
X509_print(out, x);
|
||||
else
|
||||
dump_cert_text(out, x);
|
||||
|
||||
if (!cfg.noout)
|
||||
PEM_write_bio_X509(out, x);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
}
|
||||
if (crls != NULL) {
|
||||
X509_CRL *crl;
|
||||
|
||||
for (i = 0; i < sk_X509_CRL_num(crls); i++) {
|
||||
crl = sk_X509_CRL_value(crls, i);
|
||||
|
||||
X509_CRL_print(out, crl);
|
||||
|
||||
if (!cfg.noout)
|
||||
PEM_write_bio_X509_CRL(out, crl);
|
||||
BIO_puts(out, "\n");
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_PKCS7_bio(out, p7);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_PKCS7(out, p7);
|
||||
else {
|
||||
BIO_printf(bio_err, "bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write pkcs7 object\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (p7 != NULL)
|
||||
PKCS7_free(p7);
|
||||
if (in != NULL)
|
||||
BIO_free(in);
|
||||
if (out != NULL)
|
||||
BIO_free_all(out);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
/* $OpenBSD: pkcs8.c,v 1.17 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999-2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/pkcs12.h>
|
||||
|
||||
static struct {
|
||||
const EVP_CIPHER *cipher;
|
||||
char *infile;
|
||||
int informat;
|
||||
int iter;
|
||||
int nocrypt;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
char *passargin;
|
||||
char *passargout;
|
||||
int pbe_nid;
|
||||
int topk8;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
pkcs8_opt_v1(char *arg)
|
||||
{
|
||||
if ((cfg.pbe_nid = OBJ_txt2nid(arg)) == NID_undef) {
|
||||
fprintf(stderr, "Unknown PBE algorithm '%s'\n", arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pkcs8_opt_v2(char *arg)
|
||||
{
|
||||
if ((cfg.cipher = EVP_get_cipherbyname(arg)) == NULL) {
|
||||
fprintf(stderr, "Unknown cipher '%s'\n", arg);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option pkcs8_options[] = {
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "der | pem",
|
||||
.desc = "Input format (default PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "nocrypt",
|
||||
.desc = "Use or expect unencrypted private key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.nocrypt,
|
||||
},
|
||||
{
|
||||
.name = "noiter",
|
||||
.desc = "Use 1 as iteration count",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.iter,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "der | pem",
|
||||
.desc = "Output format (default PEM)",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "source",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "source",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{
|
||||
.name = "topk8",
|
||||
.desc = "Read traditional format key and write PKCS#8 format"
|
||||
" key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.topk8,
|
||||
},
|
||||
{
|
||||
.name = "v1",
|
||||
.argname = "algorithm",
|
||||
.desc = "Use PKCS#5 v1.5 or PKCS#12 with given algorithm",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = pkcs8_opt_v1,
|
||||
},
|
||||
{
|
||||
.name = "v2",
|
||||
.argname = "cipher",
|
||||
.desc = "Use PKCS#5 v2.0 with given cipher",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = pkcs8_opt_v2,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
pkcs8_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: pkcs8 [-in file] [inform der | pem] "
|
||||
"[-nocrypt] [-noiter]\n"
|
||||
" [-out file] [-outform der | pem] [-passin arg]\n"
|
||||
" [-passout arg] [-topk8] [-v1 alg] [-v2 alg]\n\n");
|
||||
options_usage(pkcs8_options);
|
||||
}
|
||||
|
||||
int
|
||||
pkcs8_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
X509_SIG *p8 = NULL;
|
||||
PKCS8_PRIV_KEY_INFO *p8inf = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.iter = PKCS12_DEFAULT_ITER;
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
cfg.pbe_nid = -1;
|
||||
|
||||
if (options_parse(argc, argv, pkcs8_options, NULL, NULL) != 0) {
|
||||
pkcs8_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin,
|
||||
cfg.passargout, &passin, &passout)) {
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
if ((cfg.pbe_nid == -1) && !cfg.cipher)
|
||||
cfg.pbe_nid = NID_pbeWithMD5AndDES_CBC;
|
||||
|
||||
if (cfg.infile) {
|
||||
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
|
||||
BIO_printf(bio_err,
|
||||
"Can't open input file '%s'\n",
|
||||
cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
|
||||
if (cfg.outfile) {
|
||||
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
|
||||
BIO_printf(bio_err, "Can't open output file '%s'\n",
|
||||
cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
if (cfg.topk8) {
|
||||
pkey = load_key(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "key");
|
||||
if (!pkey)
|
||||
goto end;
|
||||
if (!(p8inf = EVP_PKEY2PKCS8(pkey))) {
|
||||
BIO_printf(bio_err, "Error converting key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.nocrypt) {
|
||||
if (cfg.outformat == FORMAT_PEM)
|
||||
PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
|
||||
else if (cfg.outformat == FORMAT_ASN1)
|
||||
i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (passout)
|
||||
p8pass = passout;
|
||||
else {
|
||||
p8pass = pass;
|
||||
if (EVP_read_pw_string(pass, sizeof pass,
|
||||
"Enter Encryption Password:", 1))
|
||||
goto end;
|
||||
}
|
||||
if (!(p8 = PKCS8_encrypt(cfg.pbe_nid,
|
||||
cfg.cipher, p8pass, strlen(p8pass),
|
||||
NULL, 0, cfg.iter, p8inf))) {
|
||||
BIO_printf(bio_err, "Error encrypting key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outformat == FORMAT_PEM)
|
||||
PEM_write_bio_PKCS8(out, p8);
|
||||
else if (cfg.outformat == FORMAT_ASN1)
|
||||
i2d_PKCS8_bio(out, p8);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if (cfg.nocrypt) {
|
||||
if (cfg.informat == FORMAT_PEM)
|
||||
p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in, NULL,
|
||||
NULL, NULL);
|
||||
else if (cfg.informat == FORMAT_ASN1)
|
||||
p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (cfg.informat == FORMAT_PEM)
|
||||
p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
|
||||
else if (cfg.informat == FORMAT_ASN1)
|
||||
p8 = d2i_PKCS8_bio(in, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!p8) {
|
||||
BIO_printf(bio_err, "Error reading key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (passin)
|
||||
p8pass = passin;
|
||||
else {
|
||||
p8pass = pass;
|
||||
EVP_read_pw_string(pass, sizeof pass,
|
||||
"Enter Password:", 0);
|
||||
}
|
||||
p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
|
||||
}
|
||||
|
||||
if (!p8inf) {
|
||||
BIO_printf(bio_err, "Error decrypting key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (!(pkey = EVP_PKCS82PKEY(p8inf))) {
|
||||
BIO_printf(bio_err, "Error converting key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outformat == FORMAT_PEM)
|
||||
PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL,
|
||||
passout);
|
||||
else if (cfg.outformat == FORMAT_ASN1)
|
||||
i2d_PrivateKey_bio(out, pkey);
|
||||
else {
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
X509_SIG_free(p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8inf);
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
free(passin);
|
||||
free(passout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,309 +0,0 @@
|
||||
/* $OpenBSD: pkey.c,v 1.20 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static struct {
|
||||
int check;
|
||||
const EVP_CIPHER *cipher;
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
char *passargin;
|
||||
char *passargout;
|
||||
int pubcheck;
|
||||
int pubin;
|
||||
int pubout;
|
||||
int pubtext;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
pkey_opt_cipher(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.cipher = EVP_get_cipherbyname(name)) == NULL) {
|
||||
BIO_printf(bio_err, "Unknown cipher %s\n", name);
|
||||
return (1);
|
||||
}
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option pkey_options[] = {
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Check validity of key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not print encoded version of the key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "src",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "src",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{
|
||||
.name = "pubcheck",
|
||||
.desc = "Check validity of public key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubcheck,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Expect a public key (default private key)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pubin,
|
||||
},
|
||||
{
|
||||
.name = "pubout",
|
||||
.desc = "Output a public key (default private key)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pubout,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print the public/private key in plain text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = "text_pub",
|
||||
.desc = "Print out only public key in plain text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubtext,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = pkey_opt_cipher,
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
pkey_usage(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: pkey [-check] [-ciphername] [-in file] [-inform fmt] "
|
||||
"[-noout] [-out file]\n"
|
||||
" [-outform fmt] [-passin src] [-passout src] [-pubcheck] "
|
||||
"[-pubin] [-pubout]\n"
|
||||
" [-text] [-text_pub]\n\n");
|
||||
options_usage(pkey_options);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Valid ciphername values:\n\n");
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
pkey_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, pkey_options, NULL, NULL) != 0) {
|
||||
pkey_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.pubtext)
|
||||
cfg.text = 1;
|
||||
if (cfg.pubin)
|
||||
cfg.pubout = cfg.pubtext = 1;
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
|
||||
&passin, &passout)) {
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile) {
|
||||
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
|
||||
BIO_printf(bio_err,
|
||||
"Can't open output file %s\n", cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
if (cfg.pubin)
|
||||
pkey = load_pubkey(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "Public Key");
|
||||
else
|
||||
pkey = load_key(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "key");
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
if (cfg.check) {
|
||||
if (!pkey_check(out, pkey, EVP_PKEY_check, "Key pair"))
|
||||
goto end;
|
||||
} else if (cfg.pubcheck) {
|
||||
if (!pkey_check(out, pkey, EVP_PKEY_public_check, "Public key"))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!cfg.noout) {
|
||||
if (cfg.outformat == FORMAT_PEM) {
|
||||
if (cfg.pubout)
|
||||
PEM_write_bio_PUBKEY(out, pkey);
|
||||
else
|
||||
PEM_write_bio_PrivateKey(out, pkey,
|
||||
cfg.cipher, NULL, 0, NULL, passout);
|
||||
} else if (cfg.outformat == FORMAT_ASN1) {
|
||||
if (cfg.pubout)
|
||||
i2d_PUBKEY_bio(out, pkey);
|
||||
else
|
||||
i2d_PrivateKey_bio(out, pkey);
|
||||
} else {
|
||||
BIO_printf(bio_err, "Bad format specified for key\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
}
|
||||
if (cfg.text) {
|
||||
if (cfg.pubtext)
|
||||
EVP_PKEY_print_public(out, pkey, 0, NULL);
|
||||
else
|
||||
EVP_PKEY_print_private(out, pkey, 0, NULL);
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
free(passin);
|
||||
free(passout);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
/* $OpenBSD: pkeyparam.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
static struct {
|
||||
int check;
|
||||
char *infile;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option pkeyparam_options[] = {
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Check validity of key parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not print encoded version of the parameters",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print out the parameters in plain text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
pkeyparam_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: pkeyparam [-check] [-in file] [-noout] [-out file] "
|
||||
"[-text]\n");
|
||||
options_usage(pkeyparam_options);
|
||||
}
|
||||
|
||||
int
|
||||
pkeyparam_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, pkeyparam_options, NULL, NULL) != 0) {
|
||||
pkeyparam_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (cfg.infile) {
|
||||
if (!(in = BIO_new_file(cfg.infile, "r"))) {
|
||||
BIO_printf(bio_err, "Can't open input file %s\n",
|
||||
cfg.infile);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
|
||||
if (cfg.outfile) {
|
||||
if (!(out = BIO_new_file(cfg.outfile, "w"))) {
|
||||
BIO_printf(bio_err, "Can't open output file %s\n",
|
||||
cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
pkey = PEM_read_bio_Parameters(in, NULL);
|
||||
if (!pkey) {
|
||||
BIO_printf(bio_err, "Error reading parameters\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.check) {
|
||||
if (!pkey_check(out, pkey, EVP_PKEY_param_check, "Parameters"))
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!cfg.noout)
|
||||
PEM_write_bio_Parameters(out, pkey);
|
||||
|
||||
if (cfg.text)
|
||||
EVP_PKEY_print_params(out, pkey, 0, NULL);
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
BIO_free_all(out);
|
||||
BIO_free(in);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,571 +0,0 @@
|
||||
/* $OpenBSD: pkeyutl.c,v 1.20 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
|
||||
#define KEY_PRIVKEY 1
|
||||
#define KEY_PUBKEY 2
|
||||
#define KEY_CERT 3
|
||||
|
||||
static struct {
|
||||
int asn1parse;
|
||||
EVP_PKEY_CTX *ctx;
|
||||
int hexdump;
|
||||
char *infile;
|
||||
int key_type;
|
||||
int keyform;
|
||||
int keysize;
|
||||
char *outfile;
|
||||
char *passargin;
|
||||
int peerform;
|
||||
int pkey_op;
|
||||
int rev;
|
||||
char *sigfile;
|
||||
} cfg;
|
||||
|
||||
static void pkeyutl_usage(void);
|
||||
|
||||
static int init_ctx(char *keyfile);
|
||||
|
||||
static int setup_peer(char *file);
|
||||
|
||||
static int pkeyutl_pkeyopt(char *pkeyopt);
|
||||
|
||||
static int do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
|
||||
unsigned char *out, size_t * poutlen,
|
||||
unsigned char *in, size_t inlen);
|
||||
|
||||
static const struct option pkeyutl_options[] = {
|
||||
{
|
||||
.name = "asn1parse",
|
||||
.desc = "ASN.1 parse the output data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.asn1parse,
|
||||
},
|
||||
{
|
||||
.name = "certin",
|
||||
.desc = "Input is a certificate containing a public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = KEY_CERT,
|
||||
.opt.value = &cfg.key_type,
|
||||
},
|
||||
{
|
||||
.name = "decrypt",
|
||||
.desc = "Decrypt the input data using a private key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_DECRYPT,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
{
|
||||
.name = "derive",
|
||||
.desc = "Derive a shared secret using the peer key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_DERIVE,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
{
|
||||
.name = "encrypt",
|
||||
.desc = "Encrypt the input data using a public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_ENCRYPT,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
{
|
||||
.name = "hexdump",
|
||||
.desc = "Hex dump the output data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.hexdump,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inkey",
|
||||
.argname = "file",
|
||||
.desc = "Input key file",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = init_ctx,
|
||||
},
|
||||
{
|
||||
.name = "keyform",
|
||||
.argname = "fmt",
|
||||
.desc = "Input key format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.keyform,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "arg",
|
||||
.desc = "Key password source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "peerform",
|
||||
.argname = "fmt",
|
||||
.desc = "Input key format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.peerform,
|
||||
},
|
||||
{
|
||||
.name = "peerkey",
|
||||
.argname = "file",
|
||||
.desc = "Peer key file",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = setup_peer,
|
||||
},
|
||||
{
|
||||
.name = "pkeyopt",
|
||||
.argname = "opt:value",
|
||||
.desc = "Public key options",
|
||||
.type = OPTION_ARG_FUNC,
|
||||
.opt.argfunc = pkeyutl_pkeyopt,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Input is a public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = KEY_PUBKEY,
|
||||
.opt.value = &cfg.key_type,
|
||||
},
|
||||
{
|
||||
.name = "rev",
|
||||
.desc = "Reverse the input data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.rev,
|
||||
},
|
||||
{
|
||||
.name = "sigfile",
|
||||
.argname = "file",
|
||||
.desc = "Signature file (verify operation only)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.sigfile,
|
||||
},
|
||||
{
|
||||
.name = "sign",
|
||||
.desc = "Sign the input data using private key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_SIGN,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.desc = "Verify the input data using public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_VERIFY,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
{
|
||||
.name = "verifyrecover",
|
||||
.desc = "Verify with public key, recover original data",
|
||||
.type = OPTION_VALUE,
|
||||
.value = EVP_PKEY_OP_VERIFYRECOVER,
|
||||
.opt.value = &cfg.pkey_op,
|
||||
},
|
||||
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
pkeyutl_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: pkeyutl [-asn1parse] [-certin] [-decrypt] [-derive] "
|
||||
"[-encrypt]\n"
|
||||
" [-hexdump] [-in file] [-inkey file] [-keyform fmt]\n"
|
||||
" [-out file] [-passin arg] [-peerform fmt]\n"
|
||||
" [-peerkey file] [-pkeyopt opt:value] [-pubin] [-rev]\n"
|
||||
" [-sigfile file] [-sign] [-verify] [-verifyrecover]\n\n");
|
||||
options_usage(pkeyutl_options);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
pkeyutl_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
|
||||
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
|
||||
size_t buf_outlen = 0;
|
||||
int buf_inlen = 0, siglen = -1;
|
||||
|
||||
int ret = 1, rv = -1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.pkey_op = EVP_PKEY_OP_SIGN;
|
||||
cfg.key_type = KEY_PRIVKEY;
|
||||
cfg.keyform = FORMAT_PEM;
|
||||
cfg.peerform = FORMAT_PEM;
|
||||
cfg.keysize = -1;
|
||||
|
||||
if (options_parse(argc, argv, pkeyutl_options, NULL, NULL) != 0) {
|
||||
pkeyutl_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!cfg.ctx) {
|
||||
pkeyutl_usage();
|
||||
goto end;
|
||||
}
|
||||
if (cfg.sigfile &&
|
||||
(cfg.pkey_op != EVP_PKEY_OP_VERIFY)) {
|
||||
BIO_puts(bio_err, "Signature file specified for non verify\n");
|
||||
goto end;
|
||||
}
|
||||
if (!cfg.sigfile &&
|
||||
(cfg.pkey_op == EVP_PKEY_OP_VERIFY)) {
|
||||
BIO_puts(bio_err, "No signature file specified for verify\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.pkey_op != EVP_PKEY_OP_DERIVE) {
|
||||
if (cfg.infile) {
|
||||
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
|
||||
BIO_puts(bio_err,
|
||||
"Error Opening Input File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
}
|
||||
if (cfg.outfile) {
|
||||
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
|
||||
BIO_printf(bio_err, "Error Creating Output File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
if (cfg.sigfile) {
|
||||
BIO *sigbio = BIO_new_file(cfg.sigfile, "rb");
|
||||
if (!sigbio) {
|
||||
BIO_printf(bio_err, "Can't open signature file %s\n",
|
||||
cfg.sigfile);
|
||||
goto end;
|
||||
}
|
||||
siglen = bio_to_mem(&sig, cfg.keysize * 10, sigbio);
|
||||
BIO_free(sigbio);
|
||||
if (siglen <= 0) {
|
||||
BIO_printf(bio_err, "Error reading signature data\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (in) {
|
||||
/* Read the input data */
|
||||
buf_inlen = bio_to_mem(&buf_in, cfg.keysize * 10, in);
|
||||
if (buf_inlen <= 0) {
|
||||
BIO_printf(bio_err, "Error reading input Data\n");
|
||||
exit(1);
|
||||
}
|
||||
if (cfg.rev) {
|
||||
size_t i;
|
||||
unsigned char ctmp;
|
||||
size_t l = (size_t) buf_inlen;
|
||||
for (i = 0; i < l / 2; i++) {
|
||||
ctmp = buf_in[i];
|
||||
buf_in[i] = buf_in[l - 1 - i];
|
||||
buf_in[l - 1 - i] = ctmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg.pkey_op == EVP_PKEY_OP_VERIFY) {
|
||||
rv = EVP_PKEY_verify(cfg.ctx, sig, (size_t) siglen,
|
||||
buf_in, (size_t) buf_inlen);
|
||||
if (rv == 1) {
|
||||
BIO_puts(out, "Signature Verified Successfully\n");
|
||||
ret = 0;
|
||||
} else
|
||||
BIO_puts(out, "Signature Verification Failure\n");
|
||||
if (rv >= 0)
|
||||
goto end;
|
||||
} else {
|
||||
rv = do_keyop(cfg.ctx, cfg.pkey_op, NULL,
|
||||
(size_t *)&buf_outlen, buf_in, (size_t) buf_inlen);
|
||||
if (rv > 0) {
|
||||
buf_out = malloc(buf_outlen);
|
||||
if (!buf_out)
|
||||
rv = -1;
|
||||
else
|
||||
rv = do_keyop(cfg.ctx,
|
||||
cfg.pkey_op,
|
||||
buf_out, (size_t *) & buf_outlen,
|
||||
buf_in, (size_t) buf_inlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (rv <= 0) {
|
||||
BIO_printf(bio_err, "Public Key operation error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
if (cfg.asn1parse) {
|
||||
if (!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
|
||||
ERR_print_errors(bio_err);
|
||||
} else if (cfg.hexdump)
|
||||
BIO_dump(out, (char *) buf_out, buf_outlen);
|
||||
else
|
||||
BIO_write(out, buf_out, buf_outlen);
|
||||
|
||||
end:
|
||||
EVP_PKEY_CTX_free(cfg.ctx);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
free(buf_in);
|
||||
free(buf_out);
|
||||
free(sig);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
init_ctx(char *keyfile)
|
||||
{
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char *passin = NULL;
|
||||
int rv = -1;
|
||||
X509 *x;
|
||||
|
||||
if (((cfg.pkey_op == EVP_PKEY_OP_SIGN)
|
||||
|| (cfg.pkey_op == EVP_PKEY_OP_DECRYPT)
|
||||
|| (cfg.pkey_op == EVP_PKEY_OP_DERIVE))
|
||||
&& (cfg.key_type != KEY_PRIVKEY)) {
|
||||
BIO_printf(bio_err,
|
||||
"A private key is needed for this operation\n");
|
||||
goto end;
|
||||
}
|
||||
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin,
|
||||
NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
switch (cfg.key_type) {
|
||||
case KEY_PRIVKEY:
|
||||
pkey = load_key(bio_err, keyfile, cfg.keyform, 0,
|
||||
passin, "Private Key");
|
||||
break;
|
||||
|
||||
case KEY_PUBKEY:
|
||||
pkey = load_pubkey(bio_err, keyfile, cfg.keyform, 0,
|
||||
NULL, "Public Key");
|
||||
break;
|
||||
|
||||
case KEY_CERT:
|
||||
x = load_cert(bio_err, keyfile, cfg.keyform,
|
||||
NULL, "Certificate");
|
||||
if (x) {
|
||||
pkey = X509_get_pubkey(x);
|
||||
X509_free(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cfg.keysize = EVP_PKEY_size(pkey);
|
||||
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
cfg.ctx = EVP_PKEY_CTX_new(pkey, NULL);
|
||||
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
if (!cfg.ctx)
|
||||
goto end;
|
||||
|
||||
switch (cfg.pkey_op) {
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign_init(cfg.ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFY:
|
||||
rv = EVP_PKEY_verify_init(cfg.ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover_init(cfg.ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt_init(cfg.ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt_init(cfg.ctx);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive_init(cfg.ctx);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv <= 0) {
|
||||
EVP_PKEY_CTX_free(cfg.ctx);
|
||||
cfg.ctx = NULL;
|
||||
}
|
||||
|
||||
end:
|
||||
free(passin);
|
||||
|
||||
if (!cfg.ctx) {
|
||||
BIO_puts(bio_err, "Error initializing context\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
setup_peer(char *file)
|
||||
{
|
||||
EVP_PKEY *peer = NULL;
|
||||
int ret;
|
||||
|
||||
if (!cfg.ctx) {
|
||||
BIO_puts(bio_err, "-peerkey command before -inkey\n");
|
||||
return (1);
|
||||
}
|
||||
peer = load_pubkey(bio_err, file, cfg.peerform, 0, NULL,
|
||||
"Peer Key");
|
||||
|
||||
if (!peer) {
|
||||
BIO_printf(bio_err, "Error reading peer key %s\n", file);
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
ret = EVP_PKEY_derive_set_peer(cfg.ctx, peer);
|
||||
|
||||
EVP_PKEY_free(peer);
|
||||
if (ret <= 0) {
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pkeyutl_pkeyopt(char *pkeyopt)
|
||||
{
|
||||
if (!cfg.ctx) {
|
||||
BIO_puts(bio_err, "-pkeyopt command before -inkey\n");
|
||||
return (1);
|
||||
} else if (pkey_ctrl_string(cfg.ctx, pkeyopt) <= 0) {
|
||||
BIO_puts(bio_err, "parameter setting error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
do_keyop(EVP_PKEY_CTX * ctx, int pkey_op,
|
||||
unsigned char *out, size_t * poutlen,
|
||||
unsigned char *in, size_t inlen)
|
||||
{
|
||||
int rv = 0;
|
||||
switch (pkey_op) {
|
||||
case EVP_PKEY_OP_VERIFYRECOVER:
|
||||
rv = EVP_PKEY_verify_recover(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_SIGN:
|
||||
rv = EVP_PKEY_sign(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_ENCRYPT:
|
||||
rv = EVP_PKEY_encrypt(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DECRYPT:
|
||||
rv = EVP_PKEY_decrypt(ctx, out, poutlen, in, inlen);
|
||||
break;
|
||||
|
||||
case EVP_PKEY_OP_DERIVE:
|
||||
rv = EVP_PKEY_derive(ctx, out, poutlen);
|
||||
break;
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@@ -1,201 +0,0 @@
|
||||
/* $OpenBSD: prime.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2004 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
static struct {
|
||||
int bits;
|
||||
int checks;
|
||||
int generate;
|
||||
int hex;
|
||||
int safe;
|
||||
} cfg;
|
||||
|
||||
static const struct option prime_options[] = {
|
||||
{
|
||||
.name = "bits",
|
||||
.argname = "n",
|
||||
.desc = "Number of bits in the generated prime number",
|
||||
.type = OPTION_ARG_INT,
|
||||
.opt.value = &cfg.bits,
|
||||
},
|
||||
{
|
||||
.name = "checks",
|
||||
.argname = "n",
|
||||
.desc = "Miller-Rabin probabilistic primality test iterations",
|
||||
.type = OPTION_ARG_INT,
|
||||
.opt.value = &cfg.checks,
|
||||
},
|
||||
{
|
||||
.name = "generate",
|
||||
.desc = "Generate a pseudo-random prime number",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.generate,
|
||||
},
|
||||
{
|
||||
.name = "hex",
|
||||
.desc = "Hexadecimal prime numbers",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.hex,
|
||||
},
|
||||
{
|
||||
.name = "safe",
|
||||
.desc = "Generate only \"safe\" prime numbers",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.safe,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
prime_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: prime [-bits n] [-checks n] [-generate] [-hex] [-safe] "
|
||||
"p\n");
|
||||
options_usage(prime_options);
|
||||
}
|
||||
|
||||
int
|
||||
prime_main(int argc, char **argv)
|
||||
{
|
||||
BIGNUM *bn = NULL;
|
||||
char *prime = NULL;
|
||||
BIO *bio_out;
|
||||
char *s;
|
||||
int is_prime, ret = 1;
|
||||
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
/* Default iterations for Miller-Rabin probabilistic primality test. */
|
||||
cfg.checks = 20;
|
||||
|
||||
if (options_parse(argc, argv, prime_options, &prime, NULL) != 0) {
|
||||
prime_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (prime == NULL && cfg.generate == 0) {
|
||||
BIO_printf(bio_err, "No prime specified.\n");
|
||||
prime_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if ((bio_out = BIO_new(BIO_s_file())) == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
return (1);
|
||||
}
|
||||
BIO_set_fp(bio_out, stdout, BIO_NOCLOSE);
|
||||
|
||||
if (cfg.generate != 0) {
|
||||
if (cfg.bits == 0) {
|
||||
BIO_printf(bio_err, "Specify the number of bits.\n");
|
||||
goto end;
|
||||
}
|
||||
bn = BN_new();
|
||||
if (!bn) {
|
||||
BIO_printf(bio_err, "Out of memory.\n");
|
||||
goto end;
|
||||
}
|
||||
if (!BN_generate_prime_ex(bn, cfg.bits,
|
||||
cfg.safe, NULL, NULL, NULL)) {
|
||||
BIO_printf(bio_err, "Prime generation error.\n");
|
||||
goto end;
|
||||
}
|
||||
s = cfg.hex ? BN_bn2hex(bn) : BN_bn2dec(bn);
|
||||
if (s == NULL) {
|
||||
BIO_printf(bio_err, "Out of memory.\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_out, "%s\n", s);
|
||||
free(s);
|
||||
} else {
|
||||
if (cfg.hex) {
|
||||
if (!BN_hex2bn(&bn, prime)) {
|
||||
BIO_printf(bio_err, "%s is an invalid hex "
|
||||
"value.\n", prime);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (!BN_dec2bn(&bn, prime)) {
|
||||
BIO_printf(bio_err, "%s is an invalid decimal "
|
||||
"value.\n", prime);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
is_prime = BN_is_prime_ex(bn, cfg.checks, NULL, NULL);
|
||||
if (is_prime < 0) {
|
||||
BIO_printf(bio_err, "BN_is_prime_ex failed.\n");
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_out, "%s is %sprime\n", prime,
|
||||
is_prime == 1 ? "" : "not ");
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BN_free(bn);
|
||||
BIO_free_all(bio_out);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/* $OpenBSD: progs.h,v 1.9 2019/11/04 15:25:54 jsing Exp $ */
|
||||
/* Public domain */
|
||||
|
||||
int asn1parse_main(int argc, char **argv);
|
||||
int ca_main(int argc, char **argv);
|
||||
int certhash_main(int argc, char **argv);
|
||||
int ciphers_main(int argc, char **argv);
|
||||
int cms_main(int argc, char **argv);
|
||||
int crl2pkcs7_main(int argc, char **argv);
|
||||
int crl_main(int argc, char **argv);
|
||||
int dgst_main(int argc, char **argv);
|
||||
int dh_main(int argc, char **argv);
|
||||
int dhparam_main(int argc, char **argv);
|
||||
int dsa_main(int argc, char **argv);
|
||||
int dsaparam_main(int argc, char **argv);
|
||||
int ec_main(int argc, char **argv);
|
||||
int ecparam_main(int argc, char **argv);
|
||||
int enc_main(int argc, char **argv);
|
||||
int errstr_main(int argc, char **argv);
|
||||
int gendh_main(int argc, char **argv);
|
||||
int gendsa_main(int argc, char **argv);
|
||||
int genpkey_main(int argc, char **argv);
|
||||
int genrsa_main(int argc, char **argv);
|
||||
int nseq_main(int argc, char **argv);
|
||||
int ocsp_main(int argc, char **argv);
|
||||
int passwd_main(int argc, char **argv);
|
||||
int pkcs7_main(int argc, char **argv);
|
||||
int pkcs8_main(int argc, char **argv);
|
||||
int pkcs12_main(int argc, char **argv);
|
||||
int pkey_main(int argc, char **argv);
|
||||
int pkeyparam_main(int argc, char **argv);
|
||||
int pkeyutl_main(int argc, char **argv);
|
||||
int prime_main(int argc, char **argv);
|
||||
int rand_main(int argc, char **argv);
|
||||
int req_main(int argc, char **argv);
|
||||
int rsa_main(int argc, char **argv);
|
||||
int rsautl_main(int argc, char **argv);
|
||||
int s_client_main(int argc, char **argv);
|
||||
int s_server_main(int argc, char **argv);
|
||||
int s_time_main(int argc, char **argv);
|
||||
int sess_id_main(int argc, char **argv);
|
||||
int smime_main(int argc, char **argv);
|
||||
int speed_main(int argc, char **argv);
|
||||
int spkac_main(int argc, char **argv);
|
||||
int ts_main(int argc, char **argv);
|
||||
int verify_main(int argc, char **argv);
|
||||
int version_main(int argc, char **argv);
|
||||
int x509_main(int argc, char **argv);
|
||||
@@ -1,182 +0,0 @@
|
||||
/* $OpenBSD: rand.c,v 1.18 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
static struct {
|
||||
int base64;
|
||||
int hex;
|
||||
char *outfile;
|
||||
} cfg;
|
||||
|
||||
static const struct option rand_options[] = {
|
||||
{
|
||||
.name = "base64",
|
||||
.desc = "Perform base64 encoding on output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.base64,
|
||||
},
|
||||
{
|
||||
.name = "hex",
|
||||
.desc = "Hexadecimal output",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.hex,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Write to the given file instead of standard output",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
rand_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: rand [-base64 | -hex] [-out file] num\n");
|
||||
options_usage(rand_options);
|
||||
}
|
||||
|
||||
int
|
||||
rand_main(int argc, char **argv)
|
||||
{
|
||||
char *num_bytes = NULL;
|
||||
int ret = 1;
|
||||
int badopt = 0;
|
||||
int num = -1;
|
||||
int i, r;
|
||||
BIO *out = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, rand_options, &num_bytes, NULL) != 0) {
|
||||
rand_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (num_bytes != NULL) {
|
||||
r = sscanf(num_bytes, "%d", &num);
|
||||
if (r == 0 || num < 0)
|
||||
badopt = 1;
|
||||
} else
|
||||
badopt = 1;
|
||||
|
||||
if (cfg.hex && cfg.base64)
|
||||
badopt = 1;
|
||||
|
||||
if (badopt) {
|
||||
rand_usage();
|
||||
goto err;
|
||||
}
|
||||
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL)
|
||||
goto err;
|
||||
if (cfg.outfile != NULL)
|
||||
r = BIO_write_filename(out, cfg.outfile);
|
||||
else
|
||||
r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
|
||||
if (r <= 0)
|
||||
goto err;
|
||||
if (cfg.base64) {
|
||||
BIO *b64 = BIO_new(BIO_f_base64());
|
||||
if (b64 == NULL)
|
||||
goto err;
|
||||
out = BIO_push(b64, out);
|
||||
}
|
||||
|
||||
while (num > 0) {
|
||||
unsigned char buf[4096];
|
||||
int chunk;
|
||||
|
||||
chunk = num;
|
||||
if (chunk > (int) sizeof(buf))
|
||||
chunk = sizeof(buf);
|
||||
arc4random_buf(buf, chunk);
|
||||
if (cfg.hex) {
|
||||
for (i = 0; i < chunk; i++)
|
||||
BIO_printf(out, "%02x", buf[i]);
|
||||
} else
|
||||
BIO_write(out, buf, chunk);
|
||||
num -= chunk;
|
||||
}
|
||||
|
||||
if (cfg.hex)
|
||||
BIO_puts(out, "\n");
|
||||
(void) BIO_flush(out);
|
||||
|
||||
ret = 0;
|
||||
|
||||
err:
|
||||
ERR_print_errors(bio_err);
|
||||
BIO_free_all(out);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
1878
apps/openssl/req.c
1878
apps/openssl/req.c
File diff suppressed because it is too large
Load Diff
@@ -1,411 +0,0 @@
|
||||
/* $OpenBSD: rsa.c,v 1.19 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
int check;
|
||||
const EVP_CIPHER *enc;
|
||||
char *infile;
|
||||
int informat;
|
||||
int modulus;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
char *passargin;
|
||||
char *passargout;
|
||||
int pubin;
|
||||
int pubout;
|
||||
int pvk_encr;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
rsa_opt_cipher(int argc, char **argv, int *argsused)
|
||||
{
|
||||
char *name = argv[0];
|
||||
|
||||
if (*name++ != '-')
|
||||
return (1);
|
||||
|
||||
if ((cfg.enc = EVP_get_cipherbyname(name)) == NULL) {
|
||||
fprintf(stderr, "Invalid cipher '%s'\n", name);
|
||||
return (1);
|
||||
}
|
||||
|
||||
*argsused = 1;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option rsa_options[] = {
|
||||
{
|
||||
.name = "check",
|
||||
.desc = "Check consistency of RSA private key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.check,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER, NET or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "modulus",
|
||||
.desc = "Print the RSA key modulus",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.modulus,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not print encoded version of the key",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER, NET or PEM (default PEM))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "src",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "passout",
|
||||
.argname = "src",
|
||||
.desc = "Output file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargout,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Expect a public key (default private key)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pubin,
|
||||
},
|
||||
{
|
||||
.name = "pubout",
|
||||
.desc = "Output a public key (default private key)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pubout,
|
||||
},
|
||||
{
|
||||
.name = "pvk-none",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 0,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "pvk-strong",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 2,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "pvk-weak",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 1,
|
||||
.opt.value = &cfg.pvk_encr,
|
||||
},
|
||||
{
|
||||
.name = "RSAPublicKey_in",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 2,
|
||||
.opt.value = &cfg.pubin,
|
||||
},
|
||||
{
|
||||
.name = "RSAPublicKey_out",
|
||||
.type = OPTION_VALUE,
|
||||
.value = 2,
|
||||
.opt.value = &cfg.pubout,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print in plain text in addition to encoded",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = rsa_opt_cipher,
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
rsa_usage(void)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: rsa [-ciphername] [-check] [-in file] "
|
||||
"[-inform fmt]\n"
|
||||
" [-modulus] [-noout] [-out file] [-outform fmt] "
|
||||
"[-passin src]\n"
|
||||
" [-passout src] [-pubin] [-pubout] [-text]\n\n");
|
||||
options_usage(rsa_options);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
fprintf(stderr, "Valid ciphername values:\n\n");
|
||||
OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, show_cipher, &n);
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
rsa_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
RSA *rsa = NULL;
|
||||
int i;
|
||||
BIO *out = NULL;
|
||||
char *passin = NULL, *passout = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.pvk_encr = 2;
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, rsa_options, NULL, NULL) != 0) {
|
||||
rsa_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin, cfg.passargout,
|
||||
&passin, &passout)) {
|
||||
BIO_printf(bio_err, "Error getting passwords\n");
|
||||
goto end;
|
||||
}
|
||||
if (cfg.check && cfg.pubin) {
|
||||
BIO_printf(bio_err, "Only private keys can be checked\n");
|
||||
goto end;
|
||||
}
|
||||
out = BIO_new(BIO_s_file());
|
||||
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
|
||||
if (cfg.pubin) {
|
||||
int tmpformat = -1;
|
||||
if (cfg.pubin == 2) {
|
||||
if (cfg.informat == FORMAT_PEM)
|
||||
tmpformat = FORMAT_PEMRSA;
|
||||
else if (cfg.informat == FORMAT_ASN1)
|
||||
tmpformat = FORMAT_ASN1RSA;
|
||||
} else
|
||||
tmpformat = cfg.informat;
|
||||
|
||||
pkey = load_pubkey(bio_err, cfg.infile,
|
||||
tmpformat, 1, passin, "Public Key");
|
||||
} else
|
||||
pkey = load_key(bio_err, cfg.infile,
|
||||
cfg.informat, 1, passin, "Private Key");
|
||||
|
||||
if (pkey != NULL)
|
||||
rsa = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
|
||||
if (rsa == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile) <= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (cfg.text)
|
||||
if (!RSA_print(out, rsa, 0)) {
|
||||
perror(cfg.outfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.modulus) {
|
||||
BIO_printf(out, "Modulus=");
|
||||
BN_print(out, RSA_get0_n(rsa));
|
||||
BIO_printf(out, "\n");
|
||||
}
|
||||
if (cfg.check) {
|
||||
int r = RSA_check_key(rsa);
|
||||
|
||||
if (r == 1)
|
||||
BIO_printf(out, "RSA key ok\n");
|
||||
else if (r == 0) {
|
||||
unsigned long err;
|
||||
|
||||
while ((err = ERR_peek_error()) != 0 &&
|
||||
ERR_GET_LIB(err) == ERR_LIB_RSA &&
|
||||
ERR_GET_FUNC(err) == RSA_F_RSA_CHECK_KEY &&
|
||||
ERR_GET_REASON(err) != ERR_R_MALLOC_FAILURE) {
|
||||
BIO_printf(out, "RSA key error: %s\n",
|
||||
ERR_reason_error_string(err));
|
||||
ERR_get_error(); /* remove e from error
|
||||
* stack */
|
||||
}
|
||||
}
|
||||
if (r == -1 || ERR_peek_error() != 0) { /* should happen only if
|
||||
* r == -1 */
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.noout) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bio_err, "writing RSA key\n");
|
||||
if (cfg.outformat == FORMAT_ASN1) {
|
||||
if (cfg.pubout || cfg.pubin) {
|
||||
if (cfg.pubout == 2)
|
||||
i = i2d_RSAPublicKey_bio(out, rsa);
|
||||
else
|
||||
i = i2d_RSA_PUBKEY_bio(out, rsa);
|
||||
} else
|
||||
i = i2d_RSAPrivateKey_bio(out, rsa);
|
||||
} else if (cfg.outformat == FORMAT_PEM) {
|
||||
if (cfg.pubout || cfg.pubin) {
|
||||
if (cfg.pubout == 2)
|
||||
i = PEM_write_bio_RSAPublicKey(out, rsa);
|
||||
else
|
||||
i = PEM_write_bio_RSA_PUBKEY(out, rsa);
|
||||
} else
|
||||
i = PEM_write_bio_RSAPrivateKey(out, rsa,
|
||||
cfg.enc, NULL, 0, NULL, passout);
|
||||
#if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_RC4)
|
||||
} else if (cfg.outformat == FORMAT_MSBLOB ||
|
||||
cfg.outformat == FORMAT_PVK) {
|
||||
EVP_PKEY *pk;
|
||||
pk = EVP_PKEY_new();
|
||||
EVP_PKEY_set1_RSA(pk, rsa);
|
||||
if (cfg.outformat == FORMAT_PVK)
|
||||
i = i2b_PVK_bio(out, pk, cfg.pvk_encr, 0,
|
||||
passout);
|
||||
else if (cfg.pubin || cfg.pubout)
|
||||
i = i2b_PublicKey_bio(out, pk);
|
||||
else
|
||||
i = i2b_PrivateKey_bio(out, pk);
|
||||
EVP_PKEY_free(pk);
|
||||
#endif
|
||||
} else {
|
||||
BIO_printf(bio_err,
|
||||
"bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (i <= 0) {
|
||||
BIO_printf(bio_err, "unable to write key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
} else
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free_all(out);
|
||||
RSA_free(rsa);
|
||||
free(passin);
|
||||
free(passout);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
/* $OpenBSD: rsautl.c,v 1.24 2023/07/23 11:39:29 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#define RSA_SIGN 1
|
||||
#define RSA_VERIFY 2
|
||||
#define RSA_ENCRYPT 3
|
||||
#define RSA_DECRYPT 4
|
||||
|
||||
#define KEY_PRIVKEY 1
|
||||
#define KEY_PUBKEY 2
|
||||
#define KEY_CERT 3
|
||||
|
||||
static struct {
|
||||
int asn1parse;
|
||||
int hexdump;
|
||||
char *infile;
|
||||
char *keyfile;
|
||||
int keyform;
|
||||
int key_type;
|
||||
char *outfile;
|
||||
int pad;
|
||||
char *passargin;
|
||||
int rev;
|
||||
int rsa_mode;
|
||||
} cfg;
|
||||
|
||||
static const struct option rsautl_options[] = {
|
||||
{
|
||||
.name = "asn1parse",
|
||||
.desc = "ASN.1 parse the output data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.asn1parse,
|
||||
},
|
||||
{
|
||||
.name = "certin",
|
||||
.desc = "Input is a certificate containing an RSA public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = KEY_CERT,
|
||||
.opt.value = &cfg.key_type,
|
||||
},
|
||||
{
|
||||
.name = "decrypt",
|
||||
.desc = "Decrypt the input data using RSA private key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_DECRYPT,
|
||||
.opt.value = &cfg.rsa_mode,
|
||||
},
|
||||
{
|
||||
.name = "encrypt",
|
||||
.desc = "Encrypt the input data using RSA public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_ENCRYPT,
|
||||
.opt.value = &cfg.rsa_mode,
|
||||
},
|
||||
{
|
||||
.name = "hexdump",
|
||||
.desc = "Hex dump the output data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.hexdump,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inkey",
|
||||
.argname = "file",
|
||||
.desc = "Input key file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keyfile,
|
||||
},
|
||||
{
|
||||
.name = "keyform",
|
||||
.argname = "fmt",
|
||||
.desc = "Input key format (DER, TXT or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.keyform,
|
||||
},
|
||||
{
|
||||
.name = "oaep",
|
||||
.desc = "Use PKCS#1 OAEP padding",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_PKCS1_OAEP_PADDING,
|
||||
.opt.value = &cfg.pad,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "arg",
|
||||
.desc = "Key password source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "pkcs",
|
||||
.desc = "Use PKCS#1 v1.5 padding (default)",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_PKCS1_PADDING,
|
||||
.opt.value = &cfg.pad,
|
||||
},
|
||||
{
|
||||
.name = "pubin",
|
||||
.desc = "Input is an RSA public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = KEY_PUBKEY,
|
||||
.opt.value = &cfg.key_type,
|
||||
},
|
||||
{
|
||||
.name = "raw",
|
||||
.desc = "Use no padding",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_NO_PADDING,
|
||||
.opt.value = &cfg.pad,
|
||||
},
|
||||
{
|
||||
.name = "rev",
|
||||
.desc = "Reverse the input data",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.rev,
|
||||
},
|
||||
{
|
||||
.name = "sign",
|
||||
.desc = "Sign the input data using RSA private key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_SIGN,
|
||||
.opt.value = &cfg.rsa_mode,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.desc = "Verify the input data using RSA public key",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_VERIFY,
|
||||
.opt.value = &cfg.rsa_mode,
|
||||
},
|
||||
{
|
||||
.name = "x931",
|
||||
.desc = "Use ANSI X9.31 padding",
|
||||
.type = OPTION_VALUE,
|
||||
.value = RSA_X931_PADDING,
|
||||
.opt.value = &cfg.pad,
|
||||
},
|
||||
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
rsautl_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: rsautl [-asn1parse] [-certin] [-decrypt] [-encrypt] "
|
||||
"[-hexdump]\n"
|
||||
" [-in file] [-inkey file] [-keyform der | pem]\n"
|
||||
" [-oaep | -pkcs | -raw | -x931] [-out file] [-passin arg]\n"
|
||||
" [-pubin] [-rev] [-sign] [-verify]\n\n");
|
||||
|
||||
options_usage(rsautl_options);
|
||||
}
|
||||
|
||||
int
|
||||
rsautl_main(int argc, char **argv)
|
||||
{
|
||||
BIO *in = NULL, *out = NULL;
|
||||
X509 *x;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
RSA *rsa = NULL;
|
||||
unsigned char *rsa_in = NULL, *rsa_out = NULL;
|
||||
char *passin = NULL;
|
||||
int rsa_inlen, rsa_outlen = 0;
|
||||
int need_priv = 0;
|
||||
int keysize;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.keyform = FORMAT_PEM;
|
||||
cfg.key_type = KEY_PRIVKEY;
|
||||
cfg.pad = RSA_PKCS1_PADDING;
|
||||
cfg.rsa_mode = RSA_VERIFY;
|
||||
|
||||
if (options_parse(argc, argv, rsautl_options, NULL, NULL) != 0) {
|
||||
rsautl_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (cfg.rsa_mode == RSA_SIGN ||
|
||||
cfg.rsa_mode == RSA_DECRYPT)
|
||||
need_priv = 1;
|
||||
|
||||
if (need_priv && cfg.key_type != KEY_PRIVKEY) {
|
||||
BIO_printf(bio_err, "A private key is needed for this operation\n");
|
||||
goto end;
|
||||
}
|
||||
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
switch (cfg.key_type) {
|
||||
case KEY_PRIVKEY:
|
||||
pkey = load_key(bio_err, cfg.keyfile,
|
||||
cfg.keyform, 0, passin, "Private Key");
|
||||
break;
|
||||
|
||||
case KEY_PUBKEY:
|
||||
pkey = load_pubkey(bio_err, cfg.keyfile,
|
||||
cfg.keyform, 0, NULL, "Public Key");
|
||||
break;
|
||||
|
||||
case KEY_CERT:
|
||||
x = load_cert(bio_err, cfg.keyfile,
|
||||
cfg.keyform, NULL, "Certificate");
|
||||
if (x) {
|
||||
pkey = X509_get_pubkey(x);
|
||||
X509_free(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!pkey)
|
||||
goto end;
|
||||
|
||||
rsa = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
|
||||
if (!rsa) {
|
||||
BIO_printf(bio_err, "Error getting RSA key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile) {
|
||||
if (!(in = BIO_new_file(cfg.infile, "rb"))) {
|
||||
BIO_printf(bio_err, "Error Reading Input File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
|
||||
if (cfg.outfile) {
|
||||
if (!(out = BIO_new_file(cfg.outfile, "wb"))) {
|
||||
BIO_printf(bio_err, "Error Reading Output File\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
keysize = RSA_size(rsa);
|
||||
|
||||
rsa_in = reallocarray(NULL, keysize, 2);
|
||||
if (rsa_in == NULL) {
|
||||
BIO_printf(bio_err, "Error allocating memory for input data\n");
|
||||
exit(1);
|
||||
}
|
||||
rsa_out = malloc(keysize);
|
||||
if (rsa_out == NULL) {
|
||||
BIO_printf(bio_err, "Error allocating memory for output data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Read the input data */
|
||||
rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
|
||||
if (rsa_inlen <= 0) {
|
||||
BIO_printf(bio_err, "Error reading input Data\n");
|
||||
exit(1);
|
||||
}
|
||||
if (cfg.rev) {
|
||||
int i;
|
||||
unsigned char ctmp;
|
||||
for (i = 0; i < rsa_inlen / 2; i++) {
|
||||
ctmp = rsa_in[i];
|
||||
rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
|
||||
rsa_in[rsa_inlen - 1 - i] = ctmp;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cfg.rsa_mode) {
|
||||
case RSA_VERIFY:
|
||||
rsa_outlen = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out,
|
||||
rsa, cfg.pad);
|
||||
break;
|
||||
|
||||
case RSA_SIGN:
|
||||
rsa_outlen = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out,
|
||||
rsa, cfg.pad);
|
||||
break;
|
||||
|
||||
case RSA_ENCRYPT:
|
||||
rsa_outlen = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out,
|
||||
rsa, cfg.pad);
|
||||
break;
|
||||
|
||||
case RSA_DECRYPT:
|
||||
rsa_outlen = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out,
|
||||
rsa, cfg.pad);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rsa_outlen <= 0) {
|
||||
BIO_printf(bio_err, "RSA operation error\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
if (cfg.asn1parse) {
|
||||
if (!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
|
||||
ERR_print_errors(bio_err);
|
||||
}
|
||||
} else if (cfg.hexdump)
|
||||
BIO_dump(out, (char *) rsa_out, rsa_outlen);
|
||||
else
|
||||
BIO_write(out, rsa_out, rsa_outlen);
|
||||
|
||||
end:
|
||||
RSA_free(rsa);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
free(rsa_in);
|
||||
free(rsa_out);
|
||||
free(passin);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
/* $OpenBSD: s_apps.h,v 1.7 2021/12/06 11:06:58 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#define PORT 4433
|
||||
#define PORT_STR "4433"
|
||||
#define PROTOCOL "tcp"
|
||||
|
||||
extern int verify_depth;
|
||||
extern int verify_return_error;
|
||||
|
||||
int do_server(int port, int type, int *ret,
|
||||
int (*cb)(int s, unsigned char *context),
|
||||
unsigned char *context, int naccept);
|
||||
#ifdef HEADER_X509_H
|
||||
int verify_callback(int ok, X509_STORE_CTX *ctx);
|
||||
#endif
|
||||
#ifdef HEADER_SSL_H
|
||||
int set_cert_stuff(SSL_CTX *ctx, char *cert_file, char *key_file);
|
||||
int set_cert_key_stuff(SSL_CTX *ctx, X509 *cert, EVP_PKEY *key);
|
||||
#endif
|
||||
int ssl_print_tmp_key(BIO *out, SSL *s);
|
||||
int init_client(int *sock, char *server, char *port, int type, int af);
|
||||
int should_retry(int i);
|
||||
int extract_port(char *str, short *port_ptr);
|
||||
int extract_host_port(char *str, char **host_ptr, unsigned char *ip, char **p);
|
||||
|
||||
long bio_dump_callback(BIO *bio, int cmd, const char *argp, int argi,
|
||||
long argl, long ret);
|
||||
|
||||
#ifdef HEADER_SSL_H
|
||||
void apps_ssl_info_callback(const SSL *s, int where, int ret);
|
||||
void msg_cb(int write_p, int version, int content_type, const void *buf,
|
||||
size_t len, SSL *ssl, void *arg);
|
||||
void tlsext_cb(SSL *s, int client_server, int type, unsigned char *data,
|
||||
int len, void *arg);
|
||||
#endif
|
||||
|
||||
int generate_cookie_callback(SSL *ssl, unsigned char *cookie,
|
||||
unsigned int *cookie_len);
|
||||
int verify_cookie_callback(SSL *ssl, const unsigned char *cookie,
|
||||
unsigned int cookie_len);
|
||||
@@ -1,932 +0,0 @@
|
||||
/* $OpenBSD: s_cb.c,v 1.21 2023/04/14 15:27:13 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "s_apps.h"
|
||||
|
||||
#define COOKIE_SECRET_LENGTH 16
|
||||
|
||||
int verify_depth = 0;
|
||||
int verify_return_error = 0;
|
||||
unsigned char cookie_secret[COOKIE_SECRET_LENGTH];
|
||||
int cookie_initialized = 0;
|
||||
|
||||
int
|
||||
verify_callback(int ok, X509_STORE_CTX * ctx)
|
||||
{
|
||||
X509 *err_cert;
|
||||
int err, depth;
|
||||
|
||||
err_cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
err = X509_STORE_CTX_get_error(ctx);
|
||||
depth = X509_STORE_CTX_get_error_depth(ctx);
|
||||
|
||||
BIO_printf(bio_err, "depth=%d ", depth);
|
||||
if (err_cert) {
|
||||
X509_NAME_print_ex(bio_err, X509_get_subject_name(err_cert),
|
||||
0, XN_FLAG_ONELINE);
|
||||
BIO_puts(bio_err, "\n");
|
||||
} else
|
||||
BIO_puts(bio_err, "<no cert>\n");
|
||||
if (!ok) {
|
||||
BIO_printf(bio_err, "verify error:num=%d:%s\n", err,
|
||||
X509_verify_cert_error_string(err));
|
||||
if (verify_depth >= depth) {
|
||||
if (!verify_return_error)
|
||||
ok = 1;
|
||||
} else {
|
||||
ok = 0;
|
||||
}
|
||||
}
|
||||
switch (err) {
|
||||
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
|
||||
BIO_puts(bio_err, "issuer= ");
|
||||
if (err_cert == NULL)
|
||||
BIO_puts(bio_err, "<error getting cert>");
|
||||
else
|
||||
X509_NAME_print_ex(bio_err,
|
||||
X509_get_issuer_name(err_cert), 0, XN_FLAG_ONELINE);
|
||||
BIO_puts(bio_err, "\n");
|
||||
break;
|
||||
case X509_V_ERR_CERT_NOT_YET_VALID:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
|
||||
BIO_printf(bio_err, "notBefore=");
|
||||
if (err_cert == NULL)
|
||||
BIO_printf(bio_err, " <error getting cert>");
|
||||
else
|
||||
ASN1_TIME_print(bio_err, X509_get_notBefore(err_cert));
|
||||
BIO_printf(bio_err, "\n");
|
||||
break;
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
|
||||
BIO_printf(bio_err, "notAfter=");
|
||||
if (err_cert == NULL)
|
||||
BIO_printf(bio_err, " <error getting cert>");
|
||||
else
|
||||
ASN1_TIME_print(bio_err, X509_get_notAfter(err_cert));
|
||||
BIO_printf(bio_err, "\n");
|
||||
break;
|
||||
case X509_V_ERR_NO_EXPLICIT_POLICY:
|
||||
break;
|
||||
}
|
||||
|
||||
BIO_printf(bio_err, "verify return:%d\n", ok);
|
||||
return (ok);
|
||||
}
|
||||
|
||||
int
|
||||
set_cert_stuff(SSL_CTX * ctx, char *cert_file, char *key_file)
|
||||
{
|
||||
if (cert_file == NULL)
|
||||
return 1;
|
||||
|
||||
if (key_file == NULL)
|
||||
key_file = cert_file;
|
||||
|
||||
if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) {
|
||||
BIO_printf(bio_err,
|
||||
"unable to get certificate from '%s'\n", cert_file);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0) {
|
||||
BIO_printf(bio_err, "unable to get private key from '%s'\n",
|
||||
key_file);
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now we know that a key and cert have been set against the context. */
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
BIO_printf(bio_err,
|
||||
"Private key does not match the certificate public key\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
set_cert_key_stuff(SSL_CTX * ctx, X509 * cert, EVP_PKEY * key)
|
||||
{
|
||||
if (cert == NULL)
|
||||
return 1;
|
||||
if (SSL_CTX_use_certificate(ctx, cert) <= 0) {
|
||||
BIO_printf(bio_err, "error setting certificate\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
if (SSL_CTX_use_PrivateKey(ctx, key) <= 0) {
|
||||
BIO_printf(bio_err, "error setting private key\n");
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Now we know that a key and cert have been set against the SSL
|
||||
* context
|
||||
*/
|
||||
if (!SSL_CTX_check_private_key(ctx)) {
|
||||
BIO_printf(bio_err,
|
||||
"Private key does not match the certificate public key\n");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
ssl_print_tmp_key(BIO *out, SSL *s)
|
||||
{
|
||||
const char *cname;
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *ec;
|
||||
const EC_GROUP *group;
|
||||
int nid;
|
||||
|
||||
if (!SSL_get_server_tmp_key(s, &pkey))
|
||||
return 0;
|
||||
|
||||
BIO_puts(out, "Server Temp Key: ");
|
||||
switch (EVP_PKEY_id(pkey)) {
|
||||
case EVP_PKEY_DH:
|
||||
BIO_printf(out, "DH, %d bits\n", EVP_PKEY_bits(pkey));
|
||||
break;
|
||||
|
||||
case EVP_PKEY_EC:
|
||||
if ((ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL)
|
||||
goto err;
|
||||
if ((group = EC_KEY_get0_group(ec)) == NULL)
|
||||
goto err;
|
||||
|
||||
nid = EC_GROUP_get_curve_name(group);
|
||||
|
||||
if ((cname = EC_curve_nid2nist(nid)) == NULL)
|
||||
cname = OBJ_nid2sn(nid);
|
||||
|
||||
BIO_printf(out, "ECDH, %s, %d bits\n", cname, EVP_PKEY_bits(pkey));
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_printf(out, "%s, %d bits\n", OBJ_nid2sn(EVP_PKEY_id(pkey)),
|
||||
EVP_PKEY_bits(pkey));
|
||||
}
|
||||
|
||||
err:
|
||||
EVP_PKEY_free(pkey);
|
||||
return 1;
|
||||
}
|
||||
|
||||
long
|
||||
bio_dump_callback(BIO * bio, int cmd, const char *argp,
|
||||
int argi, long argl, long ret)
|
||||
{
|
||||
BIO *out;
|
||||
|
||||
out = (BIO *) BIO_get_callback_arg(bio);
|
||||
if (out == NULL)
|
||||
return (ret);
|
||||
|
||||
if (cmd == (BIO_CB_READ | BIO_CB_RETURN)) {
|
||||
BIO_printf(out,
|
||||
"read from %p [%p] (%lu bytes => %ld (0x%lX))\n",
|
||||
(void *) bio, argp, (unsigned long) argi, ret, ret);
|
||||
BIO_dump(out, argp, (int) ret);
|
||||
return (ret);
|
||||
} else if (cmd == (BIO_CB_WRITE | BIO_CB_RETURN)) {
|
||||
BIO_printf(out,
|
||||
"write to %p [%p] (%lu bytes => %ld (0x%lX))\n",
|
||||
(void *) bio, argp, (unsigned long) argi, ret, ret);
|
||||
BIO_dump(out, argp, (int) ret);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void
|
||||
apps_ssl_info_callback(const SSL * s, int where, int ret)
|
||||
{
|
||||
const char *str;
|
||||
int w;
|
||||
|
||||
w = where & ~SSL_ST_MASK;
|
||||
|
||||
if (w & SSL_ST_CONNECT)
|
||||
str = "SSL_connect";
|
||||
else if (w & SSL_ST_ACCEPT)
|
||||
str = "SSL_accept";
|
||||
else
|
||||
str = "undefined";
|
||||
|
||||
if (where & SSL_CB_LOOP) {
|
||||
BIO_printf(bio_err, "%s:%s\n", str, SSL_state_string_long(s));
|
||||
} else if (where & SSL_CB_ALERT) {
|
||||
str = (where & SSL_CB_READ) ? "read" : "write";
|
||||
BIO_printf(bio_err, "SSL3 alert %s:%s:%s\n", str,
|
||||
SSL_alert_type_string_long(ret),
|
||||
SSL_alert_desc_string_long(ret));
|
||||
} else if (where & SSL_CB_EXIT) {
|
||||
if (ret == 0)
|
||||
BIO_printf(bio_err, "%s:failed in %s\n",
|
||||
str, SSL_state_string_long(s));
|
||||
else if (ret < 0) {
|
||||
BIO_printf(bio_err, "%s:error in %s\n",
|
||||
str, SSL_state_string_long(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL * ssl, void *arg)
|
||||
{
|
||||
BIO *bio = arg;
|
||||
const char *str_write_p, *str_version, *str_content_type = "",
|
||||
*str_details1 = "", *str_details2 = "";
|
||||
|
||||
str_write_p = write_p ? ">>>" : "<<<";
|
||||
|
||||
/* XXX convert to using ssl_get_version */
|
||||
switch (version) {
|
||||
case SSL2_VERSION:
|
||||
str_version = "SSL 2.0";
|
||||
break;
|
||||
case SSL3_VERSION:
|
||||
str_version = "SSL 3.0 ";
|
||||
break;
|
||||
case TLS1_VERSION:
|
||||
str_version = "TLS 1.0 ";
|
||||
break;
|
||||
case TLS1_1_VERSION:
|
||||
str_version = "TLS 1.1 ";
|
||||
break;
|
||||
case TLS1_2_VERSION:
|
||||
str_version = "TLS 1.2 ";
|
||||
break;
|
||||
case TLS1_3_VERSION:
|
||||
str_version = "TLS 1.3 ";
|
||||
break;
|
||||
case DTLS1_VERSION:
|
||||
str_version = "DTLS 1.0 ";
|
||||
break;
|
||||
case DTLS1_2_VERSION:
|
||||
str_version = "DTLS 1.2 ";
|
||||
break;
|
||||
default:
|
||||
str_version = "???";
|
||||
}
|
||||
|
||||
if (version == SSL2_VERSION) {
|
||||
str_details1 = "???";
|
||||
|
||||
if (len > 0) {
|
||||
/* XXX magic numbers */
|
||||
switch (((const unsigned char *) buf)[0]) {
|
||||
case 0:
|
||||
str_details1 = ", ERROR:";
|
||||
str_details2 = " ???";
|
||||
if (len >= 3) {
|
||||
unsigned err = (((const unsigned char *) buf)[1] << 8) + ((const unsigned char *) buf)[2];
|
||||
|
||||
switch (err) {
|
||||
case 0x0001:
|
||||
str_details2 = " NO-CIPHER-ERROR";
|
||||
break;
|
||||
case 0x0002:
|
||||
str_details2 = " NO-CERTIFICATE-ERROR";
|
||||
break;
|
||||
case 0x0004:
|
||||
str_details2 = " BAD-CERTIFICATE-ERROR";
|
||||
break;
|
||||
case 0x0006:
|
||||
str_details2 = " UNSUPPORTED-CERTIFICATE-TYPE-ERROR";
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
str_details1 = ", CLIENT-HELLO";
|
||||
break;
|
||||
case 2:
|
||||
str_details1 = ", CLIENT-MASTER-KEY";
|
||||
break;
|
||||
case 3:
|
||||
str_details1 = ", CLIENT-FINISHED";
|
||||
break;
|
||||
case 4:
|
||||
str_details1 = ", SERVER-HELLO";
|
||||
break;
|
||||
case 5:
|
||||
str_details1 = ", SERVER-VERIFY";
|
||||
break;
|
||||
case 6:
|
||||
str_details1 = ", SERVER-FINISHED";
|
||||
break;
|
||||
case 7:
|
||||
str_details1 = ", REQUEST-CERTIFICATE";
|
||||
break;
|
||||
case 8:
|
||||
str_details1 = ", CLIENT-CERTIFICATE";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (version == SSL3_VERSION || version == TLS1_VERSION ||
|
||||
version == TLS1_1_VERSION || version == TLS1_2_VERSION ||
|
||||
version == TLS1_3_VERSION || version == DTLS1_VERSION ||
|
||||
version == DTLS1_2_VERSION) {
|
||||
/* XXX magic numbers are in ssl3.h */
|
||||
switch (content_type) {
|
||||
case 20:
|
||||
str_content_type = "ChangeCipherSpec";
|
||||
break;
|
||||
case 21:
|
||||
str_content_type = "Alert";
|
||||
break;
|
||||
case 22:
|
||||
str_content_type = "Handshake";
|
||||
break;
|
||||
}
|
||||
|
||||
if (content_type == 21) { /* Alert */
|
||||
str_details1 = ", ???";
|
||||
|
||||
if (len == 2) {
|
||||
switch (((const unsigned char *) buf)[0]) {
|
||||
case 1:
|
||||
str_details1 = ", warning";
|
||||
break;
|
||||
case 2:
|
||||
str_details1 = ", fatal";
|
||||
break;
|
||||
}
|
||||
|
||||
str_details2 = " ???";
|
||||
switch (((const unsigned char *) buf)[1]) {
|
||||
case 0:
|
||||
str_details2 = " close_notify";
|
||||
break;
|
||||
case 10:
|
||||
str_details2 = " unexpected_message";
|
||||
break;
|
||||
case 20:
|
||||
str_details2 = " bad_record_mac";
|
||||
break;
|
||||
case 21:
|
||||
str_details2 = " decryption_failed";
|
||||
break;
|
||||
case 22:
|
||||
str_details2 = " record_overflow";
|
||||
break;
|
||||
case 30:
|
||||
str_details2 = " decompression_failure";
|
||||
break;
|
||||
case 40:
|
||||
str_details2 = " handshake_failure";
|
||||
break;
|
||||
case 42:
|
||||
str_details2 = " bad_certificate";
|
||||
break;
|
||||
case 43:
|
||||
str_details2 = " unsupported_certificate";
|
||||
break;
|
||||
case 44:
|
||||
str_details2 = " certificate_revoked";
|
||||
break;
|
||||
case 45:
|
||||
str_details2 = " certificate_expired";
|
||||
break;
|
||||
case 46:
|
||||
str_details2 = " certificate_unknown";
|
||||
break;
|
||||
case 47:
|
||||
str_details2 = " illegal_parameter";
|
||||
break;
|
||||
case 48:
|
||||
str_details2 = " unknown_ca";
|
||||
break;
|
||||
case 49:
|
||||
str_details2 = " access_denied";
|
||||
break;
|
||||
case 50:
|
||||
str_details2 = " decode_error";
|
||||
break;
|
||||
case 51:
|
||||
str_details2 = " decrypt_error";
|
||||
break;
|
||||
case 60:
|
||||
str_details2 = " export_restriction";
|
||||
break;
|
||||
case 70:
|
||||
str_details2 = " protocol_version";
|
||||
break;
|
||||
case 71:
|
||||
str_details2 = " insufficient_security";
|
||||
break;
|
||||
case 80:
|
||||
str_details2 = " internal_error";
|
||||
break;
|
||||
case 90:
|
||||
str_details2 = " user_canceled";
|
||||
break;
|
||||
case 100:
|
||||
str_details2 = " no_renegotiation";
|
||||
break;
|
||||
case 110:
|
||||
str_details2 = " unsupported_extension";
|
||||
break;
|
||||
case 111:
|
||||
str_details2 = " certificate_unobtainable";
|
||||
break;
|
||||
case 112:
|
||||
str_details2 = " unrecognized_name";
|
||||
break;
|
||||
case 113:
|
||||
str_details2 = " bad_certificate_status_response";
|
||||
break;
|
||||
case 114:
|
||||
str_details2 = " bad_certificate_hash_value";
|
||||
break;
|
||||
case 115:
|
||||
str_details2 = " unknown_psk_identity";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (content_type == 22) { /* Handshake */
|
||||
str_details1 = "???";
|
||||
|
||||
if (len > 0) {
|
||||
switch (((const unsigned char *) buf)[0]) {
|
||||
case 0:
|
||||
str_details1 = ", HelloRequest";
|
||||
break;
|
||||
case 1:
|
||||
str_details1 = ", ClientHello";
|
||||
break;
|
||||
case 2:
|
||||
str_details1 = ", ServerHello";
|
||||
break;
|
||||
case 3:
|
||||
str_details1 = ", HelloVerifyRequest";
|
||||
break;
|
||||
case 4:
|
||||
str_details1 = ", NewSessionTicket";
|
||||
break;
|
||||
case 5:
|
||||
str_details1 = ", EndOfEarlyData";
|
||||
break;
|
||||
case 8:
|
||||
str_details1 = ", EncryptedExtensions";
|
||||
break;
|
||||
case 11:
|
||||
str_details1 = ", Certificate";
|
||||
break;
|
||||
case 12:
|
||||
str_details1 = ", ServerKeyExchange";
|
||||
break;
|
||||
case 13:
|
||||
str_details1 = ", CertificateRequest";
|
||||
break;
|
||||
case 14:
|
||||
str_details1 = ", ServerHelloDone";
|
||||
break;
|
||||
case 15:
|
||||
str_details1 = ", CertificateVerify";
|
||||
break;
|
||||
case 16:
|
||||
str_details1 = ", ClientKeyExchange";
|
||||
break;
|
||||
case 20:
|
||||
str_details1 = ", Finished";
|
||||
break;
|
||||
case 24:
|
||||
str_details1 = ", KeyUpdate";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIO_printf(bio, "%s %s%s [length %04lx]%s%s\n", str_write_p,
|
||||
str_version, str_content_type, (unsigned long) len,
|
||||
str_details1, str_details2);
|
||||
|
||||
if (len > 0) {
|
||||
size_t num, i;
|
||||
|
||||
BIO_printf(bio, " ");
|
||||
num = len;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i % 16 == 0 && i > 0)
|
||||
BIO_printf(bio, "\n ");
|
||||
BIO_printf(bio, " %02x",
|
||||
((const unsigned char *) buf)[i]);
|
||||
}
|
||||
if (i < len)
|
||||
BIO_printf(bio, " ...");
|
||||
BIO_printf(bio, "\n");
|
||||
}
|
||||
(void) BIO_flush(bio);
|
||||
}
|
||||
|
||||
void
|
||||
tlsext_cb(SSL * s, int client_server, int type, unsigned char *data, int len,
|
||||
void *arg)
|
||||
{
|
||||
BIO *bio = arg;
|
||||
char *extname;
|
||||
|
||||
switch (type) {
|
||||
case TLSEXT_TYPE_server_name:
|
||||
extname = "server name";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_max_fragment_length:
|
||||
extname = "max fragment length";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_client_certificate_url:
|
||||
extname = "client certificate URL";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_trusted_ca_keys:
|
||||
extname = "trusted CA keys";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_truncated_hmac:
|
||||
extname = "truncated HMAC";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_status_request:
|
||||
extname = "status request";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_user_mapping:
|
||||
extname = "user mapping";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_client_authz:
|
||||
extname = "client authz";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_server_authz:
|
||||
extname = "server authz";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_cert_type:
|
||||
extname = "cert type";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_supported_groups:
|
||||
extname = "supported groups";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_ec_point_formats:
|
||||
extname = "EC point formats";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_srp:
|
||||
extname = "SRP";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_signature_algorithms:
|
||||
extname = "signature algorithms";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_use_srtp:
|
||||
extname = "use SRTP";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_heartbeat:
|
||||
extname = "heartbeat";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_application_layer_protocol_negotiation:
|
||||
extname = "application layer protocol negotiation";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_padding:
|
||||
extname = "TLS padding";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_session_ticket:
|
||||
extname = "session ticket";
|
||||
break;
|
||||
|
||||
#if defined(LIBRESSL_HAS_TLS1_3) || defined(LIBRESSL_INTERNAL)
|
||||
case TLSEXT_TYPE_pre_shared_key:
|
||||
extname = "pre shared key";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_early_data:
|
||||
extname = "early data";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_supported_versions:
|
||||
extname = "supported versions";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_cookie:
|
||||
extname = "cookie";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_psk_key_exchange_modes:
|
||||
extname = "PSK key exchange modes";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_certificate_authorities:
|
||||
extname = "certificate authorities";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_oid_filters:
|
||||
extname = "OID filters";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_post_handshake_auth:
|
||||
extname = "post handshake auth";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_signature_algorithms_cert:
|
||||
extname = "signature algorithms cert";
|
||||
break;
|
||||
|
||||
case TLSEXT_TYPE_key_share:
|
||||
extname = "key share";
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TLSEXT_TYPE_renegotiate:
|
||||
extname = "renegotiation info";
|
||||
break;
|
||||
|
||||
default:
|
||||
extname = "unknown";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
BIO_printf(bio, "TLS %s extension \"%s\" (id=%d), len=%d\n",
|
||||
client_server ? "server" : "client", extname, type, len);
|
||||
BIO_dump(bio, (char *) data, len);
|
||||
(void) BIO_flush(bio);
|
||||
}
|
||||
|
||||
int
|
||||
generate_cookie_callback(SSL * ssl, unsigned char *cookie,
|
||||
unsigned int *cookie_len)
|
||||
{
|
||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
||||
unsigned int length, resultlength;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in s4;
|
||||
struct sockaddr_in6 s6;
|
||||
} peer;
|
||||
|
||||
/* Initialize a random secret */
|
||||
if (!cookie_initialized) {
|
||||
arc4random_buf(cookie_secret, COOKIE_SECRET_LENGTH);
|
||||
cookie_initialized = 1;
|
||||
}
|
||||
/* Read peer information */
|
||||
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||
|
||||
/* Create buffer with peer's address and port */
|
||||
length = 0;
|
||||
switch (peer.sa.sa_family) {
|
||||
case AF_INET:
|
||||
length += sizeof(struct in_addr);
|
||||
length += sizeof(peer.s4.sin_port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
length += sizeof(struct in6_addr);
|
||||
length += sizeof(peer.s6.sin6_port);
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
buffer = malloc(length);
|
||||
|
||||
if (buffer == NULL) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
switch (peer.sa.sa_family) {
|
||||
case AF_INET:
|
||||
memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
|
||||
memcpy(buffer + sizeof(peer.s4.sin_port),
|
||||
&peer.s4.sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
|
||||
memcpy(buffer + sizeof(peer.s6.sin6_port),
|
||||
&peer.s6.sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate HMAC of buffer using the secret */
|
||||
HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
|
||||
buffer, length, result, &resultlength);
|
||||
free(buffer);
|
||||
|
||||
memcpy(cookie, result, resultlength);
|
||||
*cookie_len = resultlength;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
verify_cookie_callback(SSL * ssl, const unsigned char *cookie,
|
||||
unsigned int cookie_len)
|
||||
{
|
||||
unsigned char *buffer, result[EVP_MAX_MD_SIZE];
|
||||
unsigned int length, resultlength;
|
||||
union {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_in s4;
|
||||
struct sockaddr_in6 s6;
|
||||
} peer;
|
||||
|
||||
/* If secret isn't initialized yet, the cookie can't be valid */
|
||||
if (!cookie_initialized)
|
||||
return 0;
|
||||
|
||||
/* Read peer information */
|
||||
(void) BIO_dgram_get_peer(SSL_get_rbio(ssl), &peer);
|
||||
|
||||
/* Create buffer with peer's address and port */
|
||||
length = 0;
|
||||
switch (peer.sa.sa_family) {
|
||||
case AF_INET:
|
||||
length += sizeof(struct in_addr);
|
||||
length += sizeof(peer.s4.sin_port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
length += sizeof(struct in6_addr);
|
||||
length += sizeof(peer.s6.sin6_port);
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
buffer = malloc(length);
|
||||
|
||||
if (buffer == NULL) {
|
||||
BIO_printf(bio_err, "out of memory\n");
|
||||
return 0;
|
||||
}
|
||||
switch (peer.sa.sa_family) {
|
||||
case AF_INET:
|
||||
memcpy(buffer, &peer.s4.sin_port, sizeof(peer.s4.sin_port));
|
||||
memcpy(buffer + sizeof(peer.s4.sin_port),
|
||||
&peer.s4.sin_addr, sizeof(struct in_addr));
|
||||
break;
|
||||
case AF_INET6:
|
||||
memcpy(buffer, &peer.s6.sin6_port, sizeof(peer.s6.sin6_port));
|
||||
memcpy(buffer + sizeof(peer.s6.sin6_port),
|
||||
&peer.s6.sin6_addr, sizeof(struct in6_addr));
|
||||
break;
|
||||
default:
|
||||
OPENSSL_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Calculate HMAC of buffer using the secret */
|
||||
if (HMAC(EVP_sha1(), cookie_secret, COOKIE_SECRET_LENGTH,
|
||||
buffer, length, result, &resultlength) == NULL) {
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
|
||||
if (cookie_len == resultlength &&
|
||||
memcmp(result, cookie, resultlength) == 0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,327 +0,0 @@
|
||||
/* $OpenBSD: s_socket.c,v 1.13 2021/12/06 11:06:58 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#include "s_apps.h"
|
||||
|
||||
static int init_server(int *sock, int port, int type);
|
||||
static int init_server_long(int *sock, int port, char *ip, int type);
|
||||
static int do_accept(int acc_sock, int *sock);
|
||||
|
||||
int
|
||||
init_client(int *sock, char *host, char *port, int type, int af)
|
||||
{
|
||||
struct addrinfo hints, *ai_top, *ai;
|
||||
int i, s = -1;
|
||||
|
||||
memset(&hints, '\0', sizeof(hints));
|
||||
hints.ai_family = af;
|
||||
hints.ai_socktype = type;
|
||||
|
||||
if ((i = getaddrinfo(host, port, &hints, &ai_top)) != 0) {
|
||||
BIO_printf(bio_err, "getaddrinfo: %s\n", gai_strerror(i));
|
||||
return (0);
|
||||
}
|
||||
if (ai_top == NULL || ai_top->ai_addr == NULL) {
|
||||
BIO_printf(bio_err, "getaddrinfo returned no addresses\n");
|
||||
if (ai_top != NULL) {
|
||||
freeaddrinfo(ai_top);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
for (ai = ai_top; ai != NULL; ai = ai->ai_next) {
|
||||
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
|
||||
if (s == -1) {
|
||||
continue;
|
||||
}
|
||||
if (type == SOCK_STREAM) {
|
||||
i = 0;
|
||||
i = setsockopt(s, SOL_SOCKET, SO_KEEPALIVE,
|
||||
(char *) &i, sizeof(i));
|
||||
if (i == -1) {
|
||||
perror("keepalive");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if ((i = connect(s, ai->ai_addr, ai->ai_addrlen)) == 0) {
|
||||
*sock = s;
|
||||
freeaddrinfo(ai_top);
|
||||
return (1);
|
||||
}
|
||||
close(s);
|
||||
s = -1;
|
||||
}
|
||||
|
||||
perror("connect");
|
||||
out:
|
||||
if (s != -1)
|
||||
close(s);
|
||||
freeaddrinfo(ai_top);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
do_server(int port, int type, int *ret,
|
||||
int (*cb)(int s, unsigned char *context),
|
||||
unsigned char *context, int naccept)
|
||||
{
|
||||
int sock;
|
||||
int accept_socket = 0;
|
||||
int i;
|
||||
|
||||
if (!init_server(&accept_socket, port, type))
|
||||
return (0);
|
||||
|
||||
if (ret != NULL) {
|
||||
*ret = accept_socket;
|
||||
/* return(1); */
|
||||
}
|
||||
for (;;) {
|
||||
if (type == SOCK_STREAM) {
|
||||
if (do_accept(accept_socket, &sock) == 0) {
|
||||
shutdown(accept_socket, SHUT_RD);
|
||||
close(accept_socket);
|
||||
return (0);
|
||||
}
|
||||
} else
|
||||
sock = accept_socket;
|
||||
i = cb(sock, context);
|
||||
if (type == SOCK_STREAM) {
|
||||
shutdown(sock, SHUT_RDWR);
|
||||
close(sock);
|
||||
}
|
||||
if (naccept != -1)
|
||||
naccept--;
|
||||
if (i < 0 || naccept == 0) {
|
||||
shutdown(accept_socket, SHUT_RDWR);
|
||||
close(accept_socket);
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
init_server_long(int *sock, int port, char *ip, int type)
|
||||
{
|
||||
int ret = 0;
|
||||
struct sockaddr_in server;
|
||||
int s = -1;
|
||||
|
||||
memset((char *) &server, 0, sizeof(server));
|
||||
server.sin_family = AF_INET;
|
||||
server.sin_port = htons((unsigned short) port);
|
||||
if (ip == NULL)
|
||||
server.sin_addr.s_addr = INADDR_ANY;
|
||||
else
|
||||
memcpy(&server.sin_addr.s_addr, ip, 4);
|
||||
|
||||
if (type == SOCK_STREAM)
|
||||
s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
else /* type == SOCK_DGRAM */
|
||||
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (s == -1)
|
||||
goto err;
|
||||
#if defined SOL_SOCKET && defined SO_REUSEADDR
|
||||
{
|
||||
int j = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR,
|
||||
(void *) &j, sizeof j) == -1) {
|
||||
perror("setsockopt");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (bind(s, (struct sockaddr *) & server, sizeof(server)) == -1) {
|
||||
perror("bind");
|
||||
goto err;
|
||||
}
|
||||
/* Make it 128 for linux */
|
||||
if (type == SOCK_STREAM && listen(s, 128) == -1)
|
||||
goto err;
|
||||
*sock = s;
|
||||
ret = 1;
|
||||
err:
|
||||
if ((ret == 0) && (s != -1)) {
|
||||
shutdown(s, SHUT_RD);
|
||||
close(s);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
init_server(int *sock, int port, int type)
|
||||
{
|
||||
return (init_server_long(sock, port, NULL, type));
|
||||
}
|
||||
|
||||
static int
|
||||
do_accept(int acc_sock, int *sock)
|
||||
{
|
||||
struct hostent *h1, *h2;
|
||||
static struct sockaddr_in from;
|
||||
socklen_t len;
|
||||
char *host = NULL;
|
||||
int ret;
|
||||
|
||||
redoit:
|
||||
|
||||
memset((char *) &from, 0, sizeof(from));
|
||||
len = sizeof(from);
|
||||
ret = accept(acc_sock, (struct sockaddr *) & from, &len);
|
||||
if (ret == -1) {
|
||||
if (errno == EINTR) {
|
||||
/* check_timeout(); */
|
||||
goto redoit;
|
||||
}
|
||||
fprintf(stderr, "errno=%d ", errno);
|
||||
perror("accept");
|
||||
return (0);
|
||||
}
|
||||
|
||||
h1 = gethostbyaddr((char *) &from.sin_addr.s_addr,
|
||||
sizeof(from.sin_addr.s_addr), AF_INET);
|
||||
if (h1 == NULL) {
|
||||
BIO_printf(bio_err, "bad gethostbyaddr\n");
|
||||
} else {
|
||||
if ((host = strdup(h1->h_name)) == NULL) {
|
||||
perror("strdup");
|
||||
close(ret);
|
||||
return (0);
|
||||
}
|
||||
|
||||
h2 = gethostbyname(host);
|
||||
if (h2 == NULL) {
|
||||
BIO_printf(bio_err, "gethostbyname failure\n");
|
||||
close(ret);
|
||||
free(host);
|
||||
return (0);
|
||||
}
|
||||
if (h2->h_addrtype != AF_INET) {
|
||||
BIO_printf(bio_err, "gethostbyname addr is not AF_INET\n");
|
||||
close(ret);
|
||||
free(host);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
free(host);
|
||||
*sock = ret;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
extract_host_port(char *str, char **host_ptr, unsigned char *ip,
|
||||
char **port_ptr)
|
||||
{
|
||||
char *h, *p;
|
||||
|
||||
h = str;
|
||||
p = strrchr(str, '/'); /* IPv6 host/port */
|
||||
if (p == NULL) {
|
||||
p = strrchr(str, ':');
|
||||
}
|
||||
if (p == NULL) {
|
||||
BIO_printf(bio_err, "no port defined\n");
|
||||
return (0);
|
||||
}
|
||||
*(p++) = '\0';
|
||||
|
||||
if (host_ptr != NULL)
|
||||
*host_ptr = h;
|
||||
|
||||
if (port_ptr != NULL && p != NULL && *p != '\0')
|
||||
*port_ptr = p;
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
extract_port(char *str, short *port_ptr)
|
||||
{
|
||||
int i;
|
||||
const char *errstr;
|
||||
struct servent *s;
|
||||
|
||||
i = strtonum(str, 1, 65535, &errstr);
|
||||
if (!errstr) {
|
||||
*port_ptr = (unsigned short) i;
|
||||
} else {
|
||||
s = getservbyname(str, "tcp");
|
||||
if (s == NULL) {
|
||||
BIO_printf(bio_err, "getservbyname failure for %s\n", str);
|
||||
return (0);
|
||||
}
|
||||
*port_ptr = ntohs((unsigned short) s->s_port);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
@@ -1,465 +0,0 @@
|
||||
/* $OpenBSD: s_time.c,v 1.38 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
/*-----------------------------------------
|
||||
s_time - SSL client connection timer program
|
||||
Written and donated by Larry Streepy <streepy@healthcare.com>
|
||||
-----------------------------------------*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include "s_apps.h"
|
||||
|
||||
#define SSL_CONNECT_NAME "localhost:4433"
|
||||
|
||||
#define BUFSIZZ 1024*10
|
||||
|
||||
#define MYBUFSIZ 1024*8
|
||||
|
||||
#define SECONDS 30
|
||||
extern int verify_depth;
|
||||
|
||||
static void s_time_usage(void);
|
||||
static int run_test(SSL *);
|
||||
static int benchmark(int);
|
||||
static void print_tally_mark(SSL *);
|
||||
|
||||
static SSL_CTX *tm_ctx = NULL;
|
||||
static const SSL_METHOD *s_time_meth = NULL;
|
||||
static long bytes_read = 0;
|
||||
|
||||
static struct {
|
||||
int bugs;
|
||||
char *CAfile;
|
||||
char *CApath;
|
||||
char *certfile;
|
||||
char *cipher;
|
||||
char *host;
|
||||
char *keyfile;
|
||||
time_t maxtime;
|
||||
int nbio;
|
||||
int no_shutdown;
|
||||
int perform;
|
||||
int verify;
|
||||
int verify_depth;
|
||||
char *www_path;
|
||||
} cfg;
|
||||
|
||||
static const struct option s_time_options[] = {
|
||||
{
|
||||
.name = "bugs",
|
||||
.desc = "Enable workarounds for known SSL/TLS bugs",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.bugs,
|
||||
},
|
||||
{
|
||||
.name = "CAfile",
|
||||
.argname = "file",
|
||||
.desc = "File containing trusted certificates in PEM format",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.CAfile,
|
||||
},
|
||||
{
|
||||
.name = "CApath",
|
||||
.argname = "path",
|
||||
.desc = "Directory containing trusted certificates",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.CApath,
|
||||
},
|
||||
{
|
||||
.name = "cert",
|
||||
.argname = "file",
|
||||
.desc = "Client certificate to use, if one is requested",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.certfile,
|
||||
},
|
||||
{
|
||||
.name = "cipher",
|
||||
.argname = "list",
|
||||
.desc = "List of cipher suites to send to the server",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.cipher,
|
||||
},
|
||||
{
|
||||
.name = "connect",
|
||||
.argname = "host:port",
|
||||
.desc = "Host and port to connect to (default "
|
||||
SSL_CONNECT_NAME ")",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.host,
|
||||
},
|
||||
{
|
||||
.name = "key",
|
||||
.argname = "file",
|
||||
.desc = "Client private key to use, if one is required",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keyfile,
|
||||
},
|
||||
{
|
||||
.name = "nbio",
|
||||
.desc = "Use non-blocking I/O",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.nbio,
|
||||
},
|
||||
{
|
||||
.name = "new",
|
||||
.desc = "Use a new session ID for each connection",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.perform,
|
||||
.value = 1,
|
||||
},
|
||||
{
|
||||
.name = "no_shutdown",
|
||||
.desc = "Shut down the connection without notifying the server",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.no_shutdown,
|
||||
},
|
||||
{
|
||||
.name = "reuse",
|
||||
.desc = "Reuse the same session ID for each connection",
|
||||
.type = OPTION_VALUE,
|
||||
.opt.value = &cfg.perform,
|
||||
.value = 2,
|
||||
},
|
||||
{
|
||||
.name = "time",
|
||||
.argname = "seconds",
|
||||
.desc = "Duration to perform timing tests for (default 30)",
|
||||
.type = OPTION_ARG_TIME,
|
||||
.opt.tvalue = &cfg.maxtime,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.argname = "depth",
|
||||
.desc = "Enable peer certificate verification with given depth",
|
||||
.type = OPTION_ARG_INT,
|
||||
.opt.value = &cfg.verify_depth,
|
||||
},
|
||||
{
|
||||
.name = "www",
|
||||
.argname = "page",
|
||||
.desc = "Page to GET from the server (default none)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.www_path,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
s_time_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: s_time "
|
||||
"[-bugs] [-CAfile file] [-CApath directory] [-cert file]\n"
|
||||
" [-cipher cipherlist] [-connect host:port] [-key keyfile]\n"
|
||||
" [-nbio] [-new] [-no_shutdown] [-reuse] [-time seconds]\n"
|
||||
" [-verify depth] [-www page]\n\n");
|
||||
options_usage(s_time_options);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* MAIN - main processing area for client
|
||||
* real name depends on MONOLITH
|
||||
*/
|
||||
int
|
||||
s_time_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio rpath inet dns", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
s_time_meth = TLS_client_method();
|
||||
|
||||
verify_depth = 0;
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.host = SSL_CONNECT_NAME;
|
||||
cfg.maxtime = SECONDS;
|
||||
cfg.perform = 3;
|
||||
cfg.verify = SSL_VERIFY_NONE;
|
||||
cfg.verify_depth = -1;
|
||||
|
||||
if (options_parse(argc, argv, s_time_options, NULL, NULL) != 0) {
|
||||
s_time_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.verify_depth >= 0) {
|
||||
cfg.verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
|
||||
verify_depth = cfg.verify_depth;
|
||||
BIO_printf(bio_err, "verify depth is %d\n", verify_depth);
|
||||
}
|
||||
|
||||
if (cfg.www_path != NULL &&
|
||||
strlen(cfg.www_path) > MYBUFSIZ - 100) {
|
||||
BIO_printf(bio_err, "-www option too long\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((tm_ctx = SSL_CTX_new(s_time_meth)) == NULL)
|
||||
return (1);
|
||||
|
||||
SSL_CTX_set_quiet_shutdown(tm_ctx, 1);
|
||||
|
||||
if (cfg.bugs)
|
||||
SSL_CTX_set_options(tm_ctx, SSL_OP_ALL);
|
||||
|
||||
if (cfg.cipher != NULL) {
|
||||
if (!SSL_CTX_set_cipher_list(tm_ctx, cfg.cipher)) {
|
||||
BIO_printf(bio_err, "error setting cipher list\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
SSL_CTX_set_verify(tm_ctx, cfg.verify, NULL);
|
||||
|
||||
if (!set_cert_stuff(tm_ctx, cfg.certfile,
|
||||
cfg.keyfile))
|
||||
goto end;
|
||||
|
||||
if ((!SSL_CTX_load_verify_locations(tm_ctx, cfg.CAfile,
|
||||
cfg.CApath)) ||
|
||||
(!SSL_CTX_set_default_verify_paths(tm_ctx))) {
|
||||
/*
|
||||
* BIO_printf(bio_err,"error setting default verify
|
||||
* locations\n");
|
||||
*/
|
||||
ERR_print_errors(bio_err);
|
||||
/* goto end; */
|
||||
}
|
||||
|
||||
/* Loop and time how long it takes to make connections */
|
||||
if (cfg.perform & 1) {
|
||||
printf("Collecting connection statistics for %lld seconds\n",
|
||||
(long long)cfg.maxtime);
|
||||
if (benchmark(0))
|
||||
goto end;
|
||||
}
|
||||
/*
|
||||
* Now loop and time connections using the same session id over and
|
||||
* over
|
||||
*/
|
||||
if (cfg.perform & 2) {
|
||||
printf("\n\nNow timing with session id reuse.\n");
|
||||
if (benchmark(1))
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
end:
|
||||
if (tm_ctx != NULL) {
|
||||
SSL_CTX_free(tm_ctx);
|
||||
tm_ctx = NULL;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* run_test - make a connection, get a file, and shut down the connection
|
||||
*
|
||||
* Args:
|
||||
* scon = SSL connection
|
||||
* Returns:
|
||||
* 1 on success, 0 on error
|
||||
*/
|
||||
static int
|
||||
run_test(SSL *scon)
|
||||
{
|
||||
char buf[1024 * 8];
|
||||
struct pollfd pfd[1];
|
||||
BIO *conn;
|
||||
long verify_error;
|
||||
int i, retval;
|
||||
|
||||
if ((conn = BIO_new(BIO_s_connect())) == NULL)
|
||||
return 0;
|
||||
BIO_set_conn_hostname(conn, cfg.host);
|
||||
SSL_set_connect_state(scon);
|
||||
SSL_set_bio(scon, conn, conn);
|
||||
for (;;) {
|
||||
i = SSL_connect(scon);
|
||||
if (BIO_sock_should_retry(i)) {
|
||||
BIO_printf(bio_err, "DELAY\n");
|
||||
pfd[0].fd = SSL_get_fd(scon);
|
||||
pfd[0].events = POLLIN;
|
||||
poll(pfd, 1, -1);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (i <= 0) {
|
||||
BIO_printf(bio_err, "ERROR\n");
|
||||
verify_error = SSL_get_verify_result(scon);
|
||||
if (verify_error != X509_V_OK)
|
||||
BIO_printf(bio_err, "verify error:%s\n",
|
||||
X509_verify_cert_error_string(verify_error));
|
||||
else
|
||||
ERR_print_errors(bio_err);
|
||||
return 0;
|
||||
}
|
||||
if (cfg.www_path != NULL) {
|
||||
retval = snprintf(buf, sizeof buf,
|
||||
"GET %s HTTP/1.0\r\n\r\n", cfg.www_path);
|
||||
if (retval < 0 || retval >= sizeof buf) {
|
||||
fprintf(stderr, "URL too long\n");
|
||||
return 0;
|
||||
}
|
||||
if (SSL_write(scon, buf, retval) != retval)
|
||||
return 0;
|
||||
while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
|
||||
bytes_read += i;
|
||||
}
|
||||
if (cfg.no_shutdown)
|
||||
SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN |
|
||||
SSL_RECEIVED_SHUTDOWN);
|
||||
else
|
||||
SSL_shutdown(scon);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
print_tally_mark(SSL *scon)
|
||||
{
|
||||
int ver;
|
||||
|
||||
if (SSL_session_reused(scon))
|
||||
ver = 'r';
|
||||
else {
|
||||
ver = SSL_version(scon);
|
||||
if (ver == TLS1_VERSION)
|
||||
ver = 't';
|
||||
else
|
||||
ver = '*';
|
||||
}
|
||||
fputc(ver, stdout);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static int
|
||||
benchmark(int reuse_session)
|
||||
{
|
||||
double elapsed, totalTime;
|
||||
int nConn = 0;
|
||||
SSL *scon = NULL;
|
||||
int ret = 1;
|
||||
|
||||
if (reuse_session) {
|
||||
/* Get an SSL object so we can reuse the session id */
|
||||
if ((scon = SSL_new(tm_ctx)) == NULL)
|
||||
goto end;
|
||||
if (!run_test(scon)) {
|
||||
fprintf(stderr, "Unable to get connection\n");
|
||||
goto end;
|
||||
}
|
||||
printf("starting\n");
|
||||
}
|
||||
|
||||
nConn = 0;
|
||||
bytes_read = 0;
|
||||
|
||||
app_timer_real(TM_RESET);
|
||||
app_timer_user(TM_RESET);
|
||||
for (;;) {
|
||||
elapsed = app_timer_real(TM_GET);
|
||||
if (elapsed > cfg.maxtime)
|
||||
break;
|
||||
if (scon == NULL) {
|
||||
if ((scon = SSL_new(tm_ctx)) == NULL)
|
||||
goto end;
|
||||
}
|
||||
if (!run_test(scon))
|
||||
goto end;
|
||||
nConn += 1;
|
||||
print_tally_mark(scon);
|
||||
if (!reuse_session) {
|
||||
SSL_free(scon);
|
||||
scon = NULL;
|
||||
}
|
||||
}
|
||||
totalTime = app_timer_user(TM_GET);
|
||||
|
||||
printf("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
|
||||
nConn, totalTime, ((double) nConn / totalTime), bytes_read);
|
||||
printf("%d connections in %.0f real seconds, %ld bytes read per connection\n",
|
||||
nConn, elapsed, nConn > 0 ? bytes_read / nConn : 0);
|
||||
|
||||
ret = 0;
|
||||
end:
|
||||
SSL_free(scon);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,293 +0,0 @@
|
||||
/* $OpenBSD: sess_id.c,v 1.12 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
int cert;
|
||||
char *context;
|
||||
char *infile;
|
||||
int informat;
|
||||
int noout;
|
||||
char *outfile;
|
||||
int outformat;
|
||||
int text;
|
||||
} cfg;
|
||||
|
||||
static const struct option sess_id_options[] = {
|
||||
{
|
||||
.name = "cert",
|
||||
.desc = "Output certificate if present in session",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.cert,
|
||||
},
|
||||
{
|
||||
.name = "context",
|
||||
.argname = "id",
|
||||
.desc = "Set the session ID context for output",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.context,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "inform",
|
||||
.argname = "format",
|
||||
.desc = "Input format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.informat,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not output the encoded session info",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "outform",
|
||||
.argname = "format",
|
||||
.desc = "Output format (DER or PEM (default))",
|
||||
.type = OPTION_ARG_FORMAT,
|
||||
.opt.value = &cfg.outformat,
|
||||
},
|
||||
{
|
||||
.name = "text",
|
||||
.desc = "Print various public or private key components in"
|
||||
" plain text",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.text,
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
sess_id_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: sess_id [-cert] [-context id] [-in file] [-inform fmt] "
|
||||
"[-noout]\n"
|
||||
" [-out file] [-outform fmt] [-text]\n\n");
|
||||
options_usage(sess_id_options);
|
||||
}
|
||||
|
||||
static SSL_SESSION *load_sess_id(char *file, int format);
|
||||
|
||||
int
|
||||
sess_id_main(int argc, char **argv)
|
||||
{
|
||||
SSL_SESSION *x = NULL;
|
||||
X509 *peer = NULL;
|
||||
int ret = 1, i;
|
||||
BIO *out = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
cfg.informat = FORMAT_PEM;
|
||||
cfg.outformat = FORMAT_PEM;
|
||||
|
||||
if (options_parse(argc, argv, sess_id_options, NULL, NULL) != 0) {
|
||||
sess_id_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
x = load_sess_id(cfg.infile, cfg.informat);
|
||||
if (x == NULL) {
|
||||
goto end;
|
||||
}
|
||||
peer = SSL_SESSION_get0_peer(x);
|
||||
|
||||
if (cfg.context) {
|
||||
size_t ctx_len = strlen(cfg.context);
|
||||
if (ctx_len > SSL_MAX_SID_CTX_LENGTH) {
|
||||
BIO_printf(bio_err, "Context too long\n");
|
||||
goto end;
|
||||
}
|
||||
SSL_SESSION_set1_id_context(x,
|
||||
(unsigned char *)cfg.context, ctx_len);
|
||||
}
|
||||
|
||||
if (!cfg.noout || cfg.text) {
|
||||
out = BIO_new(BIO_s_file());
|
||||
if (out == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile == NULL) {
|
||||
BIO_set_fp(out, stdout, BIO_NOCLOSE);
|
||||
} else {
|
||||
if (BIO_write_filename(out, cfg.outfile)
|
||||
<= 0) {
|
||||
perror(cfg.outfile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cfg.text) {
|
||||
SSL_SESSION_print(out, x);
|
||||
|
||||
if (cfg.cert) {
|
||||
if (peer == NULL)
|
||||
BIO_puts(out, "No certificate present\n");
|
||||
else
|
||||
X509_print(out, peer);
|
||||
}
|
||||
}
|
||||
if (!cfg.noout && !cfg.cert) {
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = i2d_SSL_SESSION_bio(out, x);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_SSL_SESSION(out, x);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write SSL_SESSION\n");
|
||||
goto end;
|
||||
}
|
||||
} else if (!cfg.noout && (peer != NULL)) {
|
||||
/* just print the certificate */
|
||||
if (cfg.outformat == FORMAT_ASN1)
|
||||
i = (int) i2d_X509_bio(out, peer);
|
||||
else if (cfg.outformat == FORMAT_PEM)
|
||||
i = PEM_write_bio_X509(out, peer);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad output format specified for outfile\n");
|
||||
goto end;
|
||||
}
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "unable to write X509\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
BIO_free_all(out);
|
||||
SSL_SESSION_free(x);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static SSL_SESSION *
|
||||
load_sess_id(char *infile, int format)
|
||||
{
|
||||
SSL_SESSION *x = NULL;
|
||||
BIO *in = NULL;
|
||||
|
||||
in = BIO_new(BIO_s_file());
|
||||
if (in == NULL) {
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (infile == NULL)
|
||||
BIO_set_fp(in, stdin, BIO_NOCLOSE);
|
||||
else {
|
||||
if (BIO_read_filename(in, infile) <= 0) {
|
||||
perror(infile);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (format == FORMAT_ASN1)
|
||||
x = d2i_SSL_SESSION_bio(in, NULL);
|
||||
else if (format == FORMAT_PEM)
|
||||
x = PEM_read_bio_SSL_SESSION(in, NULL, NULL, NULL);
|
||||
else {
|
||||
BIO_printf(bio_err,
|
||||
"bad input format specified for input crl\n");
|
||||
goto end;
|
||||
}
|
||||
if (x == NULL) {
|
||||
BIO_printf(bio_err, "unable to load SSL_SESSION\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
BIO_free(in);
|
||||
return (x);
|
||||
}
|
||||
1103
apps/openssl/smime.c
1103
apps/openssl/smime.c
File diff suppressed because it is too large
Load Diff
2136
apps/openssl/speed.c
2136
apps/openssl/speed.c
File diff suppressed because it is too large
Load Diff
@@ -1,311 +0,0 @@
|
||||
/* $OpenBSD: spkac.c,v 1.13 2023/03/06 14:32:06 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999. Based on an original idea by Massimiliano Pala
|
||||
* (madwolf@openca.org).
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apps.h"
|
||||
#include "progs.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/conf.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/lhash.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
static struct {
|
||||
char *challenge;
|
||||
char *infile;
|
||||
char *keyfile;
|
||||
int noout;
|
||||
char *outfile;
|
||||
char *passargin;
|
||||
int pubkey;
|
||||
char *spkac;
|
||||
char *spksect;
|
||||
int verify;
|
||||
} cfg;
|
||||
|
||||
static const struct option spkac_options[] = {
|
||||
{
|
||||
.name = "challenge",
|
||||
.argname = "string",
|
||||
.desc = "Specify challenge string if SPKAC is generated",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.challenge,
|
||||
},
|
||||
{
|
||||
.name = "in",
|
||||
.argname = "file",
|
||||
.desc = "Input file (default stdin)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.infile,
|
||||
},
|
||||
{
|
||||
.name = "key",
|
||||
.argname = "file",
|
||||
.desc = "Create SPKAC using private key file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.keyfile,
|
||||
},
|
||||
{
|
||||
.name = "noout",
|
||||
.desc = "Do not print text version of SPKAC",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.noout,
|
||||
},
|
||||
{
|
||||
.name = "out",
|
||||
.argname = "file",
|
||||
.desc = "Output file (default stdout)",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.outfile,
|
||||
},
|
||||
{
|
||||
.name = "passin",
|
||||
.argname = "src",
|
||||
.desc = "Input file passphrase source",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.passargin,
|
||||
},
|
||||
{
|
||||
.name = "pubkey",
|
||||
.desc = "Output public key of an SPKAC (not used if creating)",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.pubkey,
|
||||
},
|
||||
{
|
||||
.name = "spkac",
|
||||
.argname = "name",
|
||||
.desc = "SPKAC name (default \"SPKAC\")",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.spkac,
|
||||
},
|
||||
{
|
||||
.name = "spksect",
|
||||
.argname = "name",
|
||||
.desc = "Name of the section containing SPKAC (default"
|
||||
" \"default\")",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.spksect,
|
||||
},
|
||||
{
|
||||
.name = "verify",
|
||||
.desc = "Verify digital signature on supplied SPKAC",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.verify,
|
||||
},
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
spkac_usage(void)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: spkac [-challenge string] [-in file] "
|
||||
"[-key file] [-noout]\n"
|
||||
" [-out file] [-passin src] [-pubkey] [-spkac name] "
|
||||
"[-spksect section]\n"
|
||||
" [-verify]\n\n");
|
||||
options_usage(spkac_options);
|
||||
}
|
||||
|
||||
int
|
||||
spkac_main(int argc, char **argv)
|
||||
{
|
||||
int i, ret = 1;
|
||||
BIO *in = NULL, *out = NULL;
|
||||
char *passin = NULL;
|
||||
char *spkstr = NULL;
|
||||
CONF *conf = NULL;
|
||||
NETSCAPE_SPKI *spki = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
if (pledge("stdio cpath wpath rpath tty", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.spkac = "SPKAC";
|
||||
cfg.spksect = "default";
|
||||
|
||||
if (options_parse(argc, argv, spkac_options, NULL, NULL) != 0) {
|
||||
spkac_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (!app_passwd(bio_err, cfg.passargin, NULL, &passin, NULL)) {
|
||||
BIO_printf(bio_err, "Error getting password\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.keyfile) {
|
||||
pkey = load_key(bio_err,
|
||||
strcmp(cfg.keyfile, "-") ? cfg.keyfile
|
||||
: NULL, FORMAT_PEM, 1, passin, "private key");
|
||||
if (!pkey) {
|
||||
goto end;
|
||||
}
|
||||
spki = NETSCAPE_SPKI_new();
|
||||
if (cfg.challenge)
|
||||
ASN1_STRING_set(spki->spkac->challenge,
|
||||
cfg.challenge,
|
||||
(int) strlen(cfg.challenge));
|
||||
NETSCAPE_SPKI_set_pubkey(spki, pkey);
|
||||
NETSCAPE_SPKI_sign(spki, pkey, EVP_md5());
|
||||
spkstr = NETSCAPE_SPKI_b64_encode(spki);
|
||||
if (spkstr == NULL) {
|
||||
BIO_printf(bio_err, "Error encoding SPKAC\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cfg.outfile)
|
||||
out = BIO_new_file(cfg.outfile, "w");
|
||||
else
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
|
||||
if (!out) {
|
||||
BIO_printf(bio_err, "Error opening output file\n");
|
||||
ERR_print_errors(bio_err);
|
||||
} else {
|
||||
BIO_printf(out, "SPKAC=%s\n", spkstr);
|
||||
ret = 0;
|
||||
}
|
||||
free(spkstr);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.infile)
|
||||
in = BIO_new_file(cfg.infile, "r");
|
||||
else
|
||||
in = BIO_new_fp(stdin, BIO_NOCLOSE);
|
||||
|
||||
if (!in) {
|
||||
BIO_printf(bio_err, "Error opening input file\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
conf = NCONF_new(NULL);
|
||||
i = NCONF_load_bio(conf, in, NULL);
|
||||
|
||||
if (!i) {
|
||||
BIO_printf(bio_err, "Error parsing config file\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
spkstr = NCONF_get_string(conf, cfg.spksect,
|
||||
cfg.spkac);
|
||||
|
||||
if (!spkstr) {
|
||||
BIO_printf(bio_err, "Can't find SPKAC called \"%s\"\n",
|
||||
cfg.spkac);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
spki = NETSCAPE_SPKI_b64_decode(spkstr, -1);
|
||||
|
||||
if (!spki) {
|
||||
BIO_printf(bio_err, "Error loading SPKAC\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (cfg.outfile)
|
||||
out = BIO_new_file(cfg.outfile, "w");
|
||||
else {
|
||||
out = BIO_new_fp(stdout, BIO_NOCLOSE);
|
||||
}
|
||||
|
||||
if (!out) {
|
||||
BIO_printf(bio_err, "Error opening output file\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
if (!cfg.noout)
|
||||
NETSCAPE_SPKI_print(out, spki);
|
||||
pkey = NETSCAPE_SPKI_get_pubkey(spki);
|
||||
if (cfg.verify) {
|
||||
i = NETSCAPE_SPKI_verify(spki, pkey);
|
||||
if (i > 0)
|
||||
BIO_printf(bio_err, "Signature OK\n");
|
||||
else {
|
||||
BIO_printf(bio_err, "Signature Failure\n");
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
if (cfg.pubkey)
|
||||
PEM_write_bio_PUBKEY(out, pkey);
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
NCONF_free(conf);
|
||||
NETSCAPE_SPKI_free(spki);
|
||||
BIO_free(in);
|
||||
BIO_free_all(out);
|
||||
EVP_PKEY_free(pkey);
|
||||
free(passin);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
/* $OpenBSD: testdsa.h,v 1.5 2022/01/10 19:22:26 tb Exp $ */
|
||||
|
||||
DSA *get_dsa512(void);
|
||||
DSA *get_dsa1024(void);
|
||||
DSA *get_dsa2048(void);
|
||||
|
||||
DSA *get_dsa(const unsigned char *priv, size_t priv_size,
|
||||
const unsigned char *pub, size_t pub_size,
|
||||
const unsigned char *p, size_t p_size,
|
||||
const unsigned char *q, size_t q_size,
|
||||
const unsigned char *g, size_t g_size);
|
||||
|
||||
static const unsigned char dsa512_priv[] = {
|
||||
0x65, 0xe5, 0xc7, 0x38, 0x60, 0x24, 0xb5, 0x89, 0xd4, 0x9c, 0xeb, 0x4c,
|
||||
0x9c, 0x1d, 0x7a, 0x22, 0xbd, 0xd1, 0xc2, 0xd2,
|
||||
};
|
||||
|
||||
static const unsigned char dsa512_pub[] = {
|
||||
0x00, 0x95, 0xa7, 0x0d, 0xec, 0x93, 0x68, 0xba, 0x5f, 0xf7, 0x5f, 0x07,
|
||||
0xf2, 0x3b, 0xad, 0x6b, 0x01, 0xdc, 0xbe, 0xec, 0xde, 0x04, 0x7a, 0x3a,
|
||||
0x27, 0xb3, 0xec, 0x49, 0xfd, 0x08, 0x43, 0x3d, 0x7e, 0xa8, 0x2c, 0x5e,
|
||||
0x7b, 0xbb, 0xfc, 0xf4, 0x6e, 0xeb, 0x6c, 0xb0, 0x6e, 0xf8, 0x02, 0x12,
|
||||
0x8c, 0x38, 0x5d, 0x83, 0x56, 0x7d, 0xee, 0x53, 0x05, 0x3e, 0x24, 0x84,
|
||||
0xbe, 0xba, 0x0a, 0x6b, 0xc8,
|
||||
};
|
||||
|
||||
static const unsigned char dsa512_p[] = {
|
||||
0x9D, 0x1B, 0x69, 0x8E, 0x26, 0xDB, 0xF2, 0x2B, 0x11, 0x70, 0x19, 0x86,
|
||||
0xF6, 0x19, 0xC8, 0xF8, 0x19, 0xF2, 0x18, 0x53, 0x94, 0x46, 0x06, 0xD0,
|
||||
0x62, 0x50, 0x33, 0x4B, 0x02, 0x3C, 0x52, 0x30, 0x03, 0x8B, 0x3B, 0xF9,
|
||||
0x5F, 0xD1, 0x24, 0x06, 0x4F, 0x7B, 0x4C, 0xBA, 0xAA, 0x40, 0x9B, 0xFD,
|
||||
0x96, 0xE4, 0x37, 0x33, 0xBB, 0x2D, 0x5A, 0xD7, 0x5A, 0x11, 0x40, 0x66,
|
||||
0xA2, 0x76, 0x7D, 0x31,
|
||||
};
|
||||
|
||||
static const unsigned char dsa512_q[] = {
|
||||
0xFB, 0x53, 0xEF, 0x50, 0xB4, 0x40, 0x92, 0x31, 0x56, 0x86, 0x53, 0x7A,
|
||||
0xE8, 0x8B, 0x22, 0x9A, 0x49, 0xFB, 0x71, 0x8F,
|
||||
};
|
||||
|
||||
static const unsigned char dsa512_g[] = {
|
||||
0x83, 0x3E, 0x88, 0xE5, 0xC5, 0x89, 0x73, 0xCE, 0x3B, 0x6C, 0x01, 0x49,
|
||||
0xBF, 0xB3, 0xC7, 0x9F, 0x0A, 0xEA, 0x44, 0x91, 0xE5, 0x30, 0xAA, 0xD9,
|
||||
0xBE, 0x5B, 0x5F, 0xB7, 0x10, 0xD7, 0x89, 0xB7, 0x8E, 0x74, 0xFB, 0xCF,
|
||||
0x29, 0x1E, 0xEB, 0xA8, 0x2C, 0x54, 0x51, 0xB8, 0x10, 0xDE, 0xA0, 0xCE,
|
||||
0x2F, 0xCC, 0x24, 0x6B, 0x90, 0x77, 0xDE, 0xA2, 0x68, 0xA6, 0x52, 0x12,
|
||||
0xA2, 0x03, 0x9D, 0x20,
|
||||
};
|
||||
|
||||
DSA *
|
||||
get_dsa512(void)
|
||||
{
|
||||
return get_dsa(dsa512_priv, sizeof(dsa512_priv),
|
||||
dsa512_pub, sizeof(dsa512_pub), dsa512_p, sizeof(dsa512_p),
|
||||
dsa512_q, sizeof(dsa512_q), dsa512_g, sizeof(dsa512_g));
|
||||
}
|
||||
|
||||
static const unsigned char dsa1024_priv[] = {
|
||||
0x7d, 0x21, 0xda, 0xbb, 0x62, 0x15, 0x47, 0x36, 0x07, 0x67, 0x12, 0xe8,
|
||||
0x8c, 0xaa, 0x1c, 0xcd, 0x38, 0x12, 0x61, 0x18,
|
||||
};
|
||||
|
||||
static const unsigned char dsa1024_pub[] = {
|
||||
0x3c, 0x4e, 0x9c, 0x2a, 0x7f, 0x16, 0xc1, 0x25, 0xeb, 0xac, 0x78, 0x63,
|
||||
0x90, 0x14, 0x8c, 0x8b, 0xf4, 0x68, 0x43, 0x3c, 0x2d, 0xee, 0x65, 0x50,
|
||||
0x7d, 0x9c, 0x8f, 0x8c, 0x8a, 0x51, 0xd6, 0x11, 0x2b, 0x99, 0xaf, 0x1e,
|
||||
0x90, 0x97, 0xb5, 0xd3, 0xa6, 0x20, 0x25, 0xd6, 0xfe, 0x43, 0x02, 0xd5,
|
||||
0x91, 0x7d, 0xa7, 0x8c, 0xdb, 0xc9, 0x85, 0xa3, 0x36, 0x48, 0xf7, 0x68,
|
||||
0xaa, 0x60, 0xb1, 0xf7, 0x05, 0x68, 0x3a, 0xa3, 0x3f, 0xd3, 0x19, 0x82,
|
||||
0xd8, 0x82, 0x7a, 0x77, 0xfb, 0xef, 0xf4, 0x15, 0x0a, 0xeb, 0x06, 0x04,
|
||||
0x7f, 0x53, 0x07, 0x0c, 0xbc, 0xcb, 0x2d, 0x83, 0xdb, 0x3e, 0xd1, 0x28,
|
||||
0xa5, 0xa1, 0x31, 0xe0, 0x67, 0xfa, 0x50, 0xde, 0x9b, 0x07, 0x83, 0x7e,
|
||||
0x2c, 0x0b, 0xc3, 0x13, 0x50, 0x61, 0xe5, 0xad, 0xbd, 0x36, 0xb8, 0x97,
|
||||
0x4e, 0x40, 0x7d, 0xe8, 0x83, 0x0d, 0xbc, 0x4b
|
||||
};
|
||||
|
||||
static const unsigned char dsa1024_p[] = {
|
||||
0xA7, 0x3F, 0x6E, 0x85, 0xBF, 0x41, 0x6A, 0x29, 0x7D, 0xF0, 0x9F, 0x47,
|
||||
0x19, 0x30, 0x90, 0x9A, 0x09, 0x1D, 0xDA, 0x6A, 0x33, 0x1E, 0xC5, 0x3D,
|
||||
0x86, 0x96, 0xB3, 0x15, 0xE0, 0x53, 0x2E, 0x8F, 0xE0, 0x59, 0x82, 0x73,
|
||||
0x90, 0x3E, 0x75, 0x31, 0x99, 0x47, 0x7A, 0x52, 0xFB, 0x85, 0xE4, 0xD9,
|
||||
0xA6, 0x7B, 0x38, 0x9B, 0x68, 0x8A, 0x84, 0x9B, 0x87, 0xC6, 0x1E, 0xB5,
|
||||
0x7E, 0x86, 0x4B, 0x53, 0x5B, 0x59, 0xCF, 0x71, 0x65, 0x19, 0x88, 0x6E,
|
||||
0xCE, 0x66, 0xAE, 0x6B, 0x88, 0x36, 0xFB, 0xEC, 0x28, 0xDC, 0xC2, 0xD7,
|
||||
0xA5, 0xBB, 0xE5, 0x2C, 0x39, 0x26, 0x4B, 0xDA, 0x9A, 0x70, 0x18, 0x95,
|
||||
0x37, 0x95, 0x10, 0x56, 0x23, 0xF6, 0x15, 0xED, 0xBA, 0x04, 0x5E, 0xDE,
|
||||
0x39, 0x4F, 0xFD, 0xB7, 0x43, 0x1F, 0xB5, 0xA4, 0x65, 0x6F, 0xCD, 0x80,
|
||||
0x11, 0xE4, 0x70, 0x95, 0x5B, 0x50, 0xCD, 0x49,
|
||||
};
|
||||
|
||||
static const unsigned char dsa1024_q[] = {
|
||||
0xF7, 0x07, 0x31, 0xED, 0xFA, 0x6C, 0x06, 0x03, 0xD5, 0x85, 0x8A, 0x1C,
|
||||
0xAC, 0x9C, 0x65, 0xE7, 0x50, 0x66, 0x65, 0x6F,
|
||||
};
|
||||
|
||||
static const unsigned char dsa1024_g[] = {
|
||||
0x4D, 0xDF, 0x4C, 0x03, 0xA6, 0x91, 0x8A, 0xF5, 0x19, 0x6F, 0x50, 0x46,
|
||||
0x25, 0x99, 0xE5, 0x68, 0x6F, 0x30, 0xE3, 0x69, 0xE1, 0xE5, 0xB3, 0x5D,
|
||||
0x98, 0xBB, 0x28, 0x86, 0x48, 0xFC, 0xDE, 0x99, 0x04, 0x3F, 0x5F, 0x88,
|
||||
0x0C, 0x9C, 0x73, 0x24, 0x0D, 0x20, 0x5D, 0xB9, 0x2A, 0x9A, 0x3F, 0x18,
|
||||
0x96, 0x27, 0xE4, 0x62, 0x87, 0xC1, 0x7B, 0x74, 0x62, 0x53, 0xFC, 0x61,
|
||||
0x27, 0xA8, 0x7A, 0x91, 0x09, 0x9D, 0xB6, 0xF1, 0x4D, 0x9C, 0x54, 0x0F,
|
||||
0x58, 0x06, 0xEE, 0x49, 0x74, 0x07, 0xCE, 0x55, 0x7E, 0x23, 0xCE, 0x16,
|
||||
0xF6, 0xCA, 0xDC, 0x5A, 0x61, 0x01, 0x7E, 0xC9, 0x71, 0xB5, 0x4D, 0xF6,
|
||||
0xDC, 0x34, 0x29, 0x87, 0x68, 0xF6, 0x5E, 0x20, 0x93, 0xB3, 0xDB, 0xF5,
|
||||
0xE4, 0x09, 0x6C, 0x41, 0x17, 0x95, 0x92, 0xEB, 0x01, 0xB5, 0x73, 0xA5,
|
||||
0x6A, 0x7E, 0xD8, 0x32, 0xED, 0x0E, 0x02, 0xB8,
|
||||
};
|
||||
|
||||
DSA *
|
||||
get_dsa1024(void)
|
||||
{
|
||||
return get_dsa(dsa1024_priv, sizeof(dsa1024_priv),
|
||||
dsa1024_pub, sizeof(dsa1024_pub), dsa1024_p, sizeof(dsa1024_p),
|
||||
dsa1024_q, sizeof(dsa1024_q), dsa1024_g, sizeof(dsa1024_g));
|
||||
}
|
||||
|
||||
static const unsigned char dsa2048_priv[] = {
|
||||
0x32, 0x67, 0x92, 0xf6, 0xc4, 0xe2, 0xe2, 0xe8, 0xa0, 0x8b, 0x6b, 0x45,
|
||||
0x0c, 0x8a, 0x76, 0xb0, 0xee, 0xcf, 0x91, 0xa7,
|
||||
};
|
||||
|
||||
static const unsigned char dsa2048_pub[] = {
|
||||
0x17, 0x8f, 0xa8, 0x11, 0x84, 0x92, 0xec, 0x83, 0x47, 0xc7, 0x6a, 0xb0,
|
||||
0x92, 0xaf, 0x5a, 0x20, 0x37, 0xa3, 0x64, 0x79, 0xd2, 0xd0, 0x3d, 0xcd,
|
||||
0xe0, 0x61, 0x88, 0x88, 0x21, 0xcc, 0x74, 0x5d, 0xce, 0x4c, 0x51, 0x47,
|
||||
0xf0, 0xc5, 0x5c, 0x4c, 0x82, 0x7a, 0xaf, 0x72, 0xad, 0xb9, 0xe0, 0x53,
|
||||
0xf2, 0x78, 0xb7, 0xf0, 0xb5, 0x48, 0x7f, 0x8a, 0x3a, 0x18, 0xd1, 0x9f,
|
||||
0x8b, 0x7d, 0xa5, 0x47, 0xb7, 0x95, 0xab, 0x98, 0xf8, 0x7b, 0x74, 0x50,
|
||||
0x56, 0x8e, 0x57, 0xf0, 0xee, 0xf5, 0xb7, 0xba, 0xab, 0x85, 0x86, 0xf9,
|
||||
0x2b, 0xef, 0x41, 0x56, 0xa0, 0xa4, 0x9f, 0xb7, 0x38, 0x00, 0x46, 0x0a,
|
||||
0xa6, 0xf1, 0xfc, 0x1f, 0xd8, 0x4e, 0x85, 0x44, 0x92, 0x43, 0x21, 0x5d,
|
||||
0x6e, 0xcc, 0xc2, 0xcb, 0x26, 0x31, 0x0d, 0x21, 0xc4, 0xbd, 0x8d, 0x24,
|
||||
0xbc, 0xd9, 0x18, 0x19, 0xd7, 0xdc, 0xf1, 0xe7, 0x93, 0x50, 0x48, 0x03,
|
||||
0x2c, 0xae, 0x2e, 0xe7, 0x49, 0x88, 0x5f, 0x93, 0x57, 0x27, 0x99, 0x36,
|
||||
0xb4, 0x20, 0xab, 0xfc, 0xa7, 0x2b, 0xf2, 0xd9, 0x98, 0xd7, 0xd4, 0x34,
|
||||
0x9d, 0x96, 0x50, 0x58, 0x9a, 0xea, 0x54, 0xf3, 0xee, 0xf5, 0x63, 0x14,
|
||||
0xee, 0x85, 0x83, 0x74, 0x76, 0xe1, 0x52, 0x95, 0xc3, 0xf7, 0xeb, 0x04,
|
||||
0x04, 0x7b, 0xa7, 0x28, 0x1b, 0xcc, 0xea, 0x4a, 0x4e, 0x84, 0xda, 0xd8,
|
||||
0x9c, 0x79, 0xd8, 0x9b, 0x66, 0x89, 0x2f, 0xcf, 0xac, 0xd7, 0x79, 0xf9,
|
||||
0xa9, 0xd8, 0x45, 0x13, 0x78, 0xb9, 0x00, 0x14, 0xc9, 0x7e, 0x22, 0x51,
|
||||
0x86, 0x67, 0xb0, 0x9f, 0x26, 0x11, 0x23, 0xc8, 0x38, 0xd7, 0x70, 0x1d,
|
||||
0x15, 0x8e, 0x4d, 0x4f, 0x95, 0x97, 0x40, 0xa1, 0xc2, 0x7e, 0x01, 0x18,
|
||||
0x72, 0xf4, 0x10, 0xe6, 0x8d, 0x52, 0x16, 0x7f, 0xf2, 0xc9, 0xf8, 0x33,
|
||||
0x8b, 0x33, 0xb7, 0xce,
|
||||
};
|
||||
|
||||
static const unsigned char dsa2048_p[] = {
|
||||
0xA0, 0x25, 0xFA, 0xAD, 0xF4, 0x8E, 0xB9, 0xE5, 0x99, 0xF3, 0x5D, 0x6F,
|
||||
0x4F, 0x83, 0x34, 0xE2, 0x7E, 0xCF, 0x6F, 0xBF, 0x30, 0xAF, 0x6F, 0x81,
|
||||
0xEB, 0xF8, 0xC4, 0x13, 0xD9, 0xA0, 0x5D, 0x8B, 0x5C, 0x8E, 0xDC, 0xC2,
|
||||
0x1D, 0x0B, 0x41, 0x32, 0xB0, 0x1F, 0xFE, 0xEF, 0x0C, 0xC2, 0xA2, 0x7E,
|
||||
0x68, 0x5C, 0x28, 0x21, 0xE9, 0xF5, 0xB1, 0x58, 0x12, 0x63, 0x4C, 0x19,
|
||||
0x4E, 0xFF, 0x02, 0x4B, 0x92, 0xED, 0xD2, 0x07, 0x11, 0x4D, 0x8C, 0x58,
|
||||
0x16, 0x5C, 0x55, 0x8E, 0xAD, 0xA3, 0x67, 0x7D, 0xB9, 0x86, 0x6E, 0x0B,
|
||||
0xE6, 0x54, 0x6F, 0x40, 0xAE, 0x0E, 0x67, 0x4C, 0xF9, 0x12, 0x5B, 0x3C,
|
||||
0x08, 0x7A, 0xF7, 0xFC, 0x67, 0x86, 0x69, 0xE7, 0x0A, 0x94, 0x40, 0xBF,
|
||||
0x8B, 0x76, 0xFE, 0x26, 0xD1, 0xF2, 0xA1, 0x1A, 0x84, 0xA1, 0x43, 0x56,
|
||||
0x28, 0xBC, 0x9A, 0x5F, 0xD7, 0x3B, 0x69, 0x89, 0x8A, 0x36, 0x2C, 0x51,
|
||||
0xDF, 0x12, 0x77, 0x2F, 0x57, 0x7B, 0xA0, 0xAA, 0xDD, 0x7F, 0xA1, 0x62,
|
||||
0x3B, 0x40, 0x7B, 0x68, 0x1A, 0x8F, 0x0D, 0x38, 0xBB, 0x21, 0x5D, 0x18,
|
||||
0xFC, 0x0F, 0x46, 0xF7, 0xA3, 0xB0, 0x1D, 0x23, 0xC3, 0xD2, 0xC7, 0x72,
|
||||
0x51, 0x18, 0xDF, 0x46, 0x95, 0x79, 0xD9, 0xBD, 0xB5, 0x19, 0x02, 0x2C,
|
||||
0x87, 0xDC, 0xE7, 0x57, 0x82, 0x7E, 0xF1, 0x8B, 0x06, 0x3D, 0x00, 0xA5,
|
||||
0x7B, 0x6B, 0x26, 0x27, 0x91, 0x0F, 0x6A, 0x77, 0xE4, 0xD5, 0x04, 0xE4,
|
||||
0x12, 0x2C, 0x42, 0xFF, 0xD2, 0x88, 0xBB, 0xD3, 0x92, 0xA0, 0xF9, 0xC8,
|
||||
0x51, 0x64, 0x14, 0x5C, 0xD8, 0xF9, 0x6C, 0x47, 0x82, 0xB4, 0x1C, 0x7F,
|
||||
0x09, 0xB8, 0xF0, 0x25, 0x83, 0x1D, 0x3F, 0x3F, 0x05, 0xB3, 0x21, 0x0A,
|
||||
0x5D, 0xA7, 0xD8, 0x54, 0xC3, 0x65, 0x7D, 0xC3, 0xB0, 0x1D, 0xBF, 0xAE,
|
||||
0xF8, 0x68, 0xCF, 0x9B,
|
||||
};
|
||||
|
||||
static const unsigned char dsa2048_q[] = {
|
||||
0x97, 0xE7, 0x33, 0x4D, 0xD3, 0x94, 0x3E, 0x0B, 0xDB, 0x62, 0x74, 0xC6,
|
||||
0xA1, 0x08, 0xDD, 0x19, 0xA3, 0x75, 0x17, 0x1B,
|
||||
};
|
||||
|
||||
static const unsigned char dsa2048_g[] = {
|
||||
0x2C, 0x78, 0x16, 0x59, 0x34, 0x63, 0xF4, 0xF3, 0x92, 0xFC, 0xB5, 0xA5,
|
||||
0x4F, 0x13, 0xDE, 0x2F, 0x1C, 0xA4, 0x3C, 0xAE, 0xAD, 0x38, 0x3F, 0x7E,
|
||||
0x90, 0xBF, 0x96, 0xA6, 0xAE, 0x25, 0x90, 0x72, 0xF5, 0x8E, 0x80, 0x0C,
|
||||
0x39, 0x1C, 0xD9, 0xEC, 0xBA, 0x90, 0x5B, 0x3A, 0xE8, 0x58, 0x6C, 0x9E,
|
||||
0x30, 0x42, 0x37, 0x02, 0x31, 0x82, 0xBC, 0x6A, 0xDF, 0x6A, 0x09, 0x29,
|
||||
0xE3, 0xC0, 0x46, 0xD1, 0xCB, 0x85, 0xEC, 0x0C, 0x30, 0x5E, 0xEA, 0xC8,
|
||||
0x39, 0x8E, 0x22, 0x9F, 0x22, 0x10, 0xD2, 0x34, 0x61, 0x68, 0x37, 0x3D,
|
||||
0x2E, 0x4A, 0x5B, 0x9A, 0xF5, 0xC1, 0x48, 0xC6, 0xF6, 0xDC, 0x63, 0x1A,
|
||||
0xD3, 0x96, 0x64, 0xBA, 0x34, 0xC9, 0xD1, 0xA0, 0xD1, 0xAE, 0x6C, 0x2F,
|
||||
0x48, 0x17, 0x93, 0x14, 0x43, 0xED, 0xF0, 0x21, 0x30, 0x19, 0xC3, 0x1B,
|
||||
0x5F, 0xDE, 0xA3, 0xF0, 0x70, 0x78, 0x18, 0xE1, 0xA8, 0xE4, 0xEE, 0x2E,
|
||||
0x00, 0xA5, 0xE4, 0xB3, 0x17, 0xC8, 0x0C, 0x7D, 0x6E, 0x42, 0xDC, 0xB7,
|
||||
0x46, 0x00, 0x36, 0x4D, 0xD4, 0x46, 0xAA, 0x3D, 0x3C, 0x46, 0x89, 0x40,
|
||||
0xBF, 0x1D, 0x84, 0x77, 0x0A, 0x75, 0xF3, 0x87, 0x1D, 0x08, 0x4C, 0xA6,
|
||||
0xD1, 0xA9, 0x1C, 0x1E, 0x12, 0x1E, 0xE1, 0xC7, 0x30, 0x28, 0x76, 0xA5,
|
||||
0x7F, 0x6C, 0x85, 0x96, 0x2B, 0x6F, 0xDB, 0x80, 0x66, 0x26, 0xAE, 0xF5,
|
||||
0x93, 0xC7, 0x8E, 0xAE, 0x9A, 0xED, 0xE4, 0xCA, 0x04, 0xEA, 0x3B, 0x72,
|
||||
0xEF, 0xDC, 0x87, 0xED, 0x0D, 0xA5, 0x4C, 0x4A, 0xDD, 0x71, 0x22, 0x64,
|
||||
0x59, 0x69, 0x4E, 0x8E, 0xBF, 0x43, 0xDC, 0xAB, 0x8E, 0x66, 0xBB, 0x01,
|
||||
0xB6, 0xF4, 0xE7, 0xFD, 0xD2, 0xAD, 0x9F, 0x36, 0xC1, 0xA0, 0x29, 0x99,
|
||||
0xD1, 0x96, 0x70, 0x59, 0x06, 0x78, 0x35, 0xBD, 0x65, 0x55, 0x52, 0x9E,
|
||||
0xF8, 0xB2, 0xE5, 0x38,
|
||||
};
|
||||
|
||||
DSA *
|
||||
get_dsa2048(void)
|
||||
{
|
||||
return get_dsa(dsa2048_priv, sizeof(dsa2048_priv),
|
||||
dsa2048_pub, sizeof(dsa2048_pub), dsa2048_p, sizeof(dsa2048_p),
|
||||
dsa2048_q, sizeof(dsa2048_q), dsa2048_g, sizeof(dsa2048_g));
|
||||
}
|
||||
|
||||
DSA *
|
||||
get_dsa(const unsigned char *priv, size_t priv_size,
|
||||
const unsigned char *pub, size_t pub_size,
|
||||
const unsigned char *p_char, size_t p_size,
|
||||
const unsigned char *q_char, size_t q_size,
|
||||
const unsigned char *g_char, size_t g_size)
|
||||
{
|
||||
DSA *dsa;
|
||||
BIGNUM *priv_key = NULL, *pub_key = NULL;
|
||||
BIGNUM *p = NULL, *q = NULL, *g = NULL;
|
||||
|
||||
if ((dsa = DSA_new()) == NULL)
|
||||
return (NULL);
|
||||
|
||||
priv_key = BN_bin2bn(priv, priv_size, NULL);
|
||||
pub_key = BN_bin2bn(pub, pub_size, NULL);
|
||||
if (priv_key == NULL || pub_key == NULL)
|
||||
goto err;
|
||||
|
||||
if (!DSA_set0_key(dsa, pub_key, priv_key))
|
||||
goto err;
|
||||
pub_key = NULL;
|
||||
priv_key = NULL;
|
||||
|
||||
p = BN_bin2bn(p_char, p_size, NULL);
|
||||
q = BN_bin2bn(q_char, q_size, NULL);
|
||||
g = BN_bin2bn(g_char, g_size, NULL);
|
||||
if (p == NULL || q == NULL || g == NULL)
|
||||
goto err;
|
||||
|
||||
if (!DSA_set0_pqg(dsa, p, q, g))
|
||||
goto err;
|
||||
p = NULL;
|
||||
q = NULL;
|
||||
g = NULL;
|
||||
|
||||
return dsa;
|
||||
|
||||
err:
|
||||
DSA_free(dsa);
|
||||
BN_free(priv_key);
|
||||
BN_free(pub_key);
|
||||
BN_free(p);
|
||||
BN_free(q);
|
||||
BN_free(g);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -1,517 +0,0 @@
|
||||
/* $OpenBSD: testrsa.h,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
static unsigned char test512[] = {
|
||||
0x30, 0x82, 0x01, 0x3a, 0x02, 0x01, 0x00, 0x02, 0x41, 0x00,
|
||||
0xd6, 0x33, 0xb9, 0xc8, 0xfb, 0x4f, 0x3c, 0x7d, 0xc0, 0x01,
|
||||
0x86, 0xd0, 0xe7, 0xa0, 0x55, 0xf2, 0x95, 0x93, 0xcc, 0x4f,
|
||||
0xb7, 0x5b, 0x67, 0x5b, 0x94, 0x68, 0xc9, 0x34, 0x15, 0xde,
|
||||
0xa5, 0x2e, 0x1c, 0x33, 0xc2, 0x6e, 0xfc, 0x34, 0x5e, 0x71,
|
||||
0x13, 0xb7, 0xd6, 0xee, 0xd8, 0xa5, 0x65, 0x05, 0x72, 0x87,
|
||||
0xa8, 0xb0, 0x77, 0xfe, 0x57, 0xf5, 0xfc, 0x5f, 0x55, 0x83,
|
||||
0x87, 0xdd, 0x57, 0x49, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
|
||||
0x41, 0x00, 0xa7, 0xf7, 0x91, 0xc5, 0x0f, 0x84, 0x57, 0xdc,
|
||||
0x07, 0xf7, 0x6a, 0x7f, 0x60, 0x52, 0xb3, 0x72, 0xf1, 0x66,
|
||||
0x1f, 0x7d, 0x97, 0x3b, 0x9e, 0xb6, 0x0a, 0x8f, 0x8c, 0xcf,
|
||||
0x42, 0x23, 0x00, 0x04, 0xd4, 0x28, 0x0e, 0x1c, 0x90, 0xc4,
|
||||
0x11, 0x25, 0x25, 0xa5, 0x93, 0xa5, 0x2f, 0x70, 0x02, 0xdf,
|
||||
0x81, 0x9c, 0x49, 0x03, 0xa0, 0xf8, 0x6d, 0x54, 0x2e, 0x26,
|
||||
0xde, 0xaa, 0x85, 0x59, 0xa8, 0x31, 0x02, 0x21, 0x00, 0xeb,
|
||||
0x47, 0xd7, 0x3b, 0xf6, 0xc3, 0xdd, 0x5a, 0x46, 0xc5, 0xb9,
|
||||
0x2b, 0x9a, 0xa0, 0x09, 0x8f, 0xa6, 0xfb, 0xf3, 0x78, 0x7a,
|
||||
0x33, 0x70, 0x9d, 0x0f, 0x42, 0x6b, 0x13, 0x68, 0x24, 0xd3,
|
||||
0x15, 0x02, 0x21, 0x00, 0xe9, 0x10, 0xb0, 0xb3, 0x0d, 0xe2,
|
||||
0x82, 0x68, 0x77, 0x8a, 0x6e, 0x7c, 0xda, 0xbc, 0x3e, 0x53,
|
||||
0x83, 0xfb, 0xd6, 0x22, 0xe7, 0xb5, 0xae, 0x6e, 0x80, 0xda,
|
||||
0x00, 0x55, 0x97, 0xc1, 0xd0, 0x65, 0x02, 0x20, 0x4c, 0xf8,
|
||||
0x73, 0xb1, 0x6a, 0x49, 0x29, 0x61, 0x1f, 0x46, 0x10, 0x0d,
|
||||
0xf3, 0xc7, 0xe7, 0x58, 0xd7, 0x88, 0x15, 0x5e, 0x94, 0x9b,
|
||||
0xbf, 0x7b, 0xa2, 0x42, 0x58, 0x45, 0x41, 0x0c, 0xcb, 0x01,
|
||||
0x02, 0x20, 0x12, 0x11, 0xba, 0x31, 0x57, 0x9d, 0x3d, 0x11,
|
||||
0x0e, 0x5b, 0x8c, 0x2f, 0x5f, 0xe2, 0x02, 0x4f, 0x05, 0x47,
|
||||
0x8c, 0x15, 0x8e, 0xb3, 0x56, 0x3f, 0xb8, 0xfb, 0xad, 0xd4,
|
||||
0xf4, 0xfc, 0x10, 0xc5, 0x02, 0x20, 0x18, 0xa1, 0x29, 0x99,
|
||||
0x5b, 0xd9, 0xc8, 0xd4, 0xfc, 0x49, 0x7a, 0x2a, 0x21, 0x2c,
|
||||
0x49, 0xe4, 0x4f, 0xeb, 0xef, 0x51, 0xf1, 0xab, 0x6d, 0xfb,
|
||||
0x4b, 0x14, 0xe9, 0x4b, 0x52, 0xb5, 0x82, 0x2c,
|
||||
};
|
||||
|
||||
static unsigned char test1024[] = {
|
||||
0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81,
|
||||
0x00, 0xdc, 0x98, 0x43, 0xe8, 0x3d, 0x43, 0x5b, 0xe4, 0x05,
|
||||
0xcd, 0xd0, 0xa9, 0x3e, 0xcb, 0x83, 0x75, 0xf6, 0xb5, 0xa5,
|
||||
0x9f, 0x6b, 0xe9, 0x34, 0x41, 0x29, 0x18, 0xfa, 0x6a, 0x55,
|
||||
0x4d, 0x70, 0xfc, 0xec, 0xae, 0x87, 0x38, 0x0a, 0x20, 0xa9,
|
||||
0xc0, 0x45, 0x77, 0x6e, 0x57, 0x60, 0x57, 0xf4, 0xed, 0x96,
|
||||
0x22, 0xcb, 0x8f, 0xe1, 0x33, 0x3a, 0x17, 0x1f, 0xed, 0x37,
|
||||
0xa5, 0x6f, 0xeb, 0xa6, 0xbc, 0x12, 0x80, 0x1d, 0x53, 0xbd,
|
||||
0x70, 0xeb, 0x21, 0x76, 0x3e, 0xc9, 0x2f, 0x1a, 0x45, 0x24,
|
||||
0x82, 0xff, 0xcd, 0x59, 0x32, 0x06, 0x2e, 0x12, 0x3b, 0x23,
|
||||
0x78, 0xed, 0x12, 0x3d, 0xe0, 0x8d, 0xf9, 0x67, 0x4f, 0x37,
|
||||
0x4e, 0x47, 0x02, 0x4c, 0x2d, 0xc0, 0x4f, 0x1f, 0xb3, 0x94,
|
||||
0xe1, 0x41, 0x2e, 0x2d, 0x90, 0x10, 0xfc, 0x82, 0x91, 0x8b,
|
||||
0x0f, 0x22, 0xd4, 0xf2, 0xfc, 0x2c, 0xab, 0x53, 0x55, 0x02,
|
||||
0x03, 0x01, 0x00, 0x01, 0x02, 0x81, 0x80, 0x2b, 0xcc, 0x3f,
|
||||
0x8f, 0x58, 0xba, 0x8b, 0x00, 0x16, 0xf6, 0xea, 0x3a, 0xf0,
|
||||
0x30, 0xd0, 0x05, 0x17, 0xda, 0xb0, 0xeb, 0x9a, 0x2d, 0x4f,
|
||||
0x26, 0xb0, 0xd6, 0x38, 0xc1, 0xeb, 0xf5, 0xd8, 0x3d, 0x1f,
|
||||
0x70, 0xf7, 0x7f, 0xf4, 0xe2, 0xcf, 0x51, 0x51, 0x79, 0x88,
|
||||
0xfa, 0xe8, 0x32, 0x0e, 0x7b, 0x2d, 0x97, 0xf2, 0xfa, 0xba,
|
||||
0x27, 0xc5, 0x9c, 0xd9, 0xc5, 0xeb, 0x8a, 0x79, 0x52, 0x3c,
|
||||
0x64, 0x34, 0x7d, 0xc2, 0xcf, 0x28, 0xc7, 0x4e, 0xd5, 0x43,
|
||||
0x0b, 0xd1, 0xa6, 0xca, 0x6d, 0x03, 0x2d, 0x72, 0x23, 0xbc,
|
||||
0x6d, 0x05, 0xfa, 0x16, 0x09, 0x2f, 0x2e, 0x5c, 0xb6, 0xee,
|
||||
0x74, 0xdd, 0xd2, 0x48, 0x8e, 0x36, 0x0c, 0x06, 0x3d, 0x4d,
|
||||
0xe5, 0x10, 0x82, 0xeb, 0x6a, 0xf3, 0x4b, 0x9f, 0xd6, 0xed,
|
||||
0x11, 0xb1, 0x6e, 0xec, 0xf4, 0xfe, 0x8e, 0x75, 0x94, 0x20,
|
||||
0x2f, 0xcb, 0xac, 0x46, 0xf1, 0x02, 0x41, 0x00, 0xf9, 0x8c,
|
||||
0xa3, 0x85, 0xb1, 0xdd, 0x29, 0xaf, 0x65, 0xc1, 0x33, 0xf3,
|
||||
0x95, 0xc5, 0x52, 0x68, 0x0b, 0xd4, 0xf1, 0xe5, 0x0e, 0x02,
|
||||
0x9f, 0x4f, 0xfa, 0x77, 0xdc, 0x46, 0x9e, 0xc7, 0xa6, 0xe4,
|
||||
0x16, 0x29, 0xda, 0xb0, 0x07, 0xcf, 0x5b, 0xa9, 0x12, 0x8a,
|
||||
0xdd, 0x63, 0x0a, 0xde, 0x2e, 0x8c, 0x66, 0x8b, 0x8c, 0xdc,
|
||||
0x19, 0xa3, 0x7e, 0xf4, 0x3b, 0xd0, 0x1a, 0x8c, 0xa4, 0xc2,
|
||||
0xe1, 0xd3, 0x02, 0x41, 0x00, 0xe2, 0x4c, 0x05, 0xf2, 0x04,
|
||||
0x86, 0x4e, 0x61, 0x43, 0xdb, 0xb0, 0xb9, 0x96, 0x86, 0x52,
|
||||
0x2c, 0xca, 0x8d, 0x7b, 0xab, 0x0b, 0x13, 0x0d, 0x7e, 0x38,
|
||||
0x5b, 0xe2, 0x2e, 0x7b, 0x0e, 0xe7, 0x19, 0x99, 0x38, 0xe7,
|
||||
0xf2, 0x21, 0xbd, 0x85, 0x85, 0xe3, 0xfd, 0x28, 0x77, 0x20,
|
||||
0x31, 0x71, 0x2c, 0xd0, 0xff, 0xfb, 0x2e, 0xaf, 0x85, 0xb4,
|
||||
0x86, 0xca, 0xf3, 0xbb, 0xca, 0xaa, 0x0f, 0x95, 0x37, 0x02,
|
||||
0x40, 0x0e, 0x41, 0x9a, 0x95, 0xe8, 0xb3, 0x59, 0xce, 0x4b,
|
||||
0x61, 0xde, 0x35, 0xec, 0x38, 0x79, 0x9c, 0xb8, 0x10, 0x52,
|
||||
0x41, 0x63, 0xab, 0x82, 0xae, 0x6f, 0x00, 0xa9, 0xf4, 0xde,
|
||||
0xdd, 0x49, 0x0b, 0x7e, 0xb8, 0xa5, 0x65, 0xa9, 0x0c, 0x8f,
|
||||
0x8f, 0xf9, 0x1f, 0x35, 0xc6, 0x92, 0xb8, 0x5e, 0xb0, 0x66,
|
||||
0xab, 0x52, 0x40, 0xc0, 0xb6, 0x36, 0x6a, 0x7d, 0x80, 0x46,
|
||||
0x04, 0x02, 0xe5, 0x9f, 0x41, 0x02, 0x41, 0x00, 0xc0, 0xad,
|
||||
0xcc, 0x4e, 0x21, 0xee, 0x1d, 0x24, 0x91, 0xfb, 0xa7, 0x80,
|
||||
0x8d, 0x9a, 0xb6, 0xb3, 0x2e, 0x8f, 0xc2, 0xe1, 0x82, 0xdf,
|
||||
0x69, 0x18, 0xb4, 0x71, 0xff, 0xa6, 0x65, 0xde, 0xed, 0x84,
|
||||
0x8d, 0x42, 0xb7, 0xb3, 0x21, 0x69, 0x56, 0x1c, 0x07, 0x60,
|
||||
0x51, 0x29, 0x04, 0xff, 0x34, 0x06, 0xdd, 0xb9, 0x67, 0x2c,
|
||||
0x7c, 0x04, 0x93, 0x0e, 0x46, 0x15, 0xbb, 0x2a, 0xb7, 0x1b,
|
||||
0xe7, 0x87, 0x02, 0x40, 0x78, 0xda, 0x5d, 0x07, 0x51, 0x0c,
|
||||
0x16, 0x7a, 0x9f, 0x29, 0x20, 0x84, 0x0d, 0x42, 0xfa, 0xd7,
|
||||
0x00, 0xd8, 0x77, 0x7e, 0xb0, 0xb0, 0x6b, 0xd6, 0x5b, 0x53,
|
||||
0xb8, 0x9b, 0x7a, 0xcd, 0xc7, 0x2b, 0xb8, 0x6a, 0x63, 0xa9,
|
||||
0xfb, 0x6f, 0xa4, 0x72, 0xbf, 0x4c, 0x5d, 0x00, 0x14, 0xba,
|
||||
0xfa, 0x59, 0x88, 0xed, 0xe4, 0xe0, 0x8c, 0xa2, 0xec, 0x14,
|
||||
0x7e, 0x2d, 0xe2, 0xf0, 0x46, 0x49, 0x95, 0x45,
|
||||
};
|
||||
|
||||
static unsigned char test2048[] = {
|
||||
0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01,
|
||||
0x01, 0x00, 0xc0, 0xc0, 0xce, 0x3e, 0x3c, 0x53, 0x67, 0x3f,
|
||||
0x4f, 0xc5, 0x2f, 0xa4, 0xc2, 0x5a, 0x2f, 0x58, 0xfd, 0x27,
|
||||
0x52, 0x6a, 0xe8, 0xcf, 0x4a, 0x73, 0x47, 0x8d, 0x25, 0x0f,
|
||||
0x5f, 0x03, 0x26, 0x78, 0xef, 0xf0, 0x22, 0x12, 0xd3, 0xde,
|
||||
0x47, 0xb2, 0x1c, 0x0b, 0x38, 0x63, 0x1a, 0x6c, 0x85, 0x7a,
|
||||
0x80, 0xc6, 0x8f, 0xa0, 0x41, 0xaf, 0x62, 0xc4, 0x67, 0x32,
|
||||
0x88, 0xf8, 0xa6, 0x9c, 0xf5, 0x23, 0x1d, 0xe4, 0xac, 0x3f,
|
||||
0x29, 0xf9, 0xec, 0xe1, 0x8b, 0x26, 0x03, 0x2c, 0xb2, 0xab,
|
||||
0xf3, 0x7d, 0xb5, 0xca, 0x49, 0xc0, 0x8f, 0x1c, 0xdf, 0x33,
|
||||
0x3a, 0x60, 0xda, 0x3c, 0xb0, 0x16, 0xf8, 0xa9, 0x12, 0x8f,
|
||||
0x64, 0xac, 0x23, 0x0c, 0x69, 0x64, 0x97, 0x5d, 0x99, 0xd4,
|
||||
0x09, 0x83, 0x9b, 0x61, 0xd3, 0xac, 0xf0, 0xde, 0xdd, 0x5e,
|
||||
0x9f, 0x44, 0x94, 0xdb, 0x3a, 0x4d, 0x97, 0xe8, 0x52, 0x29,
|
||||
0xf7, 0xdb, 0x94, 0x07, 0x45, 0x90, 0x78, 0x1e, 0x31, 0x0b,
|
||||
0x80, 0xf7, 0x57, 0xad, 0x1c, 0x79, 0xc5, 0xcb, 0x32, 0xb0,
|
||||
0xce, 0xcd, 0x74, 0xb3, 0xe2, 0x94, 0xc5, 0x78, 0x2f, 0x34,
|
||||
0x1a, 0x45, 0xf7, 0x8c, 0x52, 0xa5, 0xbc, 0x8d, 0xec, 0xd1,
|
||||
0x2f, 0x31, 0x3b, 0xf0, 0x49, 0x59, 0x5e, 0x88, 0x9d, 0x15,
|
||||
0x92, 0x35, 0x32, 0xc1, 0xe7, 0x61, 0xec, 0x50, 0x48, 0x7c,
|
||||
0xba, 0x05, 0xf9, 0xf8, 0xf8, 0xa7, 0x8c, 0x83, 0xe8, 0x66,
|
||||
0x5b, 0xeb, 0xfe, 0xd8, 0x4f, 0xdd, 0x6d, 0x36, 0xc0, 0xb2,
|
||||
0x90, 0x0f, 0xb8, 0x52, 0xf9, 0x04, 0x9b, 0x40, 0x2c, 0x27,
|
||||
0xd6, 0x36, 0x8e, 0xc2, 0x1b, 0x44, 0xf3, 0x92, 0xd5, 0x15,
|
||||
0x9e, 0x9a, 0xbc, 0xf3, 0x7d, 0x03, 0xd7, 0x02, 0x14, 0x20,
|
||||
0xe9, 0x10, 0x92, 0xfd, 0xf9, 0xfc, 0x8f, 0xe5, 0x18, 0xe1,
|
||||
0x95, 0xcc, 0x9e, 0x60, 0xa6, 0xfa, 0x38, 0x4d, 0x02, 0x03,
|
||||
0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x00, 0xc3, 0xc3,
|
||||
0x0d, 0xb4, 0x27, 0x90, 0x8d, 0x4b, 0xbf, 0xb8, 0x84, 0xaa,
|
||||
0xd0, 0xb8, 0xc7, 0x5d, 0x99, 0xbe, 0x55, 0xf6, 0x3e, 0x7c,
|
||||
0x49, 0x20, 0xcb, 0x8a, 0x8e, 0x19, 0x0e, 0x66, 0x24, 0xac,
|
||||
0xaf, 0x03, 0x33, 0x97, 0xeb, 0x95, 0xd5, 0x3b, 0x0f, 0x40,
|
||||
0x56, 0x04, 0x50, 0xd1, 0xe6, 0xbe, 0x84, 0x0b, 0x25, 0xd3,
|
||||
0x9c, 0xe2, 0x83, 0x6c, 0xf5, 0x62, 0x5d, 0xba, 0x2b, 0x7d,
|
||||
0x3d, 0x7a, 0x6c, 0xe1, 0xd2, 0x0e, 0x54, 0x93, 0x80, 0x01,
|
||||
0x91, 0x51, 0x09, 0xe8, 0x5b, 0x8e, 0x47, 0xbd, 0x64, 0xe4,
|
||||
0x0e, 0x03, 0x83, 0x55, 0xcf, 0x5a, 0x37, 0xf0, 0x25, 0xb5,
|
||||
0x7d, 0x21, 0xd7, 0x69, 0xdf, 0x6f, 0xc2, 0xcf, 0x10, 0xc9,
|
||||
0x8a, 0x40, 0x9f, 0x7a, 0x70, 0xc0, 0xe8, 0xe8, 0xc0, 0xe6,
|
||||
0x9a, 0x15, 0x0a, 0x8d, 0x4e, 0x46, 0xcb, 0x7a, 0xdb, 0xb3,
|
||||
0xcb, 0x83, 0x02, 0xc4, 0xf0, 0xab, 0xeb, 0x02, 0x01, 0x0e,
|
||||
0x23, 0xfc, 0x1d, 0xc4, 0xbd, 0xd4, 0xaa, 0x5d, 0x31, 0x46,
|
||||
0x99, 0xce, 0x9e, 0xf8, 0x04, 0x75, 0x10, 0x67, 0xc4, 0x53,
|
||||
0x47, 0x44, 0xfa, 0xc2, 0x25, 0x73, 0x7e, 0xd0, 0x8e, 0x59,
|
||||
0xd1, 0xb2, 0x5a, 0xf4, 0xc7, 0x18, 0x92, 0x2f, 0x39, 0xab,
|
||||
0xcd, 0xa3, 0xb5, 0xc2, 0xb9, 0xc7, 0xb9, 0x1b, 0x9f, 0x48,
|
||||
0xfa, 0x13, 0xc6, 0x98, 0x4d, 0xca, 0x84, 0x9c, 0x06, 0xca,
|
||||
0xe7, 0x89, 0x01, 0x04, 0xc4, 0x6c, 0xfd, 0x29, 0x59, 0x35,
|
||||
0xe7, 0xf3, 0xdd, 0xce, 0x64, 0x59, 0xbf, 0x21, 0x13, 0xa9,
|
||||
0x9f, 0x0e, 0xc5, 0xff, 0xbd, 0x33, 0x00, 0xec, 0xac, 0x6b,
|
||||
0x11, 0xef, 0x51, 0x5e, 0xad, 0x07, 0x15, 0xde, 0xb8, 0x5f,
|
||||
0xc6, 0xb9, 0xa3, 0x22, 0x65, 0x46, 0x83, 0x14, 0xdf, 0xd0,
|
||||
0xf1, 0x44, 0x8a, 0xe1, 0x9c, 0x23, 0x33, 0xb4, 0x97, 0x33,
|
||||
0xe6, 0x6b, 0x81, 0x02, 0x81, 0x81, 0x00, 0xec, 0x12, 0xa7,
|
||||
0x59, 0x74, 0x6a, 0xde, 0x3e, 0xad, 0xd8, 0x36, 0x80, 0x50,
|
||||
0xa2, 0xd5, 0x21, 0x81, 0x07, 0xf1, 0xd0, 0x91, 0xf2, 0x6c,
|
||||
0x12, 0x2f, 0x9d, 0x1a, 0x26, 0xf8, 0x30, 0x65, 0xdf, 0xe8,
|
||||
0xc0, 0x9b, 0x6a, 0x30, 0x98, 0x82, 0x87, 0xec, 0xa2, 0x56,
|
||||
0x87, 0x62, 0x6f, 0xe7, 0x9f, 0xf6, 0x56, 0xe6, 0x71, 0x8f,
|
||||
0x49, 0x86, 0x93, 0x5a, 0x4d, 0x34, 0x58, 0xfe, 0xd9, 0x04,
|
||||
0x13, 0xaf, 0x79, 0xb7, 0xad, 0x11, 0xd1, 0x30, 0x9a, 0x14,
|
||||
0x06, 0xa0, 0xfa, 0xb7, 0x55, 0xdc, 0x6c, 0x5a, 0x4c, 0x2c,
|
||||
0x59, 0x56, 0xf6, 0xe8, 0x9d, 0xaf, 0x0a, 0x78, 0x99, 0x06,
|
||||
0x06, 0x9e, 0xe7, 0x9c, 0x51, 0x55, 0x43, 0xfc, 0x3b, 0x6c,
|
||||
0x0b, 0xbf, 0x2d, 0x41, 0xa7, 0xaf, 0xb7, 0xe0, 0xe8, 0x28,
|
||||
0x18, 0xb4, 0x13, 0xd1, 0xe6, 0x97, 0xd0, 0x9f, 0x6a, 0x80,
|
||||
0xca, 0xdd, 0x1a, 0x7e, 0x15, 0x02, 0x81, 0x81, 0x00, 0xd1,
|
||||
0x06, 0x0c, 0x1f, 0xe3, 0xd0, 0xab, 0xd6, 0xca, 0x7c, 0xbc,
|
||||
0x7d, 0x13, 0x35, 0xce, 0x27, 0xcd, 0xd8, 0x49, 0x51, 0x63,
|
||||
0x64, 0x0f, 0xca, 0x06, 0x12, 0xfc, 0x07, 0x3e, 0xaf, 0x61,
|
||||
0x6d, 0xe2, 0x53, 0x39, 0x27, 0xae, 0xc3, 0x11, 0x9e, 0x94,
|
||||
0x01, 0x4f, 0xe3, 0xf3, 0x67, 0xf9, 0x77, 0xf9, 0xe7, 0x95,
|
||||
0x3a, 0x6f, 0xe2, 0x20, 0x73, 0x3e, 0xa4, 0x7a, 0x28, 0xd4,
|
||||
0x61, 0x97, 0xf6, 0x17, 0xa0, 0x23, 0x10, 0x2b, 0xce, 0x84,
|
||||
0x57, 0x7e, 0x25, 0x1f, 0xf4, 0xa8, 0x54, 0xd2, 0x65, 0x94,
|
||||
0xcc, 0x95, 0x0a, 0xab, 0x30, 0xc1, 0x59, 0x1f, 0x61, 0x8e,
|
||||
0xb9, 0x6b, 0xd7, 0x4e, 0xb9, 0x83, 0x43, 0x79, 0x85, 0x11,
|
||||
0xbc, 0x0f, 0xae, 0x25, 0x20, 0x05, 0xbc, 0xd2, 0x48, 0xa1,
|
||||
0x68, 0x09, 0x84, 0xf6, 0x12, 0x9a, 0x66, 0xb9, 0x2b, 0xbb,
|
||||
0x76, 0x03, 0x17, 0x46, 0x4e, 0x97, 0x59, 0x02, 0x81, 0x80,
|
||||
0x09, 0x4c, 0xfa, 0xd6, 0xe5, 0x65, 0x48, 0x78, 0x43, 0xb5,
|
||||
0x1f, 0x00, 0x93, 0x2c, 0xb7, 0x24, 0xe8, 0xc6, 0x7d, 0x5a,
|
||||
0x70, 0x45, 0x92, 0xc8, 0x6c, 0xa3, 0xcd, 0xe1, 0xf7, 0x29,
|
||||
0x40, 0xfa, 0x3f, 0x5b, 0x47, 0x44, 0x39, 0xc1, 0xe8, 0x72,
|
||||
0x9e, 0x7a, 0x0e, 0xda, 0xaa, 0xa0, 0x2a, 0x09, 0xfd, 0x54,
|
||||
0x93, 0x23, 0xaa, 0x37, 0x85, 0x5b, 0xcc, 0xd4, 0xf9, 0xd8,
|
||||
0xff, 0xc1, 0x61, 0x0d, 0xbd, 0x7e, 0x18, 0x24, 0x73, 0x6d,
|
||||
0x40, 0x72, 0xf1, 0x93, 0x09, 0x48, 0x97, 0x6c, 0x84, 0x90,
|
||||
0xa8, 0x46, 0x14, 0x01, 0x39, 0x11, 0xe5, 0x3c, 0x41, 0x27,
|
||||
0x32, 0x75, 0x24, 0xed, 0xa1, 0xd9, 0x12, 0x29, 0x8a, 0x28,
|
||||
0x71, 0x89, 0x8d, 0xca, 0x30, 0xb0, 0x01, 0xc4, 0x2f, 0x82,
|
||||
0x19, 0x14, 0x4c, 0x70, 0x1c, 0xb8, 0x23, 0x2e, 0xe8, 0x90,
|
||||
0x49, 0x97, 0x92, 0x97, 0x6b, 0x7a, 0x9d, 0xb9, 0x02, 0x81,
|
||||
0x80, 0x0f, 0x0e, 0xa1, 0x76, 0xf6, 0xa1, 0x44, 0x8f, 0xaf,
|
||||
0x7c, 0x76, 0xd3, 0x87, 0xbb, 0xbb, 0x83, 0x10, 0x88, 0x01,
|
||||
0x18, 0x14, 0xd1, 0xd3, 0x75, 0x59, 0x24, 0xaa, 0xf5, 0x16,
|
||||
0xa5, 0xe9, 0x9d, 0xd1, 0xcc, 0xee, 0xf4, 0x15, 0xd9, 0xc5,
|
||||
0x7e, 0x27, 0xe9, 0x44, 0x49, 0x06, 0x72, 0xb9, 0xfc, 0xd3,
|
||||
0x8a, 0xc4, 0x2c, 0x36, 0x7d, 0x12, 0x9b, 0x5a, 0xaa, 0xdc,
|
||||
0x85, 0xee, 0x6e, 0xad, 0x54, 0xb3, 0xf4, 0xfc, 0x31, 0xa1,
|
||||
0x06, 0x3a, 0x70, 0x57, 0x0c, 0xf3, 0x95, 0x5b, 0x3e, 0xe8,
|
||||
0xfd, 0x1a, 0x4f, 0xf6, 0x78, 0x93, 0x46, 0x6a, 0xd7, 0x31,
|
||||
0xb4, 0x84, 0x64, 0x85, 0x09, 0x38, 0x89, 0x92, 0x94, 0x1c,
|
||||
0xbf, 0xe2, 0x3c, 0x2a, 0xe0, 0xff, 0x99, 0xa3, 0xf0, 0x2b,
|
||||
0x31, 0xc2, 0x36, 0xcd, 0x60, 0xbf, 0x9d, 0x2d, 0x74, 0x32,
|
||||
0xe8, 0x9c, 0x93, 0x6e, 0xbb, 0x91, 0x7b, 0xfd, 0xd9, 0x02,
|
||||
0x81, 0x81, 0x00, 0xa2, 0x71, 0x25, 0x38, 0xeb, 0x2a, 0xe9,
|
||||
0x37, 0xcd, 0xfe, 0x44, 0xce, 0x90, 0x3f, 0x52, 0x87, 0x84,
|
||||
0x52, 0x1b, 0xae, 0x8d, 0x22, 0x94, 0xce, 0x38, 0xe6, 0x04,
|
||||
0x88, 0x76, 0x85, 0x9a, 0xd3, 0x14, 0x09, 0xe5, 0x69, 0x9a,
|
||||
0xff, 0x58, 0x92, 0x02, 0x6a, 0x7d, 0x7c, 0x1e, 0x2c, 0xfd,
|
||||
0xa8, 0xca, 0x32, 0x14, 0x4f, 0x0d, 0x84, 0x0d, 0x37, 0x43,
|
||||
0xbf, 0xe4, 0x5d, 0x12, 0xc8, 0x24, 0x91, 0x27, 0x8d, 0x46,
|
||||
0xd9, 0x54, 0x53, 0xe7, 0x62, 0x71, 0xa8, 0x2b, 0x71, 0x41,
|
||||
0x8d, 0x75, 0xf8, 0x3a, 0xa0, 0x61, 0x29, 0x46, 0xa6, 0xe5,
|
||||
0x82, 0xfa, 0x3a, 0xd9, 0x08, 0xfa, 0xfc, 0x63, 0xfd, 0x6b,
|
||||
0x30, 0xbc, 0xf4, 0x4e, 0x9e, 0x8c, 0x25, 0x0c, 0xb6, 0x55,
|
||||
0xe7, 0x3c, 0xd4, 0x4e, 0x0b, 0xfd, 0x8b, 0xc3, 0x0e, 0x1d,
|
||||
0x9c, 0x44, 0x57, 0x8f, 0x1f, 0x86, 0xf7, 0xd5, 0x1b, 0xe4,
|
||||
0x95,
|
||||
};
|
||||
|
||||
static unsigned char test4096[] = {
|
||||
0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02,
|
||||
0x01, 0x00, 0xc0, 0x71, 0xac, 0x1a, 0x13, 0x88, 0x82, 0x43,
|
||||
0x3b, 0x51, 0x57, 0x71, 0x8d, 0xb6, 0x2b, 0x82, 0x65, 0x21,
|
||||
0x53, 0x5f, 0x28, 0x29, 0x4f, 0x8d, 0x7c, 0x8a, 0xb9, 0x44,
|
||||
0xb3, 0x28, 0x41, 0x4f, 0xd3, 0xfa, 0x6a, 0xf8, 0xb9, 0x28,
|
||||
0x50, 0x39, 0x67, 0x53, 0x2c, 0x3c, 0xd7, 0xcb, 0x96, 0x41,
|
||||
0x40, 0x32, 0xbb, 0xeb, 0x70, 0xae, 0x1f, 0xb0, 0x65, 0xf7,
|
||||
0x3a, 0xd9, 0x22, 0xfd, 0x10, 0xae, 0xbd, 0x02, 0xe2, 0xdd,
|
||||
0xf3, 0xc2, 0x79, 0x3c, 0xc6, 0xfc, 0x75, 0xbb, 0xaf, 0x4e,
|
||||
0x3a, 0x36, 0xc2, 0x4f, 0xea, 0x25, 0xdf, 0x13, 0x16, 0x4b,
|
||||
0x20, 0xfe, 0x4b, 0x69, 0x16, 0xc4, 0x7f, 0x1a, 0x43, 0xa6,
|
||||
0x17, 0x1b, 0xb9, 0x0a, 0xf3, 0x09, 0x86, 0x28, 0x89, 0xcf,
|
||||
0x2c, 0xd0, 0xd4, 0x81, 0xaf, 0xc6, 0x6d, 0xe6, 0x21, 0x8d,
|
||||
0xee, 0xef, 0xea, 0xdc, 0xb7, 0xc6, 0x3b, 0x63, 0x9f, 0x0e,
|
||||
0xad, 0x89, 0x78, 0x23, 0x18, 0xbf, 0x70, 0x7e, 0x84, 0xe0,
|
||||
0x37, 0xec, 0xdb, 0x8e, 0x9c, 0x3e, 0x6a, 0x19, 0xcc, 0x99,
|
||||
0x72, 0xe6, 0xb5, 0x7d, 0x6d, 0xfa, 0xe5, 0xd3, 0xe4, 0x90,
|
||||
0xb5, 0xb2, 0xb2, 0x12, 0x70, 0x4e, 0xca, 0xf8, 0x10, 0xf8,
|
||||
0xa3, 0x14, 0xc2, 0x48, 0x19, 0xeb, 0x60, 0x99, 0xbb, 0x2a,
|
||||
0x1f, 0xb1, 0x7a, 0xb1, 0x3d, 0x24, 0xfb, 0xa0, 0x29, 0xda,
|
||||
0xbd, 0x1b, 0xd7, 0xa4, 0xbf, 0xef, 0x60, 0x2d, 0x22, 0xca,
|
||||
0x65, 0x98, 0xf1, 0xc4, 0xe1, 0xc9, 0x02, 0x6b, 0x16, 0x28,
|
||||
0x2f, 0xa1, 0xaa, 0x79, 0x00, 0xda, 0xdc, 0x7c, 0x43, 0xf7,
|
||||
0x42, 0x3c, 0xa0, 0xef, 0x68, 0xf7, 0xdf, 0xb9, 0x69, 0xfb,
|
||||
0x8e, 0x01, 0xed, 0x01, 0x42, 0xb5, 0x4e, 0x57, 0xa6, 0x26,
|
||||
0xb8, 0xd0, 0x7b, 0x56, 0x6d, 0x03, 0xc6, 0x40, 0x8c, 0x8c,
|
||||
0x2a, 0x55, 0xd7, 0x9c, 0x35, 0x00, 0x94, 0x93, 0xec, 0x03,
|
||||
0xeb, 0x22, 0xef, 0x77, 0xbb, 0x79, 0x13, 0x3f, 0x15, 0xa1,
|
||||
0x8f, 0xca, 0xdf, 0xfd, 0xd3, 0xb8, 0xe1, 0xd4, 0xcc, 0x09,
|
||||
0x3f, 0x3c, 0x2c, 0xdb, 0xd1, 0x49, 0x7f, 0x38, 0x07, 0x83,
|
||||
0x6d, 0xeb, 0x08, 0x66, 0xe9, 0x06, 0x44, 0x12, 0xac, 0x95,
|
||||
0x22, 0x90, 0x23, 0x67, 0xd4, 0x08, 0xcc, 0xf4, 0xb7, 0xdc,
|
||||
0xcc, 0x87, 0xd4, 0xac, 0x69, 0x35, 0x4c, 0xb5, 0x39, 0x36,
|
||||
0xcd, 0xa4, 0xd2, 0x95, 0xca, 0x0d, 0xc5, 0xda, 0xc2, 0xc5,
|
||||
0x22, 0x32, 0x28, 0x08, 0xe3, 0xd2, 0x8b, 0x38, 0x30, 0xdc,
|
||||
0x8c, 0x75, 0x4f, 0x6a, 0xec, 0x7a, 0xac, 0x16, 0x3e, 0xa8,
|
||||
0xd4, 0x6a, 0x45, 0xe1, 0xa8, 0x4f, 0x2e, 0x80, 0x34, 0xaa,
|
||||
0x54, 0x1b, 0x02, 0x95, 0x7d, 0x8a, 0x6d, 0xcc, 0x79, 0xca,
|
||||
0xf2, 0xa4, 0x2e, 0x8d, 0xfb, 0xfe, 0x15, 0x51, 0x10, 0x0e,
|
||||
0x4d, 0x88, 0xb1, 0xc7, 0xf4, 0x79, 0xdb, 0xf0, 0xb4, 0x56,
|
||||
0x44, 0x37, 0xca, 0x5a, 0xc1, 0x8c, 0x48, 0xac, 0xae, 0x48,
|
||||
0x80, 0x83, 0x01, 0x3f, 0xde, 0xd9, 0xd3, 0x2c, 0x51, 0x46,
|
||||
0xb1, 0x41, 0xb6, 0xc6, 0x91, 0x72, 0xf9, 0x83, 0x55, 0x1b,
|
||||
0x8c, 0xba, 0xf3, 0x73, 0xe5, 0x2c, 0x74, 0x50, 0x3a, 0xbe,
|
||||
0xc5, 0x2f, 0xa7, 0xb2, 0x6d, 0x8c, 0x9e, 0x13, 0x77, 0xa3,
|
||||
0x13, 0xcd, 0x6d, 0x8c, 0x45, 0xe1, 0xfc, 0x0b, 0xb7, 0x69,
|
||||
0xe9, 0x27, 0xbc, 0x65, 0xc3, 0xfa, 0x9b, 0xd0, 0xef, 0xfe,
|
||||
0xe8, 0x1f, 0xb3, 0x5e, 0x34, 0xf4, 0x8c, 0xea, 0xfc, 0xd3,
|
||||
0x81, 0xbf, 0x3d, 0x30, 0xb2, 0xb4, 0x01, 0xe8, 0x43, 0x0f,
|
||||
0xba, 0x02, 0x23, 0x42, 0x76, 0x82, 0x31, 0x73, 0x91, 0xed,
|
||||
0x07, 0x46, 0x61, 0x0d, 0x39, 0x83, 0x40, 0xce, 0x7a, 0xd4,
|
||||
0xdb, 0x80, 0x2c, 0x1f, 0x0d, 0xd1, 0x34, 0xd4, 0x92, 0xe3,
|
||||
0xd4, 0xf1, 0xc2, 0x01, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02,
|
||||
0x82, 0x02, 0x01, 0x00, 0x97, 0x6c, 0xda, 0x6e, 0xea, 0x4f,
|
||||
0xcf, 0xaf, 0xf7, 0x4c, 0xd9, 0xf1, 0x90, 0x00, 0x77, 0xdb,
|
||||
0xf2, 0x97, 0x76, 0x72, 0xb9, 0xb7, 0x47, 0xd1, 0x9c, 0xdd,
|
||||
0xcb, 0x4a, 0x33, 0x6e, 0xc9, 0x75, 0x76, 0xe6, 0xe4, 0xa5,
|
||||
0x31, 0x8c, 0x77, 0x13, 0xb4, 0x29, 0xcd, 0xf5, 0x52, 0x17,
|
||||
0xef, 0xf3, 0x08, 0x00, 0xe3, 0xbd, 0x2e, 0xbc, 0xd4, 0x52,
|
||||
0x88, 0xe9, 0x30, 0x75, 0x0b, 0x02, 0xf5, 0xcd, 0x89, 0x0c,
|
||||
0x6c, 0x57, 0x19, 0x27, 0x3d, 0x1e, 0x85, 0xb4, 0xc1, 0x2f,
|
||||
0x1d, 0x92, 0x00, 0x5c, 0x76, 0x29, 0x4b, 0xa4, 0xe1, 0x12,
|
||||
0xb3, 0xc8, 0x09, 0xfe, 0x0e, 0x78, 0x72, 0x61, 0xcb, 0x61,
|
||||
0x6f, 0x39, 0x91, 0x95, 0x4e, 0xd5, 0x3e, 0xc7, 0x8f, 0xb8,
|
||||
0xf6, 0x36, 0xfe, 0x9c, 0x93, 0x9a, 0x38, 0x25, 0x7a, 0xf4,
|
||||
0x4a, 0x12, 0xd4, 0xa0, 0x13, 0xbd, 0xf9, 0x1d, 0x12, 0x3e,
|
||||
0x21, 0x39, 0xfb, 0x72, 0xe0, 0x05, 0x3d, 0xc3, 0xe5, 0x50,
|
||||
0xa8, 0x5d, 0x85, 0xa3, 0xea, 0x5f, 0x1c, 0xb2, 0x3f, 0xea,
|
||||
0x6d, 0x03, 0x91, 0x55, 0xd8, 0x19, 0x0a, 0x21, 0x12, 0x16,
|
||||
0xd9, 0x12, 0xc4, 0xe6, 0x07, 0x18, 0x5b, 0x26, 0xa4, 0xae,
|
||||
0xed, 0x2b, 0xb7, 0xa6, 0xed, 0xf8, 0xad, 0xec, 0x77, 0xe6,
|
||||
0x7f, 0x4f, 0x76, 0x00, 0xc0, 0xfa, 0x15, 0x92, 0xb4, 0x2c,
|
||||
0x22, 0xc2, 0xeb, 0x6a, 0xad, 0x14, 0x05, 0xb2, 0xe5, 0x8a,
|
||||
0x9e, 0x85, 0x83, 0xcc, 0x04, 0xf1, 0x56, 0x78, 0x44, 0x5e,
|
||||
0xde, 0xe0, 0x60, 0x1a, 0x65, 0x79, 0x31, 0x23, 0x05, 0xbb,
|
||||
0x01, 0xff, 0xdd, 0x2e, 0xb7, 0xb3, 0xaa, 0x74, 0xe0, 0xa5,
|
||||
0x94, 0xaf, 0x4b, 0xde, 0x58, 0x0f, 0x55, 0xde, 0x33, 0xf6,
|
||||
0xe3, 0xd6, 0x34, 0x36, 0x57, 0xd6, 0x79, 0x91, 0x2e, 0xbe,
|
||||
0x3b, 0xd9, 0x4e, 0xb6, 0x9d, 0x21, 0x5c, 0xd3, 0x48, 0x14,
|
||||
0x7f, 0x4a, 0xc4, 0x60, 0xa9, 0x29, 0xf8, 0x53, 0x7f, 0x88,
|
||||
0x11, 0x2d, 0xb5, 0xc5, 0x2d, 0x6f, 0xee, 0x85, 0x0b, 0xf7,
|
||||
0x8d, 0x9a, 0xbe, 0xb0, 0x42, 0xf2, 0x2e, 0x71, 0xaf, 0x19,
|
||||
0x31, 0x6d, 0xec, 0xcd, 0x6f, 0x2b, 0x23, 0xdf, 0xb4, 0x40,
|
||||
0xaf, 0x2c, 0x0a, 0xc3, 0x1b, 0x7d, 0x7d, 0x03, 0x1d, 0x4b,
|
||||
0xf3, 0xb5, 0xe0, 0x85, 0xd8, 0xdf, 0x91, 0x6b, 0x0a, 0x69,
|
||||
0xf7, 0xf2, 0x69, 0x66, 0x5b, 0xf1, 0xcf, 0x46, 0x7d, 0xe9,
|
||||
0x70, 0xfa, 0x6d, 0x7e, 0x75, 0x4e, 0xa9, 0x77, 0xe6, 0x8c,
|
||||
0x02, 0xf7, 0x14, 0x4d, 0xa5, 0x41, 0x8f, 0x3f, 0xc1, 0x62,
|
||||
0x1e, 0x71, 0x5e, 0x38, 0xb4, 0xd6, 0xe6, 0xe1, 0x4b, 0xc2,
|
||||
0x2c, 0x30, 0x83, 0x81, 0x6f, 0x49, 0x2e, 0x96, 0xe6, 0xc9,
|
||||
0x9a, 0xf7, 0x5d, 0x09, 0xa0, 0x55, 0x02, 0xa5, 0x3a, 0x25,
|
||||
0x23, 0xd0, 0x92, 0xc3, 0xa3, 0xe3, 0x0e, 0x12, 0x2f, 0x4d,
|
||||
0xef, 0xf3, 0x55, 0x5a, 0xbe, 0xe6, 0x19, 0x86, 0x31, 0xab,
|
||||
0x75, 0x9a, 0xd3, 0xf0, 0x2c, 0xc5, 0x41, 0x92, 0xd9, 0x1f,
|
||||
0x5f, 0x11, 0x8c, 0x75, 0x1c, 0x63, 0xd0, 0x02, 0x80, 0x2c,
|
||||
0x68, 0xcb, 0x93, 0xfb, 0x51, 0x73, 0x49, 0xb4, 0x60, 0xda,
|
||||
0xe2, 0x26, 0xaf, 0xa9, 0x46, 0x12, 0xb8, 0xec, 0x50, 0xdd,
|
||||
0x12, 0x06, 0x5f, 0xce, 0x59, 0xe6, 0xf6, 0x1c, 0xe0, 0x54,
|
||||
0x10, 0xad, 0xf6, 0xcd, 0x98, 0xcc, 0x0f, 0xfb, 0xcb, 0x41,
|
||||
0x14, 0x9d, 0xed, 0xe4, 0xb4, 0x74, 0x5f, 0x09, 0x60, 0xc7,
|
||||
0x12, 0xf6, 0x7b, 0x3c, 0x8f, 0xa7, 0x20, 0xbc, 0xe4, 0xb1,
|
||||
0xef, 0xeb, 0xa4, 0x93, 0xc5, 0x06, 0xca, 0x9a, 0x27, 0x9d,
|
||||
0x87, 0xf3, 0xde, 0xca, 0xe5, 0xe7, 0xf6, 0x1c, 0x01, 0x65,
|
||||
0x5b, 0xfb, 0x19, 0x79, 0x6e, 0x08, 0x26, 0xc5, 0xc8, 0x28,
|
||||
0x0e, 0xb6, 0x3b, 0x07, 0x08, 0xc1, 0x02, 0x82, 0x01, 0x01,
|
||||
0x00, 0xe8, 0x1c, 0x73, 0xa6, 0xb8, 0xe0, 0x0e, 0x6d, 0x8d,
|
||||
0x1b, 0xb9, 0x53, 0xed, 0x58, 0x94, 0xe6, 0x1d, 0x60, 0x14,
|
||||
0x5c, 0x76, 0x43, 0xc4, 0x58, 0x19, 0xc4, 0x24, 0xe8, 0xbc,
|
||||
0x1b, 0x3b, 0x0b, 0x13, 0x24, 0x45, 0x54, 0x0e, 0xcc, 0x37,
|
||||
0xf0, 0xe0, 0x63, 0x7d, 0xc3, 0xf7, 0xfb, 0x81, 0x74, 0x81,
|
||||
0xc4, 0x0f, 0x1a, 0x21, 0x48, 0xaf, 0xce, 0xc1, 0xc4, 0x94,
|
||||
0x18, 0x06, 0x44, 0x8d, 0xd3, 0xd2, 0x22, 0x2d, 0x2d, 0x3e,
|
||||
0x5a, 0x31, 0xdc, 0x95, 0x8e, 0xf4, 0x41, 0xfc, 0x58, 0xc9,
|
||||
0x40, 0x92, 0x17, 0x5f, 0xe3, 0xda, 0xac, 0x9e, 0x3f, 0x1c,
|
||||
0x2a, 0x6b, 0x58, 0x5f, 0x48, 0x78, 0x20, 0xb1, 0xaf, 0x24,
|
||||
0x9b, 0x3c, 0x20, 0x8b, 0x93, 0x25, 0x9e, 0xe6, 0x6b, 0xbc,
|
||||
0x13, 0x42, 0x14, 0x6c, 0x36, 0x31, 0xff, 0x7a, 0xd1, 0xc1,
|
||||
0x1a, 0x26, 0x14, 0x7f, 0xa9, 0x76, 0xa7, 0x0c, 0xf8, 0xcc,
|
||||
0xed, 0x07, 0x6a, 0xd2, 0xdf, 0x62, 0xee, 0x0a, 0x7c, 0x84,
|
||||
0xcb, 0x49, 0x90, 0xb2, 0x03, 0x0d, 0xa2, 0x82, 0x06, 0x77,
|
||||
0xf1, 0xcd, 0x67, 0xf2, 0x47, 0x21, 0x02, 0x3f, 0x43, 0x21,
|
||||
0xf0, 0x46, 0x30, 0x62, 0x51, 0x72, 0xb1, 0xe7, 0x48, 0xc6,
|
||||
0x67, 0x12, 0xcd, 0x9e, 0xd6, 0x15, 0xe5, 0x21, 0xed, 0xfa,
|
||||
0x8f, 0x30, 0xa6, 0x41, 0xfe, 0xb6, 0xfa, 0x8f, 0x34, 0x14,
|
||||
0x19, 0xe8, 0x11, 0xf7, 0xa5, 0x77, 0x3e, 0xb7, 0xf9, 0x39,
|
||||
0x07, 0x8c, 0x67, 0x2a, 0xab, 0x7b, 0x08, 0xf8, 0xb0, 0x06,
|
||||
0xa8, 0xea, 0x2f, 0x8f, 0xfa, 0xcc, 0xcc, 0x40, 0xce, 0xf3,
|
||||
0x70, 0x4f, 0x3f, 0x7f, 0xe2, 0x0c, 0xea, 0x76, 0x4a, 0x35,
|
||||
0x4e, 0x47, 0xad, 0x2b, 0xa7, 0x97, 0x5d, 0x74, 0x43, 0x97,
|
||||
0x90, 0xd2, 0xfb, 0xd9, 0xf9, 0x96, 0x01, 0x33, 0x05, 0xed,
|
||||
0x7b, 0x03, 0x05, 0xad, 0xf8, 0x49, 0x03, 0x02, 0x82, 0x01,
|
||||
0x01, 0x00, 0xd4, 0x40, 0x17, 0x66, 0x10, 0x92, 0x95, 0xc8,
|
||||
0xec, 0x62, 0xa9, 0x7a, 0xcb, 0x93, 0x8e, 0xe6, 0x53, 0xd4,
|
||||
0x80, 0x48, 0x27, 0x4b, 0x41, 0xce, 0x61, 0xdf, 0xbf, 0x94,
|
||||
0xa4, 0x3d, 0x71, 0x03, 0x0b, 0xed, 0x25, 0x71, 0x98, 0xa4,
|
||||
0xd6, 0xd5, 0x4a, 0x57, 0xf5, 0x6c, 0x1b, 0xda, 0x21, 0x7d,
|
||||
0x35, 0x45, 0xb3, 0xf3, 0x6a, 0xd9, 0xd3, 0x43, 0xe8, 0x5c,
|
||||
0x54, 0x1c, 0x83, 0x1b, 0xb4, 0x5f, 0xf2, 0x97, 0x24, 0x2e,
|
||||
0xdc, 0x40, 0xde, 0x92, 0x23, 0x59, 0x8e, 0xbc, 0xd2, 0xa1,
|
||||
0xf2, 0xe0, 0x4c, 0xdd, 0x0b, 0xd1, 0xe7, 0xae, 0x65, 0xbc,
|
||||
0xb5, 0xf5, 0x5b, 0x98, 0xe9, 0xd7, 0xc2, 0xb7, 0x0e, 0x55,
|
||||
0x71, 0x0e, 0x3c, 0x0a, 0x24, 0x6b, 0xa6, 0xe6, 0x14, 0x61,
|
||||
0x11, 0xfd, 0x33, 0x42, 0x99, 0x2b, 0x84, 0x77, 0x74, 0x92,
|
||||
0x91, 0xf5, 0x79, 0x79, 0xcf, 0xad, 0x8e, 0x04, 0xef, 0x80,
|
||||
0x1e, 0x57, 0xf4, 0x14, 0xf5, 0x35, 0x09, 0x74, 0xb2, 0x13,
|
||||
0x71, 0x58, 0x6b, 0xea, 0x32, 0x5d, 0xf3, 0xd3, 0x76, 0x48,
|
||||
0x39, 0x10, 0x23, 0x84, 0x9d, 0xbe, 0x92, 0x77, 0x4a, 0xed,
|
||||
0x70, 0x3e, 0x1a, 0xa2, 0x6c, 0xb3, 0x81, 0x00, 0xc3, 0xc9,
|
||||
0xe4, 0x52, 0xc8, 0x24, 0x88, 0x0c, 0x41, 0xad, 0x87, 0x5a,
|
||||
0xea, 0xa3, 0x7a, 0x85, 0x1c, 0x5e, 0x31, 0x7f, 0xc3, 0x35,
|
||||
0xc6, 0xfa, 0x10, 0xc8, 0x75, 0x10, 0xc4, 0x96, 0x99, 0xe7,
|
||||
0xfe, 0x01, 0xb4, 0x74, 0xdb, 0xb4, 0x11, 0xc3, 0xc8, 0x8c,
|
||||
0xf6, 0xf7, 0x3b, 0x66, 0x50, 0xfc, 0xdb, 0xeb, 0xca, 0x47,
|
||||
0x85, 0x89, 0xe1, 0x65, 0xd9, 0x62, 0x34, 0x3c, 0x70, 0xd8,
|
||||
0x2e, 0xb4, 0x2f, 0x65, 0x3c, 0x4a, 0xa6, 0x2a, 0xe7, 0xc7,
|
||||
0xd8, 0x41, 0x8f, 0x8a, 0x43, 0xbf, 0x42, 0xf2, 0x4d, 0xbc,
|
||||
0xfc, 0x9e, 0x27, 0x95, 0xfb, 0x75, 0xff, 0xab, 0x02, 0x82,
|
||||
0x01, 0x00, 0x41, 0x2f, 0x44, 0x57, 0x6d, 0x12, 0x17, 0x5b,
|
||||
0x32, 0xc6, 0xb7, 0x6c, 0x57, 0x7a, 0x8a, 0x0e, 0x79, 0xef,
|
||||
0x72, 0xa8, 0x68, 0xda, 0x2d, 0x38, 0xe4, 0xbb, 0x8d, 0xf6,
|
||||
0x02, 0x65, 0xcf, 0x56, 0x13, 0xe1, 0x1a, 0xcb, 0x39, 0x80,
|
||||
0xa6, 0xb1, 0x32, 0x03, 0x1e, 0xdd, 0xbb, 0x35, 0xd9, 0xac,
|
||||
0x43, 0x89, 0x31, 0x08, 0x90, 0x92, 0x5e, 0x35, 0x3d, 0x7b,
|
||||
0x9c, 0x6f, 0x86, 0xcb, 0x17, 0xdd, 0x85, 0xe4, 0xed, 0x35,
|
||||
0x08, 0x8e, 0xc1, 0xf4, 0x05, 0xd8, 0x68, 0xc6, 0x63, 0x3c,
|
||||
0xf7, 0xff, 0xf7, 0x47, 0x33, 0x39, 0xc5, 0x3e, 0xb7, 0x0e,
|
||||
0x58, 0x35, 0x9d, 0x81, 0xea, 0xf8, 0x6a, 0x2c, 0x1c, 0x5a,
|
||||
0x68, 0x78, 0x64, 0x11, 0x6b, 0xc1, 0x3e, 0x4e, 0x7a, 0xbd,
|
||||
0x84, 0xcb, 0x0f, 0xc2, 0xb6, 0x85, 0x1d, 0xd3, 0x76, 0xc5,
|
||||
0x93, 0x6a, 0x69, 0x89, 0x56, 0x34, 0xdc, 0x4a, 0x9b, 0xbc,
|
||||
0xff, 0xa8, 0x0d, 0x6e, 0x35, 0x9c, 0x60, 0xa7, 0x23, 0x30,
|
||||
0xc7, 0x06, 0x64, 0x39, 0x8b, 0x94, 0x89, 0xee, 0xba, 0x7f,
|
||||
0x60, 0x8d, 0xfa, 0xb6, 0x97, 0x76, 0xdc, 0x51, 0x4a, 0x3c,
|
||||
0xeb, 0x3a, 0x14, 0x2c, 0x20, 0x60, 0x69, 0x4a, 0x86, 0xfe,
|
||||
0x8c, 0x21, 0x84, 0x49, 0x54, 0xb3, 0x20, 0xe1, 0x01, 0x7f,
|
||||
0x58, 0xdf, 0x7f, 0xb5, 0x21, 0x51, 0x8c, 0x47, 0x9f, 0x91,
|
||||
0xeb, 0x97, 0x3e, 0xf2, 0x54, 0xcf, 0x16, 0x46, 0xf9, 0xd9,
|
||||
0xb6, 0xe7, 0x64, 0xc9, 0xd0, 0x54, 0xea, 0x2f, 0xa1, 0xcf,
|
||||
0xa5, 0x7f, 0x28, 0x8d, 0x84, 0xec, 0xd5, 0x39, 0x03, 0x76,
|
||||
0x5b, 0x2d, 0x8e, 0x43, 0xf2, 0x01, 0x24, 0xc9, 0x6f, 0xc0,
|
||||
0xf5, 0x69, 0x6f, 0x7d, 0xb5, 0x85, 0xd2, 0x5f, 0x7f, 0x78,
|
||||
0x40, 0x07, 0x7f, 0x09, 0x15, 0xb5, 0x1f, 0x28, 0x65, 0x10,
|
||||
0xe4, 0x19, 0xa8, 0xc6, 0x9e, 0x8d, 0xdc, 0xcb, 0x02, 0x82,
|
||||
0x01, 0x00, 0x13, 0x01, 0xee, 0x56, 0x80, 0x93, 0x70, 0x00,
|
||||
0x7f, 0x52, 0xd2, 0x94, 0xa1, 0x98, 0x84, 0x4a, 0x92, 0x25,
|
||||
0x4c, 0x9b, 0xa9, 0x91, 0x2e, 0xc2, 0x79, 0xb7, 0x5c, 0xe3,
|
||||
0xc5, 0xd5, 0x8e, 0xc2, 0x54, 0x16, 0x17, 0xad, 0x55, 0x9b,
|
||||
0x25, 0x76, 0x12, 0x63, 0x50, 0x22, 0x2f, 0x58, 0x58, 0x79,
|
||||
0x6b, 0x04, 0xe3, 0xf9, 0x9f, 0x8f, 0x04, 0x41, 0x67, 0x94,
|
||||
0xa5, 0x1f, 0xac, 0x8a, 0x15, 0x9c, 0x26, 0x10, 0x6c, 0xf8,
|
||||
0x19, 0x57, 0x61, 0xd7, 0x3a, 0x7d, 0x31, 0xb0, 0x2d, 0x38,
|
||||
0xbd, 0x94, 0x62, 0xad, 0xc4, 0xfa, 0x36, 0x42, 0x42, 0xf0,
|
||||
0x24, 0x67, 0x65, 0x9d, 0x8b, 0x0b, 0x7c, 0x6f, 0x82, 0x44,
|
||||
0x1a, 0x8c, 0xc8, 0xc9, 0xab, 0xbb, 0x4c, 0x45, 0xfc, 0x7b,
|
||||
0x38, 0xee, 0x30, 0xe1, 0xfc, 0xef, 0x8d, 0xbc, 0x58, 0xdf,
|
||||
0x2b, 0x5d, 0x0d, 0x54, 0xe0, 0x49, 0x4d, 0x97, 0x99, 0x8f,
|
||||
0x22, 0xa8, 0x83, 0xbe, 0x40, 0xbb, 0x50, 0x2e, 0x78, 0x28,
|
||||
0x0f, 0x95, 0x78, 0x8c, 0x8f, 0x98, 0x24, 0x56, 0xc2, 0x97,
|
||||
0xf3, 0x2c, 0x43, 0xd2, 0x03, 0x82, 0x66, 0x81, 0x72, 0x5f,
|
||||
0x53, 0x16, 0xec, 0xb1, 0xb1, 0x04, 0x5e, 0x40, 0x20, 0x48,
|
||||
0x7b, 0x3f, 0x02, 0x97, 0x6a, 0xeb, 0x96, 0x12, 0x21, 0x35,
|
||||
0xfe, 0x1f, 0x47, 0xc0, 0x95, 0xea, 0xc5, 0x8a, 0x08, 0x84,
|
||||
0x4f, 0x5e, 0x63, 0x94, 0x60, 0x0f, 0x71, 0x5b, 0x7f, 0x4a,
|
||||
0xec, 0x4f, 0x60, 0xc6, 0xba, 0x4a, 0x24, 0xf1, 0x20, 0x8b,
|
||||
0xa7, 0x2e, 0x3a, 0xce, 0x8d, 0xe0, 0x27, 0x1d, 0xb5, 0x8e,
|
||||
0xb4, 0x21, 0xc5, 0xe2, 0xa6, 0x16, 0x0a, 0x51, 0x83, 0x55,
|
||||
0x88, 0xd1, 0x30, 0x11, 0x63, 0xd5, 0xd7, 0x8d, 0xae, 0x16,
|
||||
0x12, 0x82, 0xc4, 0x85, 0x00, 0x4e, 0x27, 0x83, 0xa5, 0x7c,
|
||||
0x90, 0x2e, 0xe5, 0xa2, 0xa3, 0xd3, 0x4c, 0x63, 0x02, 0x82,
|
||||
0x01, 0x01, 0x00, 0x86, 0x08, 0x98, 0x98, 0xa5, 0x00, 0x05,
|
||||
0x39, 0x77, 0xd9, 0x66, 0xb3, 0xcf, 0xca, 0xa0, 0x71, 0xb3,
|
||||
0x50, 0xce, 0x3d, 0xb1, 0x93, 0x95, 0x35, 0xc4, 0xd4, 0x2e,
|
||||
0x90, 0xdf, 0x0f, 0xfc, 0x60, 0xc1, 0x94, 0x68, 0x61, 0x43,
|
||||
0xca, 0x9a, 0x23, 0x4a, 0x1e, 0x45, 0x72, 0x99, 0xb5, 0x1e,
|
||||
0x61, 0x8d, 0x77, 0x0f, 0xa0, 0xbb, 0xd7, 0x77, 0xb4, 0x2a,
|
||||
0x15, 0x11, 0x88, 0x2d, 0xb3, 0x56, 0x61, 0x5e, 0x6a, 0xed,
|
||||
0xa4, 0x46, 0x4a, 0x3f, 0x50, 0x11, 0xd6, 0xba, 0xb6, 0xd7,
|
||||
0x95, 0x65, 0x53, 0xc3, 0xa1, 0x8f, 0xe0, 0xa3, 0xf5, 0x1c,
|
||||
0xfd, 0xaf, 0x6e, 0x43, 0xd7, 0x17, 0xa7, 0xd3, 0x81, 0x1b,
|
||||
0xa4, 0xdf, 0xe0, 0x97, 0x8a, 0x46, 0x03, 0xd3, 0x46, 0x0e,
|
||||
0x83, 0x48, 0x4e, 0xd2, 0x02, 0xcb, 0xc0, 0xad, 0x79, 0x95,
|
||||
0x8c, 0x96, 0xba, 0x40, 0x34, 0x11, 0x71, 0x5e, 0xe9, 0x11,
|
||||
0xf9, 0xc5, 0x4a, 0x5e, 0x91, 0x9d, 0xf5, 0x92, 0x4f, 0xeb,
|
||||
0xc6, 0x70, 0x02, 0x2d, 0x3d, 0x04, 0xaa, 0xe9, 0x3a, 0x8e,
|
||||
0xd5, 0xa8, 0xad, 0xf7, 0xce, 0x0d, 0x16, 0xb2, 0xec, 0x0a,
|
||||
0x9c, 0xf5, 0x94, 0x39, 0xb9, 0x8a, 0xfc, 0x1e, 0xf9, 0xcc,
|
||||
0xf2, 0x5f, 0x21, 0x31, 0x74, 0x72, 0x6b, 0x64, 0xae, 0x35,
|
||||
0x61, 0x8d, 0x0d, 0xcb, 0xe7, 0xda, 0x39, 0xca, 0xf3, 0x21,
|
||||
0x66, 0x0b, 0x95, 0xd7, 0x0a, 0x7c, 0xca, 0xa1, 0xa9, 0x5a,
|
||||
0xe8, 0xac, 0xe0, 0x71, 0x54, 0xaf, 0x28, 0xcf, 0xd5, 0x70,
|
||||
0x89, 0xe0, 0xf3, 0x9e, 0x43, 0x6c, 0x8d, 0x7b, 0x99, 0x01,
|
||||
0x68, 0x4d, 0xa1, 0x45, 0x46, 0x0c, 0x43, 0xbc, 0xcc, 0x2c,
|
||||
0xdd, 0xc5, 0x46, 0xc8, 0x4e, 0x0e, 0xbe, 0xed, 0xb9, 0x26,
|
||||
0xab, 0x2e, 0xdb, 0xeb, 0x8f, 0xff, 0xdb, 0xb0, 0xc6, 0x55,
|
||||
0xaf, 0xf8, 0x2a, 0x91, 0x9d, 0x50, 0x44, 0x21, 0x17,
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
/* $OpenBSD: timeouts.h,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
|
||||
/*
|
||||
* DTLS implementation written by Nagendra Modadugu
|
||||
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_TIMEOUTS_H
|
||||
#define INCLUDED_TIMEOUTS_H
|
||||
|
||||
/* numbers in us */
|
||||
#define DGRAM_RCV_TIMEOUT 250000
|
||||
#define DGRAM_SND_TIMEOUT 250000
|
||||
|
||||
#endif /* ! INCLUDED_TIMEOUTS_H */
|
||||
1252
apps/openssl/ts.c
1252
apps/openssl/ts.c
File diff suppressed because it is too large
Load Diff
@@ -1,457 +0,0 @@
|
||||
/* $OpenBSD: verify.c,v 1.17 2023/04/14 15:27:13 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static int cb(int ok, X509_STORE_CTX *ctx);
|
||||
static int check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
|
||||
STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls);
|
||||
static int vflags = 0;
|
||||
|
||||
static struct {
|
||||
char *CAfile;
|
||||
char *CApath;
|
||||
char *crlfile;
|
||||
char *trustfile;
|
||||
char *untfile;
|
||||
int verbose;
|
||||
X509_VERIFY_PARAM *vpm;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
verify_opt_args(int argc, char **argv, int *argsused)
|
||||
{
|
||||
int oargc = argc;
|
||||
int badarg = 0;
|
||||
|
||||
if (!args_verify(&argv, &argc, &badarg, bio_err, &cfg.vpm))
|
||||
return (1);
|
||||
if (badarg)
|
||||
return (1);
|
||||
|
||||
*argsused = oargc - argc;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option verify_options[] = {
|
||||
{
|
||||
.name = "CAfile",
|
||||
.argname = "file",
|
||||
.desc = "Certificate Authority file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.CAfile,
|
||||
},
|
||||
{
|
||||
.name = "CApath",
|
||||
.argname = "path",
|
||||
.desc = "Certificate Authority path",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.CApath,
|
||||
},
|
||||
{
|
||||
.name = "CRLfile",
|
||||
.argname = "file",
|
||||
.desc = "Certificate Revocation List file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.crlfile,
|
||||
},
|
||||
{
|
||||
.name = "trusted",
|
||||
.argname = "file",
|
||||
.desc = "Trusted certificates file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.trustfile,
|
||||
},
|
||||
{
|
||||
.name = "untrusted",
|
||||
.argname = "file",
|
||||
.desc = "Untrusted certificates file",
|
||||
.type = OPTION_ARG,
|
||||
.opt.arg = &cfg.untfile,
|
||||
},
|
||||
{
|
||||
.name = "verbose",
|
||||
.desc = "Verbose",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.verbose,
|
||||
},
|
||||
{
|
||||
.name = NULL,
|
||||
.desc = "",
|
||||
.type = OPTION_ARGV_FUNC,
|
||||
.opt.argvfunc = verify_opt_args,
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const struct option verify_shared_options[] = {
|
||||
{
|
||||
.name = "attime",
|
||||
.argname = "epoch",
|
||||
.desc = "Use epoch as the verification time",
|
||||
},
|
||||
{
|
||||
.name = "check_ss_sig",
|
||||
.desc = "Check the root CA self-signed certificate signature",
|
||||
},
|
||||
{
|
||||
.name = "crl_check",
|
||||
.desc = "Enable CRL checking for the leaf certificate",
|
||||
},
|
||||
{
|
||||
.name = "crl_check_all",
|
||||
.desc = "Enable CRL checking for the entire certificate chain",
|
||||
},
|
||||
{
|
||||
.name = "explicit_policy",
|
||||
.desc = "Require explicit policy (per RFC 3280)",
|
||||
},
|
||||
{
|
||||
.name = "extended_crl",
|
||||
.desc = "Enable extended CRL support",
|
||||
},
|
||||
{
|
||||
.name = "ignore_critical",
|
||||
.desc = "Disable critical extension checking",
|
||||
},
|
||||
{
|
||||
.name = "inhibit_any",
|
||||
.desc = "Inhibit any policy (per RFC 3280)",
|
||||
},
|
||||
{
|
||||
.name = "inhibit_map",
|
||||
.desc = "Inhibit policy mapping (per RFC 3280)",
|
||||
},
|
||||
{
|
||||
.name = "issuer_checks",
|
||||
.desc = "Enable debugging of certificate issuer checks",
|
||||
},
|
||||
{
|
||||
.name = "legacy_verify",
|
||||
.desc = "Use legacy certificate chain verification",
|
||||
},
|
||||
{
|
||||
.name = "policy",
|
||||
.argname = "name",
|
||||
.desc = "Add given policy to the acceptable set",
|
||||
},
|
||||
{
|
||||
.name = "policy_check",
|
||||
.desc = "Enable certificate policy checking",
|
||||
},
|
||||
{
|
||||
.name = "policy_print",
|
||||
.desc = "Print policy",
|
||||
},
|
||||
{
|
||||
.name = "purpose",
|
||||
.argname = "name",
|
||||
.desc = "Verify for the given purpose",
|
||||
},
|
||||
{
|
||||
.name = "use_deltas",
|
||||
.desc = "Use delta CRLS (if present)",
|
||||
},
|
||||
{
|
||||
.name = "verify_depth",
|
||||
.argname = "num",
|
||||
.desc = "Limit verification to the given depth",
|
||||
},
|
||||
{
|
||||
.name = "x509_strict",
|
||||
.desc = "Use strict X.509 rules (disables workarounds)",
|
||||
},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static void
|
||||
verify_usage(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: verify [-CAfile file] [-CApath directory] [-check_ss_sig]\n"
|
||||
" [-CRLfile file] [-crl_check] [-crl_check_all]\n"
|
||||
" [-explicit_policy] [-extended_crl]\n"
|
||||
" [-ignore_critical] [-inhibit_any] [-inhibit_map]\n"
|
||||
" [-issuer_checks] [-policy_check] [-purpose purpose]\n"
|
||||
" [-trusted file] [-untrusted file] [-verbose]\n"
|
||||
" [-x509_strict] [certificates]\n\n");
|
||||
|
||||
options_usage(verify_options);
|
||||
|
||||
fprintf(stderr, "\nVerification options:\n\n");
|
||||
options_usage(verify_shared_options);
|
||||
|
||||
fprintf(stderr, "\nValid purposes:\n\n");
|
||||
for (i = 0; i < X509_PURPOSE_get_count(); i++) {
|
||||
X509_PURPOSE *ptmp = X509_PURPOSE_get0(i);
|
||||
fprintf(stderr, " %-18s%s\n", X509_PURPOSE_get0_sname(ptmp),
|
||||
X509_PURPOSE_get0_name(ptmp));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
verify_main(int argc, char **argv)
|
||||
{
|
||||
STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
|
||||
STACK_OF(X509_CRL) *crls = NULL;
|
||||
X509_STORE *cert_ctx = NULL;
|
||||
X509_LOOKUP *lookup = NULL;
|
||||
char **cert_files = NULL;
|
||||
int argsused;
|
||||
int ret = 1;
|
||||
|
||||
if (pledge("stdio rpath", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, verify_options, NULL, &argsused) != 0) {
|
||||
verify_usage();
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argsused < argc)
|
||||
cert_files = &argv[argsused];
|
||||
|
||||
cert_ctx = X509_STORE_new();
|
||||
if (cert_ctx == NULL)
|
||||
goto end;
|
||||
X509_STORE_set_verify_cb(cert_ctx, cb);
|
||||
|
||||
if (cfg.vpm)
|
||||
X509_STORE_set1_param(cert_ctx, cfg.vpm);
|
||||
|
||||
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
|
||||
if (lookup == NULL)
|
||||
abort(); /* XXX */
|
||||
if (cfg.CAfile) {
|
||||
if (!X509_LOOKUP_load_file(lookup, cfg.CAfile,
|
||||
X509_FILETYPE_PEM)) {
|
||||
BIO_printf(bio_err, "Error loading file %s\n",
|
||||
cfg.CAfile);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
|
||||
|
||||
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
|
||||
if (lookup == NULL)
|
||||
abort(); /* XXX */
|
||||
if (cfg.CApath) {
|
||||
if (!X509_LOOKUP_add_dir(lookup, cfg.CApath,
|
||||
X509_FILETYPE_PEM)) {
|
||||
BIO_printf(bio_err, "Error loading directory %s\n",
|
||||
cfg.CApath);
|
||||
ERR_print_errors(bio_err);
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
if (cfg.untfile) {
|
||||
untrusted = load_certs(bio_err, cfg.untfile,
|
||||
FORMAT_PEM, NULL, "untrusted certificates");
|
||||
if (!untrusted)
|
||||
goto end;
|
||||
}
|
||||
if (cfg.trustfile) {
|
||||
trusted = load_certs(bio_err, cfg.trustfile,
|
||||
FORMAT_PEM, NULL, "trusted certificates");
|
||||
if (!trusted)
|
||||
goto end;
|
||||
}
|
||||
if (cfg.crlfile) {
|
||||
crls = load_crls(bio_err, cfg.crlfile, FORMAT_PEM,
|
||||
NULL, "other CRLs");
|
||||
if (!crls)
|
||||
goto end;
|
||||
}
|
||||
ret = 0;
|
||||
if (cert_files == NULL) {
|
||||
if (1 != check(cert_ctx, NULL, untrusted, trusted, crls))
|
||||
ret = -1;
|
||||
} else {
|
||||
do {
|
||||
if (1 != check(cert_ctx, *cert_files++, untrusted,
|
||||
trusted, crls))
|
||||
ret = -1;
|
||||
} while (*cert_files != NULL);
|
||||
}
|
||||
|
||||
end:
|
||||
if (cfg.vpm)
|
||||
X509_VERIFY_PARAM_free(cfg.vpm);
|
||||
if (cert_ctx != NULL)
|
||||
X509_STORE_free(cert_ctx);
|
||||
sk_X509_pop_free(untrusted, X509_free);
|
||||
sk_X509_pop_free(trusted, X509_free);
|
||||
sk_X509_CRL_pop_free(crls, X509_CRL_free);
|
||||
|
||||
return (ret < 0 ? 2 : ret);
|
||||
}
|
||||
|
||||
static int
|
||||
check(X509_STORE *ctx, char *file, STACK_OF(X509) *uchain,
|
||||
STACK_OF(X509) *tchain, STACK_OF(X509_CRL) *crls)
|
||||
{
|
||||
X509 *x = NULL;
|
||||
X509_STORE_CTX *csc = NULL;
|
||||
const char *certfile = (file == NULL) ? "stdin" : file;
|
||||
int verify_err;
|
||||
int i = 0, ret = 0;
|
||||
|
||||
x = load_cert(bio_err, file, FORMAT_PEM, NULL, "certificate file");
|
||||
if (x == NULL)
|
||||
goto end;
|
||||
|
||||
if ((csc = X509_STORE_CTX_new()) == NULL)
|
||||
goto end;
|
||||
X509_STORE_set_flags(ctx, vflags);
|
||||
if (!X509_STORE_CTX_init(csc, ctx, x, uchain))
|
||||
goto end;
|
||||
if (tchain)
|
||||
X509_STORE_CTX_trusted_stack(csc, tchain);
|
||||
if (crls)
|
||||
X509_STORE_CTX_set0_crls(csc, crls);
|
||||
|
||||
i = X509_verify_cert(csc);
|
||||
verify_err = X509_STORE_CTX_get_error(csc);
|
||||
|
||||
if (i > 0 && verify_err == X509_V_OK) {
|
||||
fprintf(stdout, "%s: OK\n", certfile);
|
||||
ret = 1;
|
||||
} else {
|
||||
fprintf(stdout, "%s: verification failed: %d (%s)\n", certfile,
|
||||
verify_err, X509_verify_cert_error_string(verify_err));
|
||||
}
|
||||
|
||||
end:
|
||||
if (i <= 0)
|
||||
ERR_print_errors(bio_err);
|
||||
X509_free(x);
|
||||
X509_STORE_CTX_free(csc);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int
|
||||
cb(int ok, X509_STORE_CTX *ctx)
|
||||
{
|
||||
int cert_error = X509_STORE_CTX_get_error(ctx);
|
||||
X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
|
||||
|
||||
if (!ok) {
|
||||
if (current_cert) {
|
||||
X509_NAME_print_ex_fp(stdout,
|
||||
X509_get_subject_name(current_cert),
|
||||
0, XN_FLAG_ONELINE);
|
||||
printf("\n");
|
||||
}
|
||||
printf("%serror %d at %d depth lookup:%s\n",
|
||||
X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
|
||||
cert_error,
|
||||
X509_STORE_CTX_get_error_depth(ctx),
|
||||
X509_verify_cert_error_string(cert_error));
|
||||
switch (cert_error) {
|
||||
case X509_V_ERR_NO_EXPLICIT_POLICY:
|
||||
case X509_V_ERR_CERT_HAS_EXPIRED:
|
||||
|
||||
/*
|
||||
* since we are just checking the certificates, it is
|
||||
* ok if they are self signed. But we should still
|
||||
* warn the user.
|
||||
*/
|
||||
|
||||
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
|
||||
/* Continue after extension errors too */
|
||||
case X509_V_ERR_INVALID_CA:
|
||||
case X509_V_ERR_INVALID_NON_CA:
|
||||
case X509_V_ERR_PATH_LENGTH_EXCEEDED:
|
||||
case X509_V_ERR_INVALID_PURPOSE:
|
||||
case X509_V_ERR_CRL_HAS_EXPIRED:
|
||||
case X509_V_ERR_CRL_NOT_YET_VALID:
|
||||
case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
|
||||
ok = 1;
|
||||
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
||||
}
|
||||
if (!cfg.verbose)
|
||||
ERR_clear_error();
|
||||
return (ok);
|
||||
}
|
||||
@@ -1,249 +0,0 @@
|
||||
/* $OpenBSD: version.c,v 1.12 2023/07/27 07:01:50 tb Exp $ */
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "apps.h"
|
||||
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
|
||||
#ifndef OPENSSL_NO_BF
|
||||
#include <openssl/blowfish.h>
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DES
|
||||
#include <openssl/des.h>
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_IDEA
|
||||
#include <openssl/idea.h>
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
#include <openssl/rc4.h>
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
int cflags;
|
||||
int date;
|
||||
int dir;
|
||||
int options;
|
||||
int platform;
|
||||
int version;
|
||||
} cfg;
|
||||
|
||||
static int
|
||||
version_all_opts(void)
|
||||
{
|
||||
cfg.cflags = 1;
|
||||
cfg.date = 1;
|
||||
cfg.dir= 1;
|
||||
cfg.options = 1;
|
||||
cfg.platform = 1;
|
||||
cfg.version = 1;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct option version_options[] = {
|
||||
{
|
||||
.name = "a",
|
||||
.desc = "All information (same as setting all other flags)",
|
||||
.type = OPTION_FUNC,
|
||||
.opt.func = version_all_opts,
|
||||
},
|
||||
{
|
||||
.name = "b",
|
||||
.desc = "Date the current version of OpenSSL was built",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.date,
|
||||
},
|
||||
{
|
||||
.name = "d",
|
||||
.desc = "OPENSSLDIR value",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.dir,
|
||||
},
|
||||
{
|
||||
.name = "f",
|
||||
.desc = "Compilation flags",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.cflags,
|
||||
},
|
||||
{
|
||||
.name = "o",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.options,
|
||||
},
|
||||
{
|
||||
.name = "p",
|
||||
.desc = "Platform settings",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.platform,
|
||||
},
|
||||
{
|
||||
.name = "v",
|
||||
.desc = "Current OpenSSL version",
|
||||
.type = OPTION_FLAG,
|
||||
.opt.flag = &cfg.version,
|
||||
},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
static void
|
||||
version_usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: version [-abdfpv]\n");
|
||||
options_usage(version_options);
|
||||
}
|
||||
|
||||
int
|
||||
version_main(int argc, char **argv)
|
||||
{
|
||||
if (pledge("stdio", NULL) == -1) {
|
||||
perror("pledge");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
if (options_parse(argc, argv, version_options, NULL, NULL) != 0) {
|
||||
version_usage();
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (argc == 1)
|
||||
cfg.version = 1;
|
||||
|
||||
if (cfg.version) {
|
||||
if (SSLeay() == SSLEAY_VERSION_NUMBER) {
|
||||
printf("%s\n", SSLeay_version(SSLEAY_VERSION));
|
||||
} else {
|
||||
printf("%s (Library: %s)\n",
|
||||
OPENSSL_VERSION_TEXT,
|
||||
SSLeay_version(SSLEAY_VERSION));
|
||||
}
|
||||
}
|
||||
if (cfg.date)
|
||||
printf("%s\n", SSLeay_version(SSLEAY_BUILT_ON));
|
||||
if (cfg.platform)
|
||||
printf("%s\n", SSLeay_version(SSLEAY_PLATFORM));
|
||||
if (cfg.cflags)
|
||||
printf("%s\n", SSLeay_version(SSLEAY_CFLAGS));
|
||||
if (cfg.dir)
|
||||
printf("%s\n", SSLeay_version(SSLEAY_DIR));
|
||||
|
||||
return (0);
|
||||
}
|
||||
1557
apps/openssl/x509.c
1557
apps/openssl/x509.c
File diff suppressed because it is too large
Load Diff
121
build.zig
121
build.zig
@@ -5,11 +5,12 @@ const LibreSslBuildOptions = struct {
|
||||
libcrypto_name: []const u8 = "crypto",
|
||||
libssl_name: []const u8 = "ssl",
|
||||
libtls_name: []const u8 = "tls",
|
||||
target: std.zig.CrossTarget,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
};
|
||||
|
||||
const LibreSslLibs = struct {
|
||||
target: std.Build.ResolvedTarget,
|
||||
libcrypto: *std.Build.Step.Compile,
|
||||
libssl: *std.Build.Step.Compile,
|
||||
libtls: *std.Build.Step.Compile,
|
||||
@@ -44,7 +45,7 @@ const LibreSslLibs = struct {
|
||||
base: []const u8,
|
||||
skiplist: []const SkipSpec,
|
||||
) !void {
|
||||
const dir = try b.build_root.handle.openIterableDir(base, .{});
|
||||
const dir = try b.build_root.handle.openDir(base, .{ .iterate = true });
|
||||
var walker = try dir.walk(b.allocator);
|
||||
defer walker.deinit();
|
||||
|
||||
@@ -68,18 +69,12 @@ const LibreSslLibs = struct {
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: this doesn't get cached, so it runs on every single build, which kind of sucks.
|
||||
// Also it won't work on windows.
|
||||
pub fn patchLibresslCompat(b: *std.Build) !void {
|
||||
var child = std.ChildProcess.init(&.{ "/bin/sh", "update.sh" }, b.allocator);
|
||||
_ = try child.spawnAndWait();
|
||||
}
|
||||
|
||||
pub fn libresslBuild(
|
||||
b: *std.Build,
|
||||
options: LibreSslBuildOptions,
|
||||
) !LibreSslLibs {
|
||||
const libressl_libs: LibreSslLibs = .{
|
||||
.target = options.target,
|
||||
.libcrypto = b.addStaticLibrary(.{
|
||||
.name = options.libcrypto_name,
|
||||
.target = options.target,
|
||||
@@ -101,7 +96,7 @@ pub fn libresslBuild(
|
||||
|
||||
libressl_libs.linkLibC();
|
||||
|
||||
const tinfo = libressl_libs.libcrypto.target_info.target;
|
||||
const tinfo = libressl_libs.target.result;
|
||||
|
||||
const common_cflags = [_][]const u8{
|
||||
"-fno-sanitize=undefined",
|
||||
@@ -113,13 +108,13 @@ pub fn libresslBuild(
|
||||
else => &common_cflags,
|
||||
};
|
||||
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_sources, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_nonasm, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_nonasm_or_armv4, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_sources, .flags = cflags });
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_nonasm, .flags = cflags });
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_nonasm_or_armv4, .flags = cflags });
|
||||
|
||||
libressl_libs.libssl.addCSourceFiles(&libssl_sources, cflags);
|
||||
libressl_libs.libssl.addCSourceFiles(.{ .files = &libssl_sources, .flags = cflags });
|
||||
|
||||
libressl_libs.libtls.addCSourceFiles(&libtls_sources, cflags);
|
||||
libressl_libs.libtls.addCSourceFiles(.{ .files = &libtls_sources, .flags = cflags });
|
||||
|
||||
libressl_libs.defineCMacro("LIBRESSL_INTERNAL", null);
|
||||
libressl_libs.defineCMacro("OPENSSL_NO_HW_PADLOCK", null);
|
||||
@@ -130,8 +125,8 @@ pub fn libresslBuild(
|
||||
|
||||
switch (tinfo.os.tag) {
|
||||
.macos => {
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_unix_sources, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_macos_compat, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_unix_sources, .flags = cflags });
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_macos_compat, .flags = cflags });
|
||||
|
||||
libressl_libs.defineCMacro("HAVE_CLOCK_GETTIME", null);
|
||||
libressl_libs.defineCMacro("HAVE_ASPRINTF", null);
|
||||
@@ -154,8 +149,8 @@ pub fn libresslBuild(
|
||||
libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null);
|
||||
},
|
||||
.linux => {
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_unix_sources, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_compat, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_unix_sources, .flags = cflags });
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_compat, .flags = cflags });
|
||||
|
||||
libressl_libs.defineCMacro("_DEFAULT_SOURCE", null);
|
||||
libressl_libs.defineCMacro("_BSD_SOURCE", null);
|
||||
@@ -183,9 +178,9 @@ pub fn libresslBuild(
|
||||
libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null);
|
||||
|
||||
if (tinfo.abi.isGnu()) {
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_glibc_compat, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_glibc_compat, .flags = cflags });
|
||||
} else if (tinfo.abi.isMusl()) {
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_linux_musl_compat, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_linux_musl_compat, .flags = cflags });
|
||||
|
||||
libressl_libs.defineCMacro("HAVE_STRLCAT", null);
|
||||
libressl_libs.defineCMacro("HAVE_STRLCPY", null);
|
||||
@@ -195,9 +190,9 @@ pub fn libresslBuild(
|
||||
libressl_libs.linkSystemLibrary("pthread");
|
||||
},
|
||||
.windows => {
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_windows_sources, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(&libcrypto_windows_compat, cflags);
|
||||
libressl_libs.libtls.addCSourceFiles(&libtls_windows_sources, cflags);
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_windows_sources, .flags = cflags });
|
||||
libressl_libs.libcrypto.addCSourceFiles(.{ .files = &libcrypto_windows_compat, .flags = cflags });
|
||||
libressl_libs.libtls.addCSourceFiles(.{ .files = &libtls_windows_sources, .flags = cflags });
|
||||
|
||||
if (tinfo.abi != .msvc) {
|
||||
libressl_libs.defineCMacro("_GNU_SOURCE", null);
|
||||
@@ -289,6 +284,13 @@ pub fn libresslBuild(
|
||||
else => @panic("unsupported target CPU arch"),
|
||||
}
|
||||
|
||||
// add the header install path to the include path so that compilation will pick
|
||||
// up "openssl/opensslconf.h". This is added last to avoid interfering with the
|
||||
// somewhat messy include handling that libressl does.
|
||||
libressl_libs.libcrypto.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
|
||||
libressl_libs.libssl.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
|
||||
libressl_libs.libtls.addIncludePath(.{ .path = b.getInstallPath(.header, "") });
|
||||
|
||||
libressl_libs.libssl.linkLibrary(libressl_libs.libcrypto);
|
||||
|
||||
// cmake builds libtls with libcrypto and libssl symbols jammed into it. However,
|
||||
@@ -307,38 +309,9 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// if (builtin.os.tag != .windows) try patchLibresslCompat(b);
|
||||
_ = try libresslBuild(b, .{ .target = target, .optimize = optimize });
|
||||
}
|
||||
|
||||
// libressl_libs.defineCMacro("HAVE_ASPRINTF", null);
|
||||
// libressl_libs.defineCMacro("HAVE_REALLOCARRAY", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRCASECMP", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRLCAT", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRLCPY", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRNDUP", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRNLEN", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRSEP", null);
|
||||
// libressl_libs.defineCMacro("HAVE_STRTONUM", null);
|
||||
// libressl_libs.defineCMacro("HAVE_TIMEGM", null);
|
||||
// libressl_libs.defineCMacro("HAVE_ARC4RANDOM_BUF", null);
|
||||
// libressl_libs.defineCMacro("HAVE_ARC4RANDOM_UNIFORM", null);
|
||||
// libressl_libs.defineCMacro("HAVE_EXPLICIT_BZERO", null);
|
||||
// libressl_libs.defineCMacro("HAVE_GETAUXVAL", null);
|
||||
// libressl_libs.defineCMacro("HAVE_GETENTROPY", null);
|
||||
// libressl_libs.defineCMacro("HAVE_GETPAGESIZE", null);
|
||||
// libressl_libs.defineCMacro("HAVE_GETPROGNAME", null);
|
||||
// libressl_libs.defineCMacro("HAVE_SYSLOG_R", null);
|
||||
// libressl_libs.defineCMacro("HAVE_SYSLOG", null);
|
||||
// libressl_libs.defineCMacro("HAVE_TIMESPECSUB", null);
|
||||
// libressl_libs.defineCMacro("HAVE_TIMINGSAFE_BCMP", null);
|
||||
// libressl_libs.defineCMacro("HAVE_MEMCMP", null);
|
||||
// libressl_libs.defineCMacro("HAVE_MEMMEM", null);
|
||||
// libressl_libs.defineCMacro("HAVE_ENDIAN_H", null);
|
||||
// libressl_libs.defineCMacro("HAVE_MACHINE_ENDIAN_H", null);
|
||||
// libressl_libs.defineCMacro("HAVE_ERR_H", null);
|
||||
// libressl_libs.defineCMacro("HAVE_NETINET_IP_H", null);
|
||||
|
||||
const SkipSpec = union(enum) {
|
||||
starts_with: []const u8,
|
||||
ends_with: []const u8,
|
||||
@@ -475,48 +448,6 @@ const libcrypto_windows_compat = [_][]const u8{
|
||||
libcrypto_src_prefix ++ "compat/timingsafe_memcmp.c",
|
||||
};
|
||||
|
||||
// const libcrypto_compat_sources = [_][]const u8{
|
||||
// libcrypto_src_prefix ++ "compat/bsd-asprintf.c",
|
||||
// libcrypto_src_prefix ++ "compat/freezero.c",
|
||||
// libcrypto_src_prefix ++ "compat/getpagesize.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/getprogname_windows.c",
|
||||
// libcrypto_src_prefix ++ "compat/getprogname_linux.c",
|
||||
// libcrypto_src_prefix ++ "compat/getprogname_unimpl.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/reallocarray.c",
|
||||
// libcrypto_src_prefix ++ "compat/recallocarray.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/strcasecmp.c",
|
||||
// libcrypto_src_prefix ++ "compat/strlcat.c",
|
||||
// libcrypto_src_prefix ++ "compat/strlcpy.c",
|
||||
// libcrypto_src_prefix ++ "compat/strndup.c",
|
||||
// libcrypto_src_prefix ++ "compat/strnlen.c",
|
||||
// libcrypto_src_prefix ++ "compat/strsep.c",
|
||||
// libcrypto_src_prefix ++ "compat/strtonum.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/syslog_r.c",
|
||||
// libcrypto_src_prefix ++ "compat/timegm.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/explicit_bzero_win.c",
|
||||
// libcrypto_src_prefix ++ "compat/explicit_bzero.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/arc4random.c",
|
||||
// libcrypto_src_prefix ++ "compat/arc4random_uniform.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_win.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_aix.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_freebsd.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_hpux.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_linux.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_netbsd.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_osx.c",
|
||||
// libcrypto_src_prefix ++ "compat/getentropy_solaris.c",
|
||||
|
||||
// libcrypto_src_prefix ++ "compat/timingsafe_bcmp.c",
|
||||
// libcrypto_src_prefix ++ "compat/timingsafe_memcmp.c",
|
||||
// };
|
||||
|
||||
const libcrypto_sources = [_][]const u8{
|
||||
libcrypto_src_prefix ++ "cpt_err.c",
|
||||
libcrypto_src_prefix ++ "cryptlib.c",
|
||||
|
||||
@@ -111,7 +111,6 @@ if(HOST_ASM_MACOSX_X86_64)
|
||||
bn/arch/amd64/word_clz.S
|
||||
bn/arch/amd64/bn_arch.c
|
||||
)
|
||||
add_definitions(-Dendbr64=)
|
||||
add_definitions(-DAES_ASM)
|
||||
add_definitions(-DBSAES_ASM)
|
||||
add_definitions(-DVPAES_ASM)
|
||||
@@ -153,6 +152,7 @@ if(HOST_ASM_MASM_X86_64)
|
||||
whrlpool/wp-masm-x86_64.S
|
||||
cpuid-masm-x86_64.S
|
||||
)
|
||||
add_definitions(-Dendbr64=)
|
||||
add_definitions(-DAES_ASM)
|
||||
add_definitions(-DBSAES_ASM)
|
||||
add_definitions(-DVPAES_ASM)
|
||||
@@ -193,6 +193,7 @@ if(HOST_ASM_MINGW64_X86_64)
|
||||
whrlpool/wp-mingw64-x86_64.S
|
||||
cpuid-mingw64-x86_64.S
|
||||
)
|
||||
add_definitions(-Dendbr64=)
|
||||
add_definitions(-DAES_ASM)
|
||||
add_definitions(-DBSAES_ASM)
|
||||
add_definitions(-DVPAES_ASM)
|
||||
@@ -778,6 +779,8 @@ endif()
|
||||
if(NOT HAVE_GETOPT)
|
||||
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getopt_long.c)
|
||||
set(EXTRA_EXPORT ${EXTRA_EXPORT} getopt)
|
||||
set(EXTRA_EXPORT ${EXTRA_EXPORT} optarg)
|
||||
set(EXTRA_EXPORT ${EXTRA_EXPORT} optind)
|
||||
endif()
|
||||
|
||||
if(NOT HAVE_GETPAGESIZE)
|
||||
|
||||
@@ -36,6 +36,7 @@ EXTRA_DIST += empty.c
|
||||
|
||||
# needed for a CMake target
|
||||
EXTRA_DIST += compat/strcasecmp.c
|
||||
EXTRA_DIST += compat/getopt_long.c
|
||||
|
||||
BUILT_SOURCES = crypto_portable.sym
|
||||
CLEANFILES = crypto_portable.sym
|
||||
|
||||
@@ -34,7 +34,6 @@ ASM_X86_64_MACOSX += bn/arch/amd64/bn_arch.c
|
||||
EXTRA_DIST += $(ASM_X86_64_MACOSX)
|
||||
|
||||
if HOST_ASM_MACOSX_X86_64
|
||||
libcrypto_la_CPPFLAGS += -Dendbr64=
|
||||
libcrypto_la_CPPFLAGS += -DAES_ASM
|
||||
libcrypto_la_CPPFLAGS += -DBSAES_ASM
|
||||
libcrypto_la_CPPFLAGS += -DVPAES_ASM
|
||||
|
||||
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
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
File diff suppressed because it is too large
Load Diff
@@ -1,65 +0,0 @@
|
||||
/* $OpenBSD: aes_cbc.c,v 1.12 2014/06/12 15:49:27 deraadt Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void
|
||||
AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key, unsigned char *ivec, const int enc)
|
||||
{
|
||||
if (enc)
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
|
||||
(block128_f)AES_encrypt);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
|
||||
(block128_f)AES_decrypt);
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
/* $OpenBSD: aes_cfb.c,v 1.8 2014/06/12 15:49:27 deraadt Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/modes.h>
|
||||
|
||||
/* The input and output encrypted as though 128bit cfb mode is being
|
||||
* used. The extra state information to record how much of the
|
||||
* 128bit block we have used is contained in *num;
|
||||
*/
|
||||
|
||||
void
|
||||
AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f)AES_encrypt);
|
||||
}
|
||||
|
||||
/* N.B. This expects the input to be packed, MS bit first */
|
||||
void
|
||||
AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f)AES_encrypt);
|
||||
}
|
||||
|
||||
void
|
||||
AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f)AES_encrypt);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
/* $OpenBSD: aes_ctr.c,v 1.9 2014/06/12 15:49:27 deraadt Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void
|
||||
AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE],
|
||||
unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num)
|
||||
{
|
||||
CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
|
||||
(block128_f)AES_encrypt);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/* $OpenBSD: aes_ecb.c,v 1.7 2022/11/26 16:08:50 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AES_DEBUG
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include "aes_local.h"
|
||||
|
||||
void
|
||||
AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key, const int enc)
|
||||
{
|
||||
if (AES_ENCRYPT == enc)
|
||||
AES_encrypt(in, out, key);
|
||||
else
|
||||
AES_decrypt(in, out, key);
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
/* $OpenBSD: aes_ige.c,v 1.9 2022/11/26 16:08:50 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/crypto.h>
|
||||
|
||||
#include "aes_local.h"
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
} aes_block_t;
|
||||
|
||||
/* XXX: probably some better way to do this */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define UNALIGNED_MEMOPS_ARE_FAST 1
|
||||
#else
|
||||
#define UNALIGNED_MEMOPS_ARE_FAST 0
|
||||
#endif
|
||||
|
||||
#if UNALIGNED_MEMOPS_ARE_FAST
|
||||
#define load_block(d, s) (d) = *(const aes_block_t *)(s)
|
||||
#define store_block(d, s) *(aes_block_t *)(d) = (s)
|
||||
#else
|
||||
#define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE)
|
||||
#define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE)
|
||||
#endif
|
||||
|
||||
/* N.B. The IV for this mode is _twice_ the block size */
|
||||
|
||||
void
|
||||
AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, const int enc)
|
||||
{
|
||||
size_t n;
|
||||
size_t len;
|
||||
|
||||
OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
|
||||
|
||||
len = length / AES_BLOCK_SIZE;
|
||||
|
||||
if (AES_ENCRYPT == enc) {
|
||||
if (in != out && (UNALIGNED_MEMOPS_ARE_FAST ||
|
||||
((size_t)in|(size_t)out|(size_t)ivec) %
|
||||
sizeof(long) == 0)) {
|
||||
aes_block_t *ivp = (aes_block_t *)ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len) {
|
||||
aes_block_t *inp = (aes_block_t *)in;
|
||||
aes_block_t *outp = (aes_block_t *)out;
|
||||
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] = inp->data[n] ^ ivp->data[n];
|
||||
AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= iv2p->data[n];
|
||||
ivp = outp;
|
||||
iv2p = inp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memmove(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
} else {
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len) {
|
||||
load_block(tmp, in);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp2.data[n] = tmp.data[n] ^ iv.data[n];
|
||||
AES_encrypt((unsigned char *)tmp2.data,
|
||||
(unsigned char *)tmp2.data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp2.data[n] ^= iv2.data[n];
|
||||
store_block(out, tmp2);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
} else {
|
||||
if (in != out && (UNALIGNED_MEMOPS_ARE_FAST ||
|
||||
((size_t)in|(size_t)out|(size_t)ivec) %
|
||||
sizeof(long) == 0)) {
|
||||
aes_block_t *ivp = (aes_block_t *)ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len) {
|
||||
aes_block_t tmp;
|
||||
aes_block_t *inp = (aes_block_t *)in;
|
||||
aes_block_t *outp = (aes_block_t *)out;
|
||||
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] = inp->data[n] ^ iv2p->data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data,
|
||||
(unsigned char *)outp->data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= ivp->data[n];
|
||||
ivp = inp;
|
||||
iv2p = outp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memmove(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
} else {
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len) {
|
||||
load_block(tmp, in);
|
||||
tmp2 = tmp;
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv2.data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data,
|
||||
(unsigned char *)tmp.data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv.data[n];
|
||||
store_block(out, tmp);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/* $OpenBSD: aes_local.h,v 1.2 2022/11/26 17:23:17 tb Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HEADER_AES_LOCAL_H
|
||||
#define HEADER_AES_LOCAL_H
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
|
||||
#ifdef OPENSSL_NO_AES
|
||||
#error AES is disabled.
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
__BEGIN_HIDDEN_DECLS
|
||||
|
||||
#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
||||
#define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
||||
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
#define MAXKC (256/32)
|
||||
#define MAXKB (256/8)
|
||||
#define MAXNR 14
|
||||
|
||||
/* This controls loop-unrolling in aes_core.c */
|
||||
#undef FULL_UNROLL
|
||||
|
||||
__END_HIDDEN_DECLS
|
||||
|
||||
#endif /* !HEADER_AES_LOCAL_H */
|
||||
@@ -1,61 +0,0 @@
|
||||
/* $OpenBSD: aes_ofb.c,v 1.6 2014/06/12 15:49:27 deraadt Exp $ */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*
|
||||
*/
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void
|
||||
AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, size_t length,
|
||||
const AES_KEY *key, unsigned char *ivec, int *num)
|
||||
{
|
||||
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
|
||||
(block128_f)AES_encrypt);
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/* $OpenBSD: aes_wrap.c,v 1.12 2018/11/07 18:31:16 tb Exp $ */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2008 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* licensing@OpenSSL.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/bio.h>
|
||||
|
||||
static const unsigned char default_iv[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
|
||||
};
|
||||
|
||||
int
|
||||
AES_wrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
|
||||
if ((inlen & 0x7) || (inlen < 16))
|
||||
return -1;
|
||||
A = B;
|
||||
t = 1;
|
||||
memmove(out + 8, in, inlen);
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
|
||||
memcpy(A, iv, 8);
|
||||
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + 8;
|
||||
for (i = 0; i < inlen; i += 8, t++, R += 8) {
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_encrypt(B, B, key);
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
memcpy(out, A, 8);
|
||||
return inlen + 8;
|
||||
}
|
||||
|
||||
int
|
||||
AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
|
||||
if ((inlen & 0x7) || (inlen < 24))
|
||||
return -1;
|
||||
inlen -= 8;
|
||||
A = B;
|
||||
t = 6 * (inlen >> 3);
|
||||
memcpy(A, in, 8);
|
||||
memmove(out, in + 8, inlen);
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + inlen - 8;
|
||||
for (i = 0; i < inlen; i += 8, t--, R -= 8) {
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_decrypt(B, B, key);
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
if (memcmp(A, iv, 8)) {
|
||||
explicit_bzero(out, inlen);
|
||||
return 0;
|
||||
}
|
||||
return inlen;
|
||||
}
|
||||
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
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user