James 2018-03-11 17:40:12 +11:00
commit 49f073a705
849 changed files with 333206 additions and 0 deletions

32
.gitignore vendored Normal file
View File

@ -0,0 +1,32 @@
# Build directory
[Bb]uild/
doc-build/
# Generated source files
src/common/scm_rev.cpp
.travis.descriptor.json
# Project/editor files
*.swp
.idea/
.vs/
.vscode/
# *nix related
# Common convention for backup or temporary files
*~
# Visual Studio CMake settings
CMakeSettings.json
# OSX global filetypes
# Created by Finder or Spotlight in directories for various OS functionality (indexing, etc)
.DS_Store
.AppleDouble
.LSOverride
.Spotlight-V100
.Trashes
# Windows global filetypes
Thumbs.db

318
CMakeLists.txt Normal file
View File

@ -0,0 +1,318 @@
cmake_minimum_required (VERSION 2.8.8)
include(CheckFunctionExists)
include(CheckLibraryExists)
include(CheckIncludeFiles)
include(CheckTypeSize)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" ${CMAKE_MODULE_PATH})
include(cmake_export_symbol)
include(GNUInstallDirs)
project (LibreSSL C)
enable_testing()
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/ssl/VERSION SSL_VERSION)
string(STRIP ${SSL_VERSION} SSL_VERSION)
string(REPLACE ":" "." SSL_VERSION ${SSL_VERSION})
string(REGEX REPLACE "\\..*" "" SSL_MAJOR_VERSION ${SSL_VERSION})
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/crypto/VERSION CRYPTO_VERSION)
string(STRIP ${CRYPTO_VERSION} CRYPTO_VERSION)
string(REPLACE ":" "." CRYPTO_VERSION ${CRYPTO_VERSION})
string(REGEX REPLACE "\\..*" "" CRYPTO_MAJOR_VERSION ${CRYPTO_VERSION})
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/tls/VERSION TLS_VERSION)
string(STRIP ${TLS_VERSION} TLS_VERSION)
string(REPLACE ":" "." TLS_VERSION ${TLS_VERSION})
string(REGEX REPLACE "\\..*" "" TLS_MAJOR_VERSION ${TLS_VERSION})
option(LIBRESSL_SKIP_INSTALL "Skip installation" ${LIBRESSL_SKIP_INSTALL})
option(ENABLE_ASM "Enable assembly" ON)
option(ENABLE_EXTRATESTS "Enable extra tests that may be unreliable on some platforms" OFF)
option(ENABLE_NC "Enable installing TLS-enabled nc(1)" OFF)
option(ENABLE_VSTEST "Enable test on Visual Studio" OFF)
set(OPENSSLDIR ${OPENSSLDIR} CACHE PATH "Set the default openssl directory" FORCE)
if(NOT LIBRESSL_SKIP_INSTALL)
set( ENABLE_LIBRESSL_INSTALL ON )
endif(NOT LIBRESSL_SKIP_INSTALL)
set(BUILD_NC true)
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_definitions(-fno-common)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "OpenBSD")
add_definitions(-DHAVE_ATTRIBUTE__BOUNDED__)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_definitions(-D_DEFAULT_SOURCE)
add_definitions(-D_BSD_SOURCE)
add_definitions(-D_POSIX_SOURCE)
add_definitions(-D_GNU_SOURCE)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "MINGW")
set(BUILD_NC false)
endif()
if(WIN32)
set(BUILD_NC false)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
if(CMAKE_C_COMPILER MATCHES "gcc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=gnu99 -fno-strict-aliasing")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mlp64")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O2 +DD64 +Otype_safety=off")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=600 -D__STRICT_ALIGNMENT")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=gnu99 -fno-strict-aliasing")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D__EXTENSIONS__")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=600")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBSD_COMP")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpic -m64")
endif()
add_definitions(-DLIBRESSL_INTERNAL)
add_definitions(-DOPENSSL_NO_HW_PADLOCK)
add_definitions(-D__BEGIN_HIDDEN_DECLS=)
add_definitions(-D__END_HIDDEN_DECLS=)
set(CMAKE_POSITION_INDEPENDENT_CODE true)
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
add_definitions(-Wno-pointer-sign)
endif()
if(WIN32)
add_definitions(-Drestrict)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-D_CRT_DEPRECATED_NO_WARNINGS)
add_definitions(-D_REENTRANT -D_POSIX_THREAD_SAFE_FUNCTIONS)
add_definitions(-DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0501)
add_definitions(-DCPPFLAGS -DOPENSSL_NO_SPEED -DNO_SYSLOG -DNO_CRYPT)
endif()
if(MSVC)
add_definitions(-Dinline=__inline)
message(STATUS "Using [${CMAKE_C_COMPILER_ID}] compiler")
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
set(MSVC_DISABLED_WARNINGS_LIST
"C4057" # C4057: 'initializing' : 'unsigned char *' differs in
# indirection to slightly different base types from 'char [2]'
"C4018" # '>=': signed/unsigned mismatch
"C4100" # 'exarg' : unreferenced formal parameter
"C4127" # conditional expression is constant
"C4146" # unary minus operator applied to unsigned
# type, result still unsigned
"C4242" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
"C4244" # 'function' : conversion from 'int' to 'uint8_t',
# possible loss of data
"C4245" # 'initializing': conversion from 'long' to
# 'unsigned long', signed/unsigned mismatch
"C4267" # conversion from 'size_t' to 'some type that is almost
# certainly safe to convert a size_t to'.
"C4389" # '!=': signed/unsigned mismatch
"C4706" # assignment within conditional expression
"C4820" # 'bytes' bytes padding added after construct 'member_name'
"C4996" # 'read': The POSIX name for this item is deprecated. Instead,
# use the ISO C++ conformant name: _read.
)
elseif(CMAKE_C_COMPILER_ID MATCHES "Intel")
add_definitions(-D_CRT_SUPPRESS_RESTRICT)
set(MSVC_DISABLED_WARNINGS_LIST
"C111" # Unreachable statement
"C128" # Unreachable loop
"C167" # Unexplict casting unsigned to signed
"C186" # Pointless comparison of unsigned int with zero
"C188" # Enumerated type mixed with another type
"C344" # Redeclared type
"C556" # Unexplict casting signed to unsigned
"C869" # Unreferenced parameters
"C1786" # Deprecated functions
"C2545" # Empty else statement
"C2557" # Comparing signed to unsigned
"C2722" # List init syntax is c++11 feature
"C3280" # Declaration hides variable
)
endif()
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
${MSVC_DISABLED_WARNINGS_LIST})
string(REGEX REPLACE "[/-]W[1234][ ]?" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -MP -W4 ${MSVC_DISABLED_WARNINGS_STR}")
endif()
check_function_exists(asprintf HAVE_ASPRINTF)
if(HAVE_ASPRINTF)
add_definitions(-DHAVE_ASPRINTF)
endif()
check_function_exists(inet_pton HAVE_INET_PTON)
if(HAVE_INET_PTON)
add_definitions(-DHAVE_INET_PTON)
endif()
check_function_exists(reallocarray HAVE_REALLOCARRAY)
if(HAVE_REALLOCARRAY)
add_definitions(-DHAVE_REALLOCARRAY)
endif()
check_function_exists(strcasecmp HAVE_STRCASECMP)
if(HAVE_STRCASECMP)
add_definitions(-DHAVE_STRCASECMP)
endif()
check_function_exists(strlcat HAVE_STRLCAT)
if(HAVE_STRLCAT)
add_definitions(-DHAVE_STRLCAT)
endif()
check_function_exists(strlcpy HAVE_STRLCPY)
if(HAVE_STRLCPY)
add_definitions(-DHAVE_STRLCPY)
endif()
check_function_exists(strndup HAVE_STRNDUP)
if(HAVE_STRNDUP)
add_definitions(-DHAVE_STRNDUP)
endif()
if(WIN32)
set(HAVE_STRNLEN true)
add_definitions(-DHAVE_STRNLEN)
else()
check_function_exists(strnlen HAVE_STRNLEN)
if(HAVE_STRNLEN)
add_definitions(-DHAVE_STRNLEN)
endif()
endif()
check_function_exists(strsep HAVE_STRSEP)
if(HAVE_STRSEP)
add_definitions(-DHAVE_STRSEP)
endif()
check_function_exists(timegm HAVE_TIMEGM)
if(HAVE_TIMEGM)
add_definitions(-DHAVE_TIMEGM)
endif()
check_function_exists(arc4random_buf HAVE_ARC4RANDOM_BUF)
if(HAVE_ARC4RANDOM_BUF)
add_definitions(-DHAVE_ARC4RANDOM_BUF)
endif()
check_function_exists(arc4random_uniform HAVE_ARC4RANDOM_UNIFORM)
if(HAVE_ARC4RANDOM_UNIFORM)
add_definitions(-DHAVE_ARC4RANDOM_UNIFORM)
endif()
check_function_exists(explicit_bzero HAVE_EXPLICIT_BZERO)
if(HAVE_EXPLICIT_BZERO)
add_definitions(-DHAVE_EXPLICIT_BZERO)
endif()
check_function_exists(getauxval HAVE_GETAUXVAL)
if(HAVE_GETAUXVAL)
add_definitions(-DHAVE_GETAUXVAL)
endif()
check_function_exists(getentropy HAVE_GETENTROPY)
if(HAVE_GETENTROPY)
add_definitions(-DHAVE_GETENTROPY)
endif()
check_function_exists(getpagesize HAVE_GETPAGESIZE)
if(HAVE_GETPAGESIZE)
add_definitions(-DHAVE_GETPAGESIZE)
endif()
check_function_exists(timingsafe_bcmp HAVE_TIMINGSAFE_BCMP)
if(HAVE_TIMINGSAFE_BCMP)
add_definitions(-DHAVE_TIMINGSAFE_BCMP)
endif()
check_function_exists(timingsafe_memcmp HAVE_TIMINGSAFE_MEMCMP)
if(HAVE_MEMCMP)
add_definitions(-DHAVE_MEMCMP)
endif()
check_function_exists(memmem HAVE_MEMMEM)
if(HAVE_MEMMEM)
add_definitions(-DHAVE_MEMMEM)
endif()
check_include_files(err.h HAVE_ERR_H)
if(HAVE_ERR_H)
add_definitions(-DHAVE_ERR_H)
endif()
if(ENABLE_ASM)
if("${CMAKE_C_COMPILER_ABI}" STREQUAL "ELF")
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64)")
set(HOST_ASM_ELF_X86_64 true)
elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386")
set(HOST_ASM_ELF_X86_64 true)
endif()
elseif(APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
set(HOST_ASM_MACOSX_X86_64 true)
endif()
endif()
if(NOT (CMAKE_SYSTEM_NAME MATCHES "(Darwin|CYGWIN)"))
set(BUILD_SHARED true)
endif()
# USE_SHARED builds applications (e.g. openssl) using shared LibreSSL.
# By default, applications use LibreSSL static library to avoid dependencies.
# USE_SHARED isn't set by default; use -DUSE_SHARED=ON with CMake to enable.
# Can be helpful for debugging; don't use for public releases.
if(NOT BUILD_SHARED)
set(USE_SHARED off)
endif()
if(USE_SHARED)
set(OPENSSL_LIBS tls-shared ssl-shared crypto-shared)
else()
set(OPENSSL_LIBS tls ssl crypto)
endif()
if(CMAKE_HOST_WIN32)
set(OPENSSL_LIBS ${OPENSSL_LIBS} ws2_32)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
check_library_exists(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME)
if (HAVE_CLOCK_GETTIME)
set(OPENSSL_LIBS ${OPENSSL_LIBS} rt)
endif()
endif()
if(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
set(OPENSSL_LIBS ${OPENSSL_LIBS} pthread)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
set(OPENSSL_LIBS ${OPENSSL_LIBS} nsl socket)
endif()
check_type_size(time_t SIZEOF_TIME_T)
if(SIZEOF_TIME_T STREQUAL "4")
set(SMALL_TIME_T true)
add_definitions(-DSMALL_TIME_T)
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})
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(tls)
add_subdirectory(include)

133
COPYING Normal file
View File

@ -0,0 +1,133 @@
LibReSSL files are retained under the copyright of the authors. New
additions are ISC licensed as per OpenBSD's normal licensing policy,
or are placed in the public domain.
The OpenSSL code is distributed under the terms of the original OpenSSL
licenses which follow:
LICENSE ISSUES
==============
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit.
See below for the actual license texts. In case of any license issues
related to OpenSSL please contact openssl-core@openssl.org.
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/

950
ChangeLog Normal file
View File

@ -0,0 +1,950 @@
Because this project is maintained both in the OpenBSD tree using CVS and in
Git, it can be confusing following all of the changes.
Most of the libssl and libcrypto source code is is here in OpenBSD CVS:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libssl/
Some of the libcrypto and OS-compatibility files for entropy and random number
generation are here:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libcrypto/
A simplified TLS wrapper library is here:
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libtls/
The LibreSSL Portable project copies these portions of the OpenBSD tree, along
with relevant portions of the C library, to a Git repository. This makes it
easier to follow all of the relevant changes to the upstream project in a
single place:
https://github.com/libressl-portable/openbsd
The portable bits of the project are largely maintained out-of-tree, and their
history is also available from Git.
https://github.com/libressl-portable/portable
LibreSSL Portable Release Notes:
2.6.4 - Bug fixes
* Make tls_config_parse_protocols() work correctly when passed a NULL
pointer for a protocol string. Issue found by semarie@, who also
provided the diff.
* Correct TLS extensions handling when no extensions are present.
If no TLS extensions are present in a client hello or server hello,
omit the entire extensions block, rather than including it with a
length of zero. Thanks to Eric Elena <eric at voguemerry dot com> for
providing packet captures and testing the fix.
* Fixed portable builds on older Android systems, and systems with out
IPV6_TCLASS support.
2.6.3 - OpenBSD 6.2 Release
* No core changes from LibreSSL 2.6.2
* Minor compatibility fixes in portable version.
2.6.2 - Bug fixes
* Provide a useful error with libtls if there are no OCSP URLs in a
peer certificate.
* Keep track of which keypair is in use by a TLS context, fixing a bug
where a TLS server with SNI would only return the OCSP staple for the
default keypair. Issue reported by William Graeber and confirmed by
Andreas Bartelt.
* Fixed various issues in the OCSP extension parsing code.
The original code incorrectly passes the pointer allocated via
CBS_stow() (using malloc()) to a d2i_*() function and then calls
free() on the now incremented pointer, most likely resulting in a
crash. This issue was reported by Robert Swiecki who found the issue
using honggfuzz.
* If tls_config_parse_protocols() is called with a NULL pointer,
return the default protocols instead of crashing - this makes the
behaviour more useful and mirrors what we already do in
tls_config_set_ciphers() et al.
2.6.1 - Code removal, rewrites
* Added a "-T tlscompat" option to nc(1), which enables the use of all
TLS protocols and "compat" ciphers. This allows for TLS connections
to TLS servers that are using less than ideal cipher suites, without
having to resort to "-T tlsall" which enables all known cipher
suites. Diff from Kyle J. McKay.
* Added a new TLS extension handling framework, somewhat analogous to
BoringSSL, and converted all TLS extensions to use it. Added new TLS
extension regression tests.
* Improved and added many new manpages. Updated *check_private_key
manpages with additional cautions regarding their use.
* Cleaned up the EC key/curve configuration handling.
* Added tls_config_set_ecdhecurves() to libtls, which allows the names
of the eliptical curves that may be used during client and server
key exchange to be specified.
* Converted more code paths to use CBB/CBS.
* Removed support for DSS/DSA, since we removed the cipher suites a
while back.
* Removed NPN support. NPN was never standardised and the last draft
expired in October 2012. ALPN was standardised in July 2014 and has
been supported in LibreSSL since December 2014. NPN has also been
removed from Chromium in May 2016.
* Removed SSL_OP_CRYPTOPRO_TLSEXT_BUG workaround for old/broken
CryptoPro clients.
* Removed support for the TLS padding extension, which was added as a
workaround for an old bug in F5's TLS termination.
* Worked around another bug in F5's TLS termination handling of the
elliptical curves extension. RFC 4492 only defines elliptic_curves
for ClientHello. However, F5 is sending it in ServerHello. We need
to skip over it since our TLS extension parsing code is now more
strict. Thanks to Armin Wolfermann and WJ Liu for reporting.
* Added ability to clamp notafter valies in certificates for systems
with 32-bit time_t. This is necessary to conform to RFC 5280
4.1.2.5.
* Implemented the SSL_CTX_set_min_proto_version(3) API.
* Removed the original (pre-IETF) chacha20-poly1305 cipher suites.
* Reclassified ECDHE-RSA-DES-CBC3-SHA from HIGH to MEDIUM.
2.6.0 - New APIs, bug fixes and improvements
* Added support for providing CRLs to libtls. Once a CRL is provided we
enable CRL checking for the full certificate chain. Based on a diff
from Jack Burton
* Allow non-compliant clients using IP literal addresses with SNI
to connect to a server using libtls.
* Avoid a potential NULL pointer dereference in d2i_ECPrivateKey().
Reported by Robert Swiecki, who found the issue using honggfuzz.
* Added definitions for three OIDs used in EV certificates.
From Kyle J. McKay
* Added tls_peer_cert_chain_pem to libtls, useful in private
certificate validation callbacks such as those in relayd.
* Converted explicit clear/free sequences to use freezero(3).
* Reworked TLS certificate name verification code to more strictly
follow RFC 6125.
* Cleaned up and simplified server key exchange EC point handling.
* Added tls_keypair_clear_key for clearing key material.
* Removed inconsistent IPv6 handling from BIO_get_accept_socket,
simplified BIO_get_host_ip and BIO_accept.
* Fixed the openssl(1) ca command so that is generates certificates
with RFC 5280-conformant time. Problem noticed by Harald Dunkel.
* Added ASN1_TIME_set_tm to set an asn1 from a struct tm *
* Added SSL{,_CTX}_set_{min,max}_proto_version() functions.
* Added HKDF (HMAC Key Derivation Function) from BoringSSL
* Provided a tls_unload_file() function that frees the memory returned
from a tls_load_file() call, ensuring that it the contents become
inaccessible. This is specifically needed on platforms where the
library allocators may be different from the application allocator.
* Perform reference counting for tls_config. This allows
tls_config_free() to be called as soon as it has been passed to the
final tls_configure() call, simplifying lifetime tracking for the
application.
* Moved internal state of SSL and other structures to be opaque.
* Dropped cipher suites with DSS authentication.
* nc(1) improvements, including:
nc -W to terminate nc after receiving a number of packets
nc -Z for saving the peer certificate and chain in a pem file
2.5.5 - Bug fixes
* Distinguish between self-issued certificates and self-signed
certificates. The certificate verification code has special cases
for self-signed certificates and without this change, self-issued
certificates (which it seems are common place with
openvpn/easyrsa) were also being included in this category.
* Added getpagesize fallback, needed for Android bionic libc.
2.5.4 - Security Updates
* Revert a previous change that forced consistency between return
value and error code when specifing a certificate verification
callback, since this breaks the documented API. When a user supplied
callback always returns 1, and later code checks the error code to
potentially abort post verification, this will result in incorrect
successul certificate verification.
* Switched Linux getrandom() usage to non-blocking mode, continuing to
use fallback mechanims if unsuccessful. This works around a design
flaw in Linux getrandom(2) where early boot usage in a library makes
it impossible to recover if getrandom(2) is not yet initialized.
* Fixed a bug caused by the return value being set early to signal
successful DTLS cookie validation. This can mask a later failure and
result in a positive return value being returned from
ssl3_get_client_hello(), when it should return a negative value to
propagate the error.
* Fixed a build error on non-x86/x86_64 systems running Solaris.
2.5.3 - OpenBSD 6.1 Release
* Documentation updates
* Improved ocspcheck(1) error handling
2.5.2 - Security features and bugfixes
* Added the recallocarray(3) memory allocation function, and converted
various places in the library to use it, such as CBB and BUF_MEM_grow.
recallocarray(3) is similar to reallocarray. Newly allocated memory
is cleared similar to calloc(3). Memory that becomes unallocated
while shrinking or moving existing allocations is explicitly
discarded by unmapping or clearing to 0
* Added new root CAs from SECOM Trust Systems / Security Communication
of Japan.
* Added EVP interface for MD5+SHA1 hashes.
* Fixed DTLS client failures when the server sends a certificate
request.
* Correct handling of padding when upgrading an SSLv2 challenge into
an SSLv3/TLS connection.
* Allow protocols and ciphers to be set on a TLS config object in
libtls.
* Improved nc(1) TLS handshake CPU usage and server-side error
reporting.
2.5.1 - Bug and security fixes, new features, documentation updates
* X509_cmp_time() now passes a malformed GeneralizedTime field as an
error. Reported by Theofilos Petsios.
* Detect zero-length encrypted session data early, instead of when
malloc(0) fails or the HMAC check fails. Noted independently by
jsing@ and Kurt Cancemi.
* Check for and handle failure of HMAC_{Update,Final} or
EVP_DecryptUpdate().
* Massive update and normalization of manpages, conversion to
mandoc format. Many pages were rewritten for clarity and accuracy.
Portable doc links are up-to-date with a new conversion tool.
* Curve25519 Key Exchange support.
* Support for alternate chains for certificate verification.
* Code cleanups, CBS conversions, further unification of DTLS/SSL
handshake code, further ASN1 macro expansion and removal.
* Private symbol are now hidden in libssl and libcryto.
* Friendly certificate verification error messages in libtls, peer
verification is now always enabled.
* Added OCSP stapling support to libtls and netcat.
* Added ocspcheck utility to validate a certificate against its OCSP
responder and save the reply for stapling
* Enhanced regression tests and error handling for libtls.
* Added explicit constant and non-constant time BN functions,
defaulting to constant time wherever possible.
* Moved many leaked implementation details in public structs behind
opaque pointers.
* Added ticket support to libtls.
* Added support for setting the supported EC curves via
SSL{_CTX}_set1_groups{_list}() - also provide defines for the previous
SSL{_CTX}_set1_curves{_list} names. This also changes the default
list of curves to be X25519, P-256 and P-384. All other curves must
be manually enabled.
* Added -groups option to openssl(1) s_client for specifying the curves
to be used in a colon-separated list.
* Merged client/server version negotiation code paths into one,
reducing much duplicate code.
* Removed error function codes from libssl and libcrypto.
* Fixed an issue where a truncated packet could crash via an OOB read.
* Added SSL_OP_NO_CLIENT_RENEGOTIATION option that disallows
client-initiated renegotiation. This is the default for libtls
servers.
* Avoid a side-channel cache-timing attack that can leak the ECDSA
private keys when signing. This is due to BN_mod_inverse() being
used without the constant time flag being set. Reported by Cesar
Pereida Garcia and Billy Brumley (Tampere University of Technology).
The fix was developed by Cesar Pereida Garcia.
* iOS and MacOS compatibility updates from Simone Basso and Jacob
Berkman.
2.5.0 - New APIs, bug fixes and improvements
* libtls now supports ALPN and SNI
* libtls adds a new callback interface for integrating custom IO
functions. Thanks to Tobias Pape.
* libtls now handles 4 cipher suite groups:
"secure" (TLSv1.2+AEAD+PFS)
"compat" (HIGH:!aNULL)
"legacy" (HIGH:MEDIUM:!aNULL)
"insecure" (ALL:!aNULL:!eNULL)
This allows for flexibility and finer grained control, rather than
having two extremes (an issue raised by Marko Kreen some time ago).
* Tightened error handling for tls_config_set_ciphers().
* libtls now always loads CA, key and certificate files at the time the
configuration function is called. This simplifies code and results in
a single memory based code path being used to provide data to libssl.
* Add support for OCSP intermediate certificates.
* Added functions used by stunnel and exim from BoringSSL - this
brings in X509_check_host, X509_check_email, X509_check_ip, and
X509_check_ip_asc.
* Added initial support for iOS, thanks to Jacob Berkman.
* Improved behavior of arc4random on Windows when using memory leak
analysis software.
* Correctly handle an EOF that occurs prior to the TLS handshake
completing. Reported by Vasily Kolobkov, based on a diff from Marko
Kreen.
* Limit the support of the "backward compatible" ssl2 handshake to
only be used if TLS 1.0 is enabled.
* Fix incorrect results in certain cases on 64-bit systems when
BN_mod_word() can return incorrect results. BN_mod_word() now can
return an error condition. Thanks to Brian Smith.
* Added constant-time updates to address CVE-2016-0702
* Fixed undefined behavior in BN_GF2m_mod_arr()
* Removed unused Cryptographic Message Support (CMS)
* More conversions of long long idioms to time_t
* Improved compatibility by avoiding printing NULL strings with
printf.
* Reverted change that cleans up the EVP cipher context in
EVP_EncryptFinal() and EVP_DecryptFinal(). Some software relies on the
previous behaviour.
* Avoid unbounded memory growth in libssl, which can be triggered by a
TLS client repeatedly renegotiating and sending OCSP Status Request
TLS extensions.
* Avoid falling back to a weak digest for (EC)DH when using SNI with
libssl.
2.4.2 - Bug fixes and improvements
* Fixed loading default certificate locations with openssl s_client.
* Ensured OCSP only uses and compares GENERALIZEDTIME values as per
RFC6960. Also added fixes for OCSP to work with intermediate
certificates provided in responses.
* Improved behavior of arc4random on Windows to not appear to leak
memory in debug tools, reduced privileges of allocated memory.
* Fixed incorrect results from BN_mod_word() when the modulus is too
large, thanks to Brian Smith from BoringSSL.
* Correctly handle an EOF prior to completing the TLS handshake in
libtls.
* Improved libtls ceritificate loading and cipher string validation.
* Updated libtls cipher group suites into four categories:
"secure" (TLSv1.2+AEAD+PFS)
"compat" (HIGH:!aNULL)
"legacy" (HIGH:MEDIUM:!aNULL)
"insecure" (ALL:!aNULL:!eNULL)
This allows for flexibility and finer grained control, rather than
having two extremes.
* Limited support for 'backward compatible' SSLv2 handshake packets to
when TLS 1.0 is enabled, providing more restricted compatibility
with TLS 1.0 clients.
* openssl(1) and other documentation improvements.
* Removed flags for disabling constant-time operations.
This removes support for DSA_FLAG_NO_EXP_CONSTTIME,
DH_FLAG_NO_EXP_CONSTTIME, and RSA_FLAG_NO_CONSTTIME flags, making
all of these operations unconditionally constant-time.
2.4.1 - Security fix
* Correct a problem that prevents the DSA signing algorithm from
running in constant time even if the flag BN_FLG_CONSTTIME is set.
This issue was reported by Cesar Pereida (Aalto University), Billy
Brumley (Tampere University of Technology), and Yuval Yarom (The
University of Adelaide and NICTA). The fix was developed by Cesar
Pereida.
2.4.0 - Build improvements, new features
* Many improvements to the CMake build infrastructure, including
Solaris, mingw-w64, Cygwin, and HP-UX support. Thanks to Kinichiro
Inoguchi for this work.
* Added missing error handling around bn_wexpand() calls.
* Added explicit_bzero calls for freed ASN.1 objects.
* Fixed X509_*set_object functions to return 0 on allocation failure.
* Implemented the IETF ChaCha20-Poly1305 cipher suites.
* Changed default EVP_aead_chacha20_poly1305() implementation to the
IETF version, which is now the default.
* Fixed password prompts from openssl(1) to properly handle ^C.
* Reworked error handling in libtls so that configuration errors are
visible.
* Deprecated internal use of EVP_[Cipher|Encrypt|Decrypt]_Final.
* Manpage fixes and updates
2.3.5 - Reliability fix
* Fixed an error in libcrypto when parsing some ASN.1 elements > 16k.
2.3.4 - Security Update
* Fix multiple vulnerabilities in libcrypto relating to ASN.1 and encoding.
From OpenSSL.
* Minor build fixes
2.3.3 - OpenBSD 5.9 release branch tagged
* Reworked build scripts to better sync with OpenNTPD-portable
* Fixed broken manpage links
* Fixed an nginx compatibility issue by adding an 'install_sw' make alias
* Fixed HP-UX builds
* Changed the default configuration directory to c:\LibreSSL\ssl on Windows
binary builds
* cert.pem has been reorganized and synced with Mozilla's certificate store
2.3.2 - Compatibility and Reliability fixes
* Changed format of LIBRESSL_VERSION_NUMBER to match that of
OPENSSL_VERSION_NUMBER, see:
https://wiki.openssl.org/index.php/Manual:OPENSSL_VERSION_NUMBER(3)
* Added EVP_aead_chacha20_poly1305_ietf() which matches the AEAD
construction introduced in RFC 7539, which is different than that
already used in TLS with EVP_aead_chacha20_poly1305()
* Avoid a potential undefined C99+ behavior due to shift overflow in
AES_decrypt, reported by Pascal Cuoq <cuoq at trust-in-soft.com>
* More man pages converted from pod to mdoc format
* Added COMODO RSA Certification Authority and QuoVadis
root certificates to cert.pem
* Removed Remove "C=US, O=VeriSign, Inc., OU=Class 3 Public Primary Certification
Authority" (serial 3c:91:31:cb:1f:f6:d0:1b:0e:9a:b8:d0:44:bf:12:be) root
certificate from cert.pem
* Added support for building nc(1) on Solaris
* Fixed GCC 5.x+ preprocessor checks, reported by Ruslan Babayev
* Improved console handling with openssl(1) on Windows
* Ensure the network stack is enabled on Windows when running
tls_init()
* Fixed incorrect TLS certificate loading by nc(1)
* Added support for Solaris 11.3's getentropy(2) system call
* Enabled support for using NetBSD 7.0's arc4random(3) implementation
* Deprecated the SSL_OP_SINGLE_DH_USE flag by disabling its effect
* Fixes from OpenSSL 1.0.1q
- CVE-2015-3194 - NULL pointer dereference in client side certificate
validation.
- CVE-2015-3195 - Memory leak in PKCS7 - not reachable from TLS/SSL
* The following OpenSSL CVEs did not apply to LibreSSL
- CVE-2015-3193 - Carry propagating bug in the x86_64 Montgomery
squaring procedure.
- CVE-2015-3196 - Double free race condition of the identify hint
data.
See https://marc.info/?l=openbsd-announce&m=144925068504102
2.3.1 - ASN.1 and time handling cleanups
* ASN.1 cleanups and RFC5280 compliance fixes.
* Time representations switched from 'unsigned long' to 'time_t'. LibreSSL
now checks if the host OS supports 64-bit time_t.
* Fixed a leak in SSL_new in the error path.
* Support always extracting the peer cipher and version with libtls.
* Added ability to check certificate validity times with libtls,
tls_peer_cert_notbefore and tls_peer_cert_notafter.
* Changed tls_connect_servername to use the first address that resolves with
getaddrinfo().
* Remove broken conditional EVP_CHECK_DES_KEY code (non-functional since
initial commit in 2004).
* Fixed a memory leak and out-of-bounds access in OBJ_obj2txt, reported
by Qualys Security.
* Fixed an up-to 7 byte overflow in RC4 when len is not a multiple of
sizeof(RC4_CHUNK), reported by Pascal Cuoq <cuoq at trust-in-soft.com>.
* Reject too small bits value in BN_generate_prime_ex(), so that it does
not risk becoming negative in probable_prime_dh_safe(), reported by
Franck Denis.
* Enable nc(1) builds on more platforms.
2.3.0 - SSLv3 removed, libtls API changes, portability improvements
* SSLv3 is now permanently removed from the tree.
* The libtls API is changed from the 2.2.x series.
The read/write functions work correctly with external event
libraries. See the tls_init man page for examples of using libtls
correctly in asynchronous mode.
Client-side verification is now supported, with the client supplying
the certificate to the server.
Also, when using tls_connect_fds, tls_connect_socket or
tls_accept_fds, libtls no longer implicitly closes the passed in
sockets. The caller is responsible for closing them in this case.
* When loading a DSA key from an raw (without DH parameters) ASN.1
serialization, perform some consistency checks on its `p' and `q'
values, and return an error if the checks failed.
Thanks for Georgi Guninski (guninski at guninski dot com) for
mentioning the possibility of a weak (non prime) q value and
providing a test case.
See
https://cpunks.org/pipermail/cypherpunks/2015-September/009007.html
for a longer discussion.
* Fixed a bug in ECDH_compute_key that can lead to silent truncation
of the result key without error. A coding error could cause software
to use much shorter keys than intended.
* Removed support for DTLS_BAD_VER. Pre-DTLSv1 implementations are no
longer supported.
* The engine command and parameters are removed from the openssl(1).
Previous releases removed dynamic and builtin engine support
already.
* SHA-0 is removed, which was withdrawn shortly after publication 20
years ago.
* Added Certplus CA root certificate to the default cert.pem file.
* New interface OPENSSL_cpu_caps is provided that does not allow
software to inadvertently modify cpu capability flags.
OPENSSL_ia32cap and OPENSSL_ia32cap_loc are removed.
* The out_len argument of AEAD changed from ssize_t to size_t.
* Deduplicated DTLS code, sharing bugfixes and improvements with
TLS.
* Converted 'nc' to use libtls for client and server operations; it is
included in the libressl-portable distribution as an example of how
to use the library.
2.2.3 - Bug fixes, build enhancements
* LibreSSL 2.2.2 incorrectly handles ClientHello messages that do not
include TLS extensions, resulting in such handshakes being aborted.
This release corrects the handling of such messages. Thanks to
Ligushka from github for reporting the issue.
* Added install target for cmake builds. Thanks to TheNietsnie from
github.
* Updated pkgconfig files to correctly report the release version
number, not the individual library ABI version numbers. Thanks to
Jan Engelhardt for reporting the issue.
2.2.2 - More TLS parser rework, bug fixes, expanded portable build support
* Switched 'openssl dhparam' default from 512 to 2048 bits
* Reworked openssl(1) option handling
* More CRYPTO ByteString (CBC) packet parsing conversions
* Fixed 'openssl pkeyutl -verify' to exit with a 0 on success
* Fixed dozens of Coverity issues including dead code, memory leaks,
logic errors and more.
* Ensure that openssl(1) restores terminal echo state after reading a
password.
* Incorporated fix for OpenSSL Issue #3683
* LibreSSL version define LIBRESSL_VERSION_NUMBER will now be bumped
for each portable release.
* Removed workarounds for TLS client padding bugs.
* No longer disable ECDHE-ECDSA on OS X
* Removed SSLv3 support from openssl(1)
* Removed IE 6 SSLv3 workarounds.
* Modified tls_write in libtls to allow partial writes, clarified with
examples in the documentation.
* Removed RSAX engine
* Tested SSLv3 removal with the OpenBSD ports tree and found several
applications that were not ready to build without SSLv3 yet. For
now, building a program that intentionally uses SSLv3 will result in
a linker warning.
* Added TLS_method, TLS_client_method and TLS_server_method as a
replacement for the SSLv23_*method calls.
* Added initial cmake build support, including support for building with
Visual Studio, currently tested with Visual Studio 2013 Community
Edition.
* --with-enginesdir is removed as a configuration parameter
* Default cert.pem, openssl.cnf, and x509v3.cnf files are now
installed under $sysconfdir/ssl or the directory specified by
--with-openssldir. Previous versions of LibreSSL left these empty.
2.2.1 - Build fixes, feature added, features removed
* Assorted build fixes for musl, HP-UX, Mingw, Solaris.
* Initial support for Windows Embedded 2009, Server 2003, XP
* Protocol parsing conversions to BoringSSL's CRYPTO ByteString (CBS) API
* Added EC_curve_nid2nist and EC_curve_nist2nid from OpenSSL
* Removed Dynamic Engine support
* Removed unused and obsolete MDC-2DES cipher
* Removed workarounds for obsolete SSL implementations
2.2.0 - Build cleanups and new OS support, Security Updates
* AIX Support - thanks to Michael Felt
* Cygwin Support - thanks to Corinna Vinschen
* Refactored build macros, support packaging libtls independently.
There are more pieces required to support building and using OpenSSL
with libtls, but this is an initial start at providing an
independent package for people to start hacking on.
* Removal of OPENSSL_issetugid and all library getenv calls.
Applications can and should no longer rely on environment variables
for changing library behavior. OPENSSL_CONF/SSLEAY_CONF is still
supported with the openssl(1) command.
* libtls API and documentation additions
* Various bug fixes and simplifications to libssl and libcrypto
* Fixes for the following issues are integrated into LibreSSL 2.2.0:
- CVE-2015-1788 - Malformed ECParameters causes infinite loop
- CVE-2015-1789 - Exploitable out-of-bounds read in X509_cmp_time
- CVE-2015-1792 - CMS verify infinite loop with unknown hash function
* The following CVEs did not apply to LibreSSL or were fixed in
earlier releases:
- CVE-2015-4000 - DHE man-in-the-middle protection (Logjam)
- CVE-2015-1790 - PKCS7 crash with missing EnvelopedContent
- CVE-2014-8176 - Invalid free in DTLS
* Fixes for the following CVEs are still in review for LibreSSL
- CVE-2015-1791 - Race condition handling NewSessionTicket
2.1.6 - Security update
* Fixes for the following issues are integrated into LibreSSL 2.1.6:
- CVE-2015-0209 - Use After Free following d2i_ECPrivatekey error
- CVE-2015-0286 - Segmentation fault in ASN1_TYPE_cmp
- CVE-2015-0287 - ASN.1 structure reuse memory corruption
- CVE-2015-0288 - X509_to_X509_REQ NULL pointer deref
- CVE-2015-0289 - PKCS7 NULL pointer dereferences
* The fix for CVE-2015-0207 - Segmentation fault in DTLSv1_listen
is integrated for safety, but LibreSSL is not vulnerable.
* Libtls is now built by default. The --enable-libtls
configuration option is no longer required.
The libtls API is now stable for the 2.1.x series.
2.1.5 - Bug fixes and a security update
* Fix incorrect comparison function in openssl(1) certhash command.
Thanks to Christian Neukirchen / Void Linux.
* Windows port improvements and bug fixes.
- Removed a dependency on libgcc in 32-bit dynamic libraries.
- Correct a hang in openssl(1) reading from stdin on an connection.
- Initialize winsock in openssl(1) earlier, allow 'openssl ocsp' and
any other network-related commands to function properly.
* Reject all server DH keys smaller than 1024 bits.
2.1.4 - Security and feature updates
* Improvements to libtls:
- a new API for loading CA chains directly from memory instead of a
file, allowing verification with privilege separation in a chroot
without direct access to CA certificate files.
- Ciphers default to TLSv1.2 with AEAD and PFS.
- Improved error handling and message generation
- New APIs and improved documentation
* Added X509_STORE_load_mem API for loading certificates from memory.
This facilitates accessing certificates from a chrooted environment.
* New AEAD "MAC alias" allows configuring TLSv1.2 AEAD ciphers by
using 'TLSv1.2+AEAD' as the cipher selection string.
* Dead and disabled code removal including MD5, Netscape workarounds,
non-POSIX IO, SCTP, RFC 3779 support, many #if 0 sections, and more.
* ASN1 macro maze expanded to aid reading and searching the code.
* NULL pointer asserts removed in favor of letting the OS/signal
handler catch them.
* Refactored argument handling in openssl(1) for consistency and
maintainability.
* New openssl(1) command 'certhash' replaces the c_rehash script.
* Support for building with OPENSSL_NO_DEPRECATED
* Server-side support for TLS_FALLBACK_SCSV for compatibility with
various auditor and vulnerability scanners.
* Dozens of issues found with the Coverity scanner fixed.
* Security Updates:
- Fix a minor information leak that was introduced in t1_lib.c
r1.71, whereby an additional 28 bytes of .rodata (or .data) is
provided to the network. In most cases this is a non-issue since
the memory content is already public. Issue found and reported by
Felix Groebert of the Google Security Team.
- Fixes for the following low-severity issues were integrated into
LibreSSL from OpenSSL 1.0.1k:
CVE-2015-0205 - DH client certificates accepted without
verification
CVE-2014-3570 - Bignum squaring may produce incorrect results
CVE-2014-8275 - Certificate fingerprints can be modified
CVE-2014-3572 - ECDHE silently downgrades to ECDH [Client]
Reported by Karthikeyan Bhargavan of the PROSECCO team at INRIA.
The following CVEs were fixed in earlier LibreSSL releases:
CVE-2015-0206 - Memory leak handling repeated DLTS records
CVE-2014-3510 - Flaw handling DTLS anonymous EC(DH) ciphersuites.
The following CVEs did not apply to LibreSSL:
CVE-2014-3571 - DTLS segmentation fault in dtls1_get_record
CVE-2014-3569 - no-ssl3 configuration sets method to NULL
CVE-2015-0204 - RSA silently downgrades to EXPORT_RSA
2.1.3 - Security update and OS support improvements
* Fixed various memory leaks in DTLS, including fixes for
CVE-2015-0206.
* Added Application-Layer Protocol Negotiation (ALPN) support.
* Removed GOST R 34.10-94 signature authentication.
* Removed nonfunctional Netscape browser-hang workaround code.
* Simplfied and refactored SSL/DTLS handshake code.
* Added SHA256 Camellia cipher suites for TLS 1.2 from RFC 5932.
* Hide timing info about padding errors during handshakes.
* Improved libtls support for non-blocking sockets, added randomized
session ID contexts. Work is ongoing with this library - feedback
and potential use-cases are welcome.
* Support building Windows DLLs.
Thanks to Jan Engelhard.
* Packaged config wrapper for better compatibility with OpenSSL-based
build systems.
Thanks to @technion from github
* Ensure the stack is marked non-executable for assembly sections.
Thanks to Anthony G. Bastile.
* Enable extra compiler hardening flags by default, where applicable.
The default set of hardening features can vary by OS to OS, so
feedback is welcome on this. To disable the default hardening flags,
specify '--disable-hardening' during configure.
Thanks to Jim Barlow
* Initial HP-UX support, tested with HP-UX 11.31 ia64
Thanks to Kinichiro Inoguchi
* Initial NetBSD support, tested with NetBSD 6.1.5 x86_64
Imported from OpenNTPD, thanks to @gitisihara from github
2.1.2 - Many new features and improvements
* Added reworked GOST cipher suite support
thanks to Dmitry Eremin-Solenikov
* Enabled Camellia ciphers due to improved patent situation
* Use builtin arc4random implementation on OS X and FreeBSD
this addresses some deficiencies in the native implementations of
these operating systems, see commit logs for more information
* Added initial Windows mingw-w64 support (32 and 64-bit)
thanks to Song Dongsheng and others for code and feedback
* Enabled assembly optimizations on x86_64 CPUs
supports Linux, *BSD, Solaris and OS X operating systems
thanks to Wouter Clarie for the initial implementation
* Added no_ssl3/no_tls1_1/no_tls1_2 options to openssl(1)
* Improved build infrastructure, 'make distcheck' now passes
this simplifies and speeds developer efficiency
thanks to Dmitry Eremin-Solenikov and Wouter Clarie
* Allow conditional building of the libtls library
expect the API and ABI of the library to change
feedback is welcome
* Fixes for more memory leaks, cleanups, etc.
2.1.1 - Security update
* Address POODLE attack by disabling SSLv3 by default
* Fix Eliptical Curve cipher selection bug
(https://github.com/libressl-portable/portable/issues/35)
2.1.0 - First release from the OpenBSD 5.7 tree
* Added support for automatic ephemeral EC keys
* Fixes for many memory leaks and overflows in error handlers
* The TLS padding extension (that works around bugs in F5 terminators) is
off by default
* support for getrandom(2) on Linux 3.17
* the NO_ASM macro is no longer being set, providing the first bits toward
enabling other assembly offloads.
2.0.5 - Fixes for CVEs from OpenSSL 1.0.1i
* CVE-2014-3506
* CVE-2014-3507
* CVE-2014-3508 (partially vulnerable)he
* CVE-2014-3509
* CVE-2014-3510
* CVE-2014-3511
* Synced LibreSSL Portable with the release version of OpenBSD 5.6
2.0.4 - Portability fixes, deleted unused SRP code
2.0.3 - Portability fixes, improvements to fork detection
2.0.2 - Address arc4random fork PID wraparound issues with pthread_atfork
2.0.1 - Portability fixes:
* Removed -Werror and and other non-portable compiler flags
* Allow setting OPENSSLDIR and ENGINSDIR
2.0.0 - First release from the OpenBSD 5.6 tree
* Removal of many obsolete features and coding conventions from the OpenSSL
1.0.1h source

370
INSTALL Normal file
View File

@ -0,0 +1,370 @@
Installation Instructions
*************************
Copyright (C) 1994-1996, 1999-2002, 2004-2013 Free Software Foundation,
Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell command `./configure && make && make install'
should configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
HP-UX `make' updates targets which have the same time stamps as
their prerequisites, which makes it generally unusable when shipped
generated files such as `configure' are involved. Use GNU `make'
instead.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf limitation. Until the limitation is lifted, you can use
this workaround:
CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

162
README.md Normal file
View File

@ -0,0 +1,162 @@
Official repository is development, not release versions of LibreSSL, and needs external applications to prepare for
build.
Built from https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.6.4.tar.gz
Modifications:
- Removed tests/mandocs/pkgconfig/scripts/apps/cmake_uninstall from both filesystem and CMakeLists.txt
- Removed m4 configuration files + make build scripts
===
![LibreSSL image](http://www.libressl.org/images/libressl.jpg)
## Official portable version of [LibreSSL](http://www.libressl.org) ##
[![Build Status](https://travis-ci.org/libressl-portable/portable.svg?branch=master)](https://travis-ci.org/libressl-portable/portable)
LibreSSL is a fork of [OpenSSL](https://www.openssl.org) 1.0.1g developed by the
[OpenBSD](http://www.openbsd.org) project. Our goal is to modernize the codebase,
improve security, and apply best practice development processes from OpenBSD.
## Compatibility with OpenSSL: ##
LibreSSL is API compatible with OpenSSL 1.0.1, but does not yet include all
new APIs from OpenSSL 1.0.2 and later. LibreSSL also includes APIs not yet
present in OpenSSL. The current common API subset is OpenSSL 1.0.1.
LibreSSL is not ABI compatible with any release of OpenSSL, or necessarily
earlier releases of LibreSSL. You will need to relink your programs to
LibreSSL in order to use it, just as in moving between major versions of OpenSSL.
LibreSSL's installed library version numbers are incremented to account for
ABI and API changes.
## Compatibility with other operating systems: ##
While primarily developed on and taking advantage of APIs available on OpenBSD,
the LibreSSL portable project attempts to provide working alternatives for
other operating systems, and assists with improving OS-native implementations
where possible.
At the time of this writing, LibreSSL is know to build and work on:
* Linux (kernel 3.17 or later recommended)
* FreeBSD (tested with 9.2 and later)
* NetBSD (7.0 or later recommended)
* HP-UX (11i)
* Solaris (11 and later preferred)
* Mac OS X (tested with 10.8 and later)
* AIX (5.3 and later)
LibreSSL also supports the following Windows environments:
* Microsoft Windows (XP or higher, x86 and x64)
* Wine (32-bit and 64-bit)
* Builds with Mingw-w64, Cygwin, and Visual Studio
Official release tarballs are available at your friendly neighborhood
OpenBSD mirror in directory
[LibreSSL](http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/),
although we suggest that you use a [mirror](http://www.openbsd.org/ftp.html).
The LibreSSL portable build framework is also
[mirrored](https://github.com/libressl-portable/portable) in Github.
Please report bugs either to the public libressl@openbsd.org mailing list,
or to the github
[issue tracker](https://github.com/libressl-portable/portable/issues)
Severe vulnerabilities or bugs requiring coordination with OpenSSL can be
sent to the core team at libressl-security@openbsd.org.
# Building LibreSSL #
## Prerequisites when building from a Git checkout ##
If you have checked this source using Git, or have downloaded a source tarball
from Github, follow these initial steps to prepare the source tree for
building. _Note: Your build will fail if you do not follow these instructions! If you cannot follow these instructions (e.g. Windows system using CMake) or cannot meet these prerequistes, please download an official release distribution from https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/ instead. Using official releases is strongly advised if you are not a developer._
1. Ensure you have the following packages installed:
automake, autoconf, git, libtool, perl
2. Run './autogen.sh' to prepare the source tree for building or
run './dist.sh' to prepare a tarball.
## Steps that apply to all builds ##
Once you have a source tree, either by downloaded using git and having
run the autogen.sh script above, or by downloading a release distribution from
an OpenBSD mirror, run these commands to build and install the package on most
systems:
```sh
./configure # see ./configure --help for configuration options
make check # runs builtin unit tests
make install # set DESTDIR= to install to an alternate location
```
If you wish to use the CMake build system, use these commands:
```sh
mkdir build
cd build
cmake ..
make
make test
```
For faster builds, you can use Ninja as well:
```sh
mkdir build-ninja
cd build-ninja
cmake -G"Ninja" ..
ninja
ninja test
```
### OS specific build information: ###
#### HP-UX (11i) ####
Set the UNIX_STD environment variable to '2003' before running 'configure'
in order to build with the HP C/aC++ compiler. See the "standards(5)" man
page for more details.
```sh
export UNIX_STD=2003
./configure
make
```
#### Windows - Mingw-w64 ####
LibreSSL builds against relatively recent versions of Mingw-w64, not to be
confused with the original mingw.org project. Mingw-w64 3.2 or later
should work. See README.windows for more information
#### Windows - Visual Studio ####
LibreSSL builds using the CMake target "Visual Studio 12 2013" and newer. To
generate a Visual Studio project, install CMake, enter the LibreSSL source
directory and run:
```sh
mkdir build-vs2013
cd build-vs2013
cmake -G"Visual Studio 12 2013" ..
```
Replace "Visual Studion 12 2013" with whatever version of Visual Studio you
have installed. This will generate a LibreSSL.sln file that you can incorporate
into other projects or build by itself.
#### Cmake - Additional Options ####
| Option Name | Default | Description
| ------------ | -----: | ------
| LIBRESSL_SKIP_INSTALL | OFF | allows skipping install() rules. Can be specified from command line using <br>```-DLIBRESSL_SKIP_INSTALL=ON``` |
| ENABLE_ASM | ON | builds assembly optimized rules. |
| ENABLE_EXTRATESTS | OFF | Enable extra tests that may be unreliable on some platforms |
| ENABLE_NC | OFF | Enable installing TLS-enabled nc(1) |
| ENABLE_VSTEST | OFF | Enable test on Visual Studio |
| OPENSSLDIR | Blank | Set the default openssl directory. Can be specified from command line using <br>```-DOPENSSLDIR=<dirname>``` |

2
VERSION Normal file
View File

@ -0,0 +1,2 @@
2.6.4

50
cmake_export_symbol.cmake Normal file
View File

@ -0,0 +1,50 @@
macro(export_symbol TARGET FILENAME)
set(FLAG "")
if(WIN32)
string(REPLACE ".sym" ".def" DEF_FILENAME ${FILENAME})
file(WRITE ${DEF_FILENAME} "EXPORTS\n")
file(READ ${FILENAME} SYMBOLS)
file(APPEND ${DEF_FILENAME} "${SYMBOLS}")
target_sources(${TARGET} PRIVATE ${DEF_FILENAME})
elseif(APPLE)
file(READ ${FILENAME} SYMBOLS)
string(REGEX REPLACE "\n$" "" SYMBOLS ${SYMBOLS})
string(REPLACE "\n" "\n_" SYMBOLS ${SYMBOLS})
string(REGEX REPLACE "(.)$" "\\1\\n" SYMBOLS ${SYMBOLS})
string(REPLACE ".sym" ".exp" EXP_FILENAME ${FILENAME})
file(WRITE ${EXP_FILENAME} "_${SYMBOLS}")
set(FLAG "-exported_symbols_list ${EXP_FILENAME}")
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS ${FLAG})
elseif(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
file(READ ${FILENAME} SYMBOLS)
string(REGEX REPLACE "\n$" "" SYMBOLS ${SYMBOLS})
string(REPLACE "\n" "\n+e " SYMBOLS ${SYMBOLS})
string(REPLACE ".sym" ".opt" OPT_FILENAME ${FILENAME})
file(WRITE ${OPT_FILENAME} "+e ${SYMBOLS}")
set(FLAG "-Wl,-c,${OPT_FILENAME}")
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS ${FLAG})
elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS")
file(READ ${FILENAME} SYMBOLS)
string(REPLACE "\n" ";\n" SYMBOLS ${SYMBOLS})
string(REPLACE ".sym" ".ver" VER_FILENAME ${FILENAME})
file(WRITE ${VER_FILENAME}
"{\nglobal:\n${SYMBOLS}\nlocal:\n*;\n};\n")
set(FLAG "-Wl,-M${VER_FILENAME}")
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS ${FLAG})
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
file(READ ${FILENAME} SYMBOLS)
string(REPLACE "\n" ";\n" SYMBOLS ${SYMBOLS})
string(REPLACE ".sym" ".ver" VER_FILENAME ${FILENAME})
file(WRITE ${VER_FILENAME}
"{\nglobal:\n${SYMBOLS}\nlocal:\n*;\n};\n")
set(FLAG "-Wl,--version-script,\"${VER_FILENAME}\"")
set_target_properties(${TARGET} PROPERTIES LINK_FLAGS ${FLAG})
endif()
endmacro()

836
crypto/CMakeLists.txt Normal file
View File

@ -0,0 +1,836 @@
include_directories(
.
../include
../include/compat
asn1
bn
dsa
evp
modes
)
if(HOST_ASM_ELF_X86_64)
set(
ASM_X86_64_ELF_SRC
aes/aes-elf-x86_64.S
aes/bsaes-elf-x86_64.S
aes/vpaes-elf-x86_64.S
aes/aesni-elf-x86_64.S
aes/aesni-sha1-elf-x86_64.S
bn/modexp512-elf-x86_64.S
bn/mont-elf-x86_64.S
bn/mont5-elf-x86_64.S
bn/gf2m-elf-x86_64.S
camellia/cmll-elf-x86_64.S
md5/md5-elf-x86_64.S
modes/ghash-elf-x86_64.S
rc4/rc4-elf-x86_64.S
rc4/rc4-md5-elf-x86_64.S
sha/sha1-elf-x86_64.S
sha/sha256-elf-x86_64.S
sha/sha512-elf-x86_64.S
whrlpool/wp-elf-x86_64.S
cpuid-elf-x86_64.S
)
add_definitions(-DAES_ASM)
add_definitions(-DBSAES_ASM)
add_definitions(-DVPAES_ASM)
add_definitions(-DOPENSSL_IA32_SSE2)
add_definitions(-DOPENSSL_BN_ASM_MONT)
add_definitions(-DOPENSSL_BN_ASM_MONT5)
add_definitions(-DOPENSSL_BN_ASM_GF2m)
add_definitions(-DMD5_ASM)
add_definitions(-DGHASH_ASM)
add_definitions(-DRSA_ASM)
add_definitions(-DSHA1_ASM)
add_definitions(-DSHA256_ASM)
add_definitions(-DSHA512_ASM)
add_definitions(-DWHIRLPOOL_ASM)
add_definitions(-DOPENSSL_CPUID_OBJ)
set(CRYPTO_SRC ${CRYPTO_SRC} ${ASM_X86_64_ELF_SRC})
set_property(SOURCE ${ASM_X86_64_ELF_SRC} PROPERTY LANGUAGE C)
endif()
if(HOST_ASM_MACOSX_X86_64)
set(
ASM_X86_64_MACOSX_SRC
aes/aes-macosx-x86_64.S
aes/bsaes-macosx-x86_64.S
aes/vpaes-macosx-x86_64.S
aes/aesni-macosx-x86_64.S
aes/aesni-sha1-macosx-x86_64.S
bn/modexp512-macosx-x86_64.S
bn/mont-macosx-x86_64.S
bn/mont5-macosx-x86_64.S
bn/gf2m-macosx-x86_64.S
camellia/cmll-macosx-x86_64.S
md5/md5-macosx-x86_64.S
modes/ghash-macosx-x86_64.S
rc4/rc4-macosx-x86_64.S
rc4/rc4-md5-macosx-x86_64.S
sha/sha1-macosx-x86_64.S
sha/sha256-macosx-x86_64.S
sha/sha512-macosx-x86_64.S
whrlpool/wp-macosx-x86_64.S
cpuid-macosx-x86_64.S
)
add_definitions(-DAES_ASM)
add_definitions(-DBSAES_ASM)
add_definitions(-DVPAES_ASM)
add_definitions(-DOPENSSL_IA32_SSE2)
add_definitions(-DOPENSSL_BN_ASM_MONT)
add_definitions(-DOPENSSL_BN_ASM_MONT5)
add_definitions(-DOPENSSL_BN_ASM_GF2m)
add_definitions(-DMD5_ASM)
add_definitions(-DGHASH_ASM)
add_definitions(-DRSA_ASM)
add_definitions(-DSHA1_ASM)
add_definitions(-DSHA256_ASM)
add_definitions(-DSHA512_ASM)
add_definitions(-DWHIRLPOOL_ASM)
add_definitions(-DOPENSSL_CPUID_OBJ)
set(CRYPTO_SRC ${CRYPTO_SRC} ${ASM_X86_64_MACOSX_SRC})
set_property(SOURCE ${ASM_X86_64_MACOSX_SRC} PROPERTY LANGUAGE C)
endif()
if((NOT HOST_ASM_ELF_X86_64) AND (NOT HOST_ASM_MACOSX_X86_64))
set(
CRYPTO_SRC
${CRYPTO_SRC}
aes/aes_cbc.c
aes/aes_core.c
camellia/camellia.c
camellia/cmll_cbc.c
rc4/rc4_enc.c
rc4/rc4_skey.c
whrlpool/wp_block.c
)
endif()
set(
CRYPTO_SRC
${CRYPTO_SRC}
cpt_err.c
cryptlib.c
cversion.c
ex_data.c
malloc-wrapper.c
mem_clr.c
mem_dbg.c
o_init.c
o_str.c
o_time.c
aes/aes_cfb.c
aes/aes_ctr.c
aes/aes_ecb.c
aes/aes_ige.c
aes/aes_misc.c
aes/aes_ofb.c
aes/aes_wrap.c
asn1/a_bitstr.c
asn1/a_bool.c
asn1/a_bytes.c
asn1/a_d2i_fp.c
asn1/a_digest.c
asn1/a_dup.c
asn1/a_enum.c
asn1/a_i2d_fp.c
asn1/a_int.c
asn1/a_mbstr.c
asn1/a_object.c
asn1/a_octet.c
asn1/a_print.c
asn1/a_set.c
asn1/a_sign.c
asn1/a_strex.c
asn1/a_strnid.c
asn1/a_time.c
asn1/a_time_tm.c
asn1/a_type.c
asn1/a_utf8.c
asn1/a_verify.c
asn1/ameth_lib.c
asn1/asn1_err.c
asn1/asn1_gen.c
asn1/asn1_lib.c
asn1/asn1_par.c
asn1/asn_mime.c
asn1/asn_moid.c
asn1/asn_pack.c
asn1/bio_asn1.c
asn1/bio_ndef.c
asn1/d2i_pr.c
asn1/d2i_pu.c
asn1/evp_asn1.c
asn1/f_enum.c
asn1/f_int.c
asn1/f_string.c
asn1/i2d_pr.c
asn1/i2d_pu.c
asn1/n_pkey.c
asn1/nsseq.c
asn1/p5_pbe.c
asn1/p5_pbev2.c
asn1/p8_pkey.c
asn1/t_bitst.c
asn1/t_crl.c
asn1/t_pkey.c
asn1/t_req.c
asn1/t_spki.c
asn1/t_x509.c
asn1/t_x509a.c
asn1/tasn_dec.c
asn1/tasn_enc.c
asn1/tasn_fre.c
asn1/tasn_new.c
asn1/tasn_prn.c
asn1/tasn_typ.c
asn1/tasn_utl.c
asn1/x_algor.c
asn1/x_attrib.c
asn1/x_bignum.c
asn1/x_crl.c
asn1/x_exten.c
asn1/x_info.c
asn1/x_long.c
asn1/x_name.c
asn1/x_nx509.c
asn1/x_pkey.c
asn1/x_pubkey.c
asn1/x_req.c
asn1/x_sig.c
asn1/x_spki.c
asn1/x_val.c
asn1/x_x509.c
asn1/x_x509a.c
bf/bf_cfb64.c
bf/bf_ecb.c
bf/bf_enc.c
bf/bf_ofb64.c
bf/bf_skey.c
bio/b_dump.c
bio/b_print.c
bio/b_sock.c
bio/bf_buff.c
bio/bf_nbio.c
bio/bf_null.c
bio/bio_cb.c
bio/bio_err.c
bio/bio_lib.c
bio/bss_acpt.c
bio/bss_bio.c
bio/bss_conn.c
bio/bss_dgram.c
bio/bss_fd.c
bio/bss_file.c
bio/bss_mem.c
bio/bss_null.c
bio/bss_sock.c
bn/bn_add.c
bn/bn_asm.c
bn/bn_blind.c
bn/bn_const.c
bn/bn_ctx.c
bn/bn_depr.c
bn/bn_div.c
bn/bn_err.c
bn/bn_exp.c
bn/bn_exp2.c
bn/bn_gcd.c
bn/bn_gf2m.c
bn/bn_kron.c
bn/bn_lib.c
bn/bn_mod.c
bn/bn_mont.c
bn/bn_mpi.c
bn/bn_mul.c
bn/bn_nist.c
bn/bn_prime.c
bn/bn_print.c
bn/bn_rand.c
bn/bn_recp.c
bn/bn_shift.c
bn/bn_sqr.c
bn/bn_sqrt.c
bn/bn_word.c
bn/bn_x931p.c
buffer/buf_err.c
buffer/buf_str.c
buffer/buffer.c
camellia/cmll_cfb.c
camellia/cmll_ctr.c
camellia/cmll_ecb.c
camellia/cmll_misc.c
camellia/cmll_ofb.c
cast/c_cfb64.c
cast/c_ecb.c
cast/c_enc.c
cast/c_ofb64.c
cast/c_skey.c
chacha/chacha.c
cmac/cm_ameth.c
cmac/cm_pmeth.c
cmac/cmac.c
comp/c_rle.c
comp/c_zlib.c
comp/comp_err.c
comp/comp_lib.c
conf/conf_api.c
conf/conf_def.c
conf/conf_err.c
conf/conf_lib.c
conf/conf_mall.c
conf/conf_mod.c
conf/conf_sap.c
curve25519/curve25519-generic.c
curve25519/curve25519.c
des/cbc_cksm.c
des/cbc_enc.c
des/cfb64ede.c
des/cfb64enc.c
des/cfb_enc.c
des/des_enc.c
des/ecb3_enc.c
des/ecb_enc.c
des/ede_cbcm_enc.c
des/enc_read.c
des/enc_writ.c
des/fcrypt.c
des/fcrypt_b.c
des/ofb64ede.c
des/ofb64enc.c
des/ofb_enc.c
des/pcbc_enc.c
des/qud_cksm.c
des/rand_key.c
des/set_key.c
des/str2key.c
des/xcbc_enc.c
dh/dh_ameth.c
dh/dh_asn1.c
dh/dh_check.c
dh/dh_depr.c
dh/dh_err.c
dh/dh_gen.c
dh/dh_key.c
dh/dh_lib.c
dh/dh_pmeth.c
dh/dh_prn.c
dsa/dsa_ameth.c
dsa/dsa_asn1.c
dsa/dsa_depr.c
dsa/dsa_err.c
dsa/dsa_gen.c
dsa/dsa_key.c
dsa/dsa_lib.c
dsa/dsa_ossl.c
dsa/dsa_pmeth.c
dsa/dsa_prn.c
dsa/dsa_sign.c
dsa/dsa_vrf.c
dso/dso_dlfcn.c
dso/dso_err.c
dso/dso_lib.c
dso/dso_null.c
dso/dso_openssl.c
ec/ec2_mult.c
ec/ec2_oct.c
ec/ec2_smpl.c
ec/ec_ameth.c
ec/ec_asn1.c
ec/ec_check.c
ec/ec_curve.c
ec/ec_cvt.c
ec/ec_err.c
ec/ec_key.c
ec/ec_lib.c
ec/ec_mult.c
ec/ec_oct.c
ec/ec_pmeth.c
ec/ec_print.c
ec/eck_prn.c
ec/ecp_mont.c
ec/ecp_nist.c
ec/ecp_oct.c
ec/ecp_smpl.c
ecdh/ech_err.c
ecdh/ech_key.c
ecdh/ech_lib.c
ecdsa/ecs_asn1.c
ecdsa/ecs_err.c
ecdsa/ecs_lib.c
ecdsa/ecs_ossl.c
ecdsa/ecs_sign.c
ecdsa/ecs_vrf.c
engine/eng_all.c
engine/eng_cnf.c
engine/eng_ctrl.c
engine/eng_dyn.c
engine/eng_err.c
engine/eng_fat.c
engine/eng_init.c
engine/eng_lib.c
engine/eng_list.c
engine/eng_openssl.c
engine/eng_pkey.c
engine/eng_table.c
engine/tb_asnmth.c
engine/tb_cipher.c
engine/tb_dh.c
engine/tb_digest.c
engine/tb_dsa.c
engine/tb_ecdh.c
engine/tb_ecdsa.c
engine/tb_pkmeth.c
engine/tb_rand.c
engine/tb_rsa.c
engine/tb_store.c
err/err.c
err/err_all.c
err/err_prn.c
evp/bio_b64.c
evp/bio_enc.c
evp/bio_md.c
evp/c_all.c
evp/digest.c
evp/e_aes.c
evp/e_aes_cbc_hmac_sha1.c
evp/e_bf.c
evp/e_camellia.c
evp/e_cast.c
evp/e_chacha.c
evp/e_chacha20poly1305.c
evp/e_des.c
evp/e_des3.c
evp/e_gost2814789.c
evp/e_idea.c
evp/e_null.c
evp/e_old.c
evp/e_rc2.c
evp/e_rc4.c
evp/e_rc4_hmac_md5.c
evp/e_xcbc_d.c
evp/encode.c
evp/evp_aead.c
evp/evp_enc.c
evp/evp_err.c
evp/evp_key.c
evp/evp_lib.c
evp/evp_pbe.c
evp/evp_pkey.c
evp/m_dss.c
evp/m_dss1.c
evp/m_ecdsa.c
evp/m_gost2814789.c
evp/m_gostr341194.c
evp/m_md4.c
evp/m_md5.c
evp/m_md5_sha1.c
evp/m_null.c
evp/m_ripemd.c
evp/m_sha1.c
evp/m_sigver.c
evp/m_streebog.c
evp/m_wp.c
evp/names.c
evp/p5_crpt.c
evp/p5_crpt2.c
evp/p_dec.c
evp/p_enc.c
evp/p_lib.c
evp/p_open.c
evp/p_seal.c
evp/p_sign.c
evp/p_verify.c
evp/pmeth_fn.c
evp/pmeth_gn.c
evp/pmeth_lib.c
gost/gost2814789.c
gost/gost89_keywrap.c
gost/gost89_params.c
gost/gost89imit_ameth.c
gost/gost89imit_pmeth.c
gost/gost_asn1.c
gost/gost_err.c
gost/gostr341001.c
gost/gostr341001_ameth.c
gost/gostr341001_key.c
gost/gostr341001_params.c
gost/gostr341001_pmeth.c
gost/gostr341194.c
gost/streebog.c
hkdf/hkdf.c
hmac/hm_ameth.c
hmac/hm_pmeth.c
hmac/hmac.c
idea/i_cbc.c
idea/i_cfb64.c
idea/i_ecb.c
idea/i_ofb64.c
idea/i_skey.c
lhash/lh_stats.c
lhash/lhash.c
md4/md4_dgst.c
md4/md4_one.c
md5/md5_dgst.c
md5/md5_one.c
modes/cbc128.c
modes/ccm128.c
modes/cfb128.c
modes/ctr128.c
modes/cts128.c
modes/gcm128.c
modes/ofb128.c
modes/xts128.c
objects/o_names.c
objects/obj_dat.c
objects/obj_err.c
objects/obj_lib.c
objects/obj_xref.c
ocsp/ocsp_asn.c
ocsp/ocsp_cl.c
ocsp/ocsp_err.c
ocsp/ocsp_ext.c
ocsp/ocsp_ht.c
ocsp/ocsp_lib.c
ocsp/ocsp_prn.c
ocsp/ocsp_srv.c
ocsp/ocsp_vfy.c
pem/pem_all.c
pem/pem_err.c
pem/pem_info.c
pem/pem_lib.c
pem/pem_oth.c
pem/pem_pk8.c
pem/pem_pkey.c
pem/pem_seal.c
pem/pem_sign.c
pem/pem_x509.c
pem/pem_xaux.c
pem/pvkfmt.c
pkcs12/p12_add.c
pkcs12/p12_asn.c
pkcs12/p12_attr.c
pkcs12/p12_crpt.c
pkcs12/p12_crt.c
pkcs12/p12_decr.c
pkcs12/p12_init.c
pkcs12/p12_key.c
pkcs12/p12_kiss.c
pkcs12/p12_mutl.c
pkcs12/p12_npas.c
pkcs12/p12_p8d.c
pkcs12/p12_p8e.c
pkcs12/p12_utl.c
pkcs12/pk12err.c
pkcs7/bio_pk7.c
pkcs7/pk7_asn1.c
pkcs7/pk7_attr.c
pkcs7/pk7_doit.c
pkcs7/pk7_lib.c
pkcs7/pk7_mime.c
pkcs7/pk7_smime.c
pkcs7/pkcs7err.c
poly1305/poly1305.c
rand/rand_err.c
rand/rand_lib.c
rand/randfile.c
rc2/rc2_cbc.c
rc2/rc2_ecb.c
rc2/rc2_skey.c
rc2/rc2cfb64.c
rc2/rc2ofb64.c
ripemd/rmd_dgst.c
ripemd/rmd_one.c
rsa/rsa_ameth.c
rsa/rsa_asn1.c
rsa/rsa_chk.c
rsa/rsa_crpt.c
rsa/rsa_depr.c
rsa/rsa_eay.c
rsa/rsa_err.c
rsa/rsa_gen.c
rsa/rsa_lib.c
rsa/rsa_none.c
rsa/rsa_oaep.c
rsa/rsa_pk1.c
rsa/rsa_pmeth.c
rsa/rsa_prn.c
rsa/rsa_pss.c
rsa/rsa_saos.c
rsa/rsa_sign.c
rsa/rsa_x931.c
sha/sha1_one.c
sha/sha1dgst.c
sha/sha256.c
sha/sha512.c
stack/stack.c
ts/ts_asn1.c
ts/ts_conf.c
ts/ts_err.c
ts/ts_lib.c
ts/ts_req_print.c
ts/ts_req_utils.c
ts/ts_rsp_print.c
ts/ts_rsp_sign.c
ts/ts_rsp_utils.c
ts/ts_rsp_verify.c
ts/ts_verify_ctx.c
txt_db/txt_db.c
ui/ui_err.c
ui/ui_lib.c
ui/ui_util.c
whrlpool/wp_dgst.c
x509/by_dir.c
x509/by_file.c
x509/by_mem.c
x509/x509_att.c
x509/x509_cmp.c
x509/x509_d2.c
x509/x509_def.c
x509/x509_err.c
x509/x509_ext.c
x509/x509_lu.c
x509/x509_obj.c
x509/x509_r2x.c
x509/x509_req.c
x509/x509_set.c
x509/x509_trs.c
x509/x509_txt.c
x509/x509_v3.c
x509/x509_vfy.c
x509/x509_vpm.c
x509/x509cset.c
x509/x509name.c
x509/x509rset.c
x509/x509spki.c
x509/x509type.c
x509/x_all.c
x509v3/pcy_cache.c
x509v3/pcy_data.c
x509v3/pcy_lib.c
x509v3/pcy_map.c
x509v3/pcy_node.c
x509v3/pcy_tree.c
x509v3/v3_akey.c
x509v3/v3_akeya.c
x509v3/v3_alt.c
x509v3/v3_bcons.c
x509v3/v3_bitst.c
x509v3/v3_conf.c
x509v3/v3_cpols.c
x509v3/v3_crld.c
x509v3/v3_enum.c
x509v3/v3_extku.c
x509v3/v3_genn.c
x509v3/v3_ia5.c
x509v3/v3_info.c
x509v3/v3_int.c
x509v3/v3_lib.c
x509v3/v3_ncons.c
x509v3/v3_ocsp.c
x509v3/v3_pci.c
x509v3/v3_pcia.c
x509v3/v3_pcons.c
x509v3/v3_pku.c
x509v3/v3_pmaps.c
x509v3/v3_prn.c
x509v3/v3_purp.c
x509v3/v3_skey.c
x509v3/v3_sxnet.c
x509v3/v3_utl.c
x509v3/v3err.c
)
if(CMAKE_HOST_UNIX)
set(CRYPTO_SRC ${CRYPTO_SRC} bio/b_posix.c)
set(CRYPTO_SRC ${CRYPTO_SRC} bio/bss_log.c)
set(CRYPTO_SRC ${CRYPTO_SRC} ui/ui_openssl.c)
endif()
if(CMAKE_HOST_WIN32)
set(CRYPTO_SRC ${CRYPTO_SRC} bio/b_win.c)
set(CRYPTO_UNEXPORT ${CRYPTO_UNEXPORT} BIO_s_log)
set(CRYPTO_SRC ${CRYPTO_SRC} ui/ui_openssl_win.c)
endif()
if(CMAKE_HOST_WIN32)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/posix_win.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} gettimeofday)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_perror)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_fopen)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_fgets)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_open)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_rename)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_connect)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_close)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_read)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_write)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_getsockopt)
set(EXTRA_EXPORT ${EXTRA_EXPORT} posix_setsockopt)
set(EXTRA_EXPORT ${EXTRA_EXPORT} sleep)
endif()
if(NOT HAVE_ASPRINTF)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/bsd-asprintf.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} asprintf)
set(EXTRA_EXPORT ${EXTRA_EXPORT} vasprintf)
endif()
if(NOT HAVE_FREEZERO)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/freezero.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} freezero)
endif()
if(NOT HAVE_GETPAGESIZE)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getpagesize.c)
endif()
if(NOT HAVE_INET_PTON)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/inet_pton.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} inet_pton)
endif()
if(NOT HAVE_REALLOCARRAY)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/reallocarray.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} reallocarray)
endif()
if(NOT HAVE_RECALLOCARRAY)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/recallocarray.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} recallocarray)
endif()
if(NOT HAVE_STRCASECMP)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strcasecmp.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strcasecmp)
endif()
if(NOT HAVE_STRLCAT)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strlcat.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strlcat)
endif()
if(NOT HAVE_STRLCPY)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strlcpy.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strlcpy)
endif()
if(NOT HAVE_STRNDUP)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strndup.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strndup)
if(NOT HAVE_STRNLEN)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strnlen.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strnlen)
endif()
endif()
if(NOT HAVE_STRSEP)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strsep.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strsep)
endif()
if(NOT HAVE_TIMEGM)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/timegm.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} timegm)
endif()
if(NOT HAVE_EXPLICIT_BZERO)
if(CMAKE_HOST_WIN32)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/explicit_bzero_win.c)
else()
set(CRYPTO_SRC ${CRYPTO_SRC} compat/explicit_bzero.c)
set_source_files_properties(compat/explicit_bzero.c PROPERTIES COMPILE_FLAGS -O0)
endif()
set(EXTRA_EXPORT ${EXTRA_EXPORT} explicit_bzero)
endif()
if(NOT HAVE_ARC4RANDOM_BUF)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/arc4random.c)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/arc4random_uniform.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} arc4random)
set(EXTRA_EXPORT ${EXTRA_EXPORT} arc4random_buf)
set(EXTRA_EXPORT ${EXTRA_EXPORT} arc4random_uniform)
if(NOT HAVE_GETENTROPY)
if(CMAKE_HOST_WIN32)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_win.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "AIX")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_aix.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_freebsd.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "HP-UX")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_hpux.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_linux.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_netbsd.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_osx.c)
elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS")
set(CRYPTO_SRC ${CRYPTO_SRC} compat/getentropy_solaris.c)
endif()
set(EXTRA_EXPORT ${EXTRA_EXPORT} getentropy)
endif()
endif()
if(NOT HAVE_TIMINGSAFE_BCMP)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/timingsafe_bcmp.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} timingsafe_bcmp)
endif()
if(NOT HAVE_TIMINGSAFE_MEMCMP)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/timingsafe_memcmp.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} timingsafe_memcmp)
endif()
if(NOT ENABLE_ASM)
add_definitions(-DOPENSSL_NO_ASM)
else()
if(CMAKE_HOST_WIN32)
add_definitions(-DOPENSSL_NO_ASM)
endif()
endif()
if(NOT "${OPENSSLDIR}" STREQUAL "")
add_definitions(-DOPENSSLDIR=\"${OPENSSLDIR}\")
else()
add_definitions(-DOPENSSLDIR=\"${CMAKE_INSTALL_PREFIX}/etc/ssl\")
endif()
file(READ ${CMAKE_CURRENT_SOURCE_DIR}/crypto.sym SYMS)
foreach(SYM IN LISTS CRYPTO_UNEXPORT)
string(REPLACE "${SYM}\n" "" SYMS ${SYMS})
endforeach()
file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/crypto_p.sym ${SYMS})
if(EXTRA_EXPORT)
list(SORT EXTRA_EXPORT)
foreach(SYM IN LISTS EXTRA_EXPORT)
file(APPEND ${CMAKE_CURRENT_SOURCE_DIR}/crypto_p.sym "${SYM}\n")
endforeach()
endif()
add_library(crypto-objects OBJECT ${CRYPTO_SRC})
if (BUILD_SHARED)
add_library(crypto STATIC $<TARGET_OBJECTS:crypto-objects>)
add_library(crypto-shared SHARED $<TARGET_OBJECTS:crypto-objects>)
export_symbol(crypto-shared ${CMAKE_CURRENT_SOURCE_DIR}/crypto_p.sym)
if (WIN32)
target_link_libraries(crypto-shared Ws2_32.lib)
set(CRYPTO_POSTFIX -${CRYPTO_MAJOR_VERSION})
endif()
set_target_properties(crypto-shared PROPERTIES
OUTPUT_NAME crypto${CRYPTO_POSTFIX}
ARCHIVE_OUTPUT_NAME crypto${CRYPTO_POSTFIX})
set_target_properties(crypto-shared PROPERTIES VERSION
${CRYPTO_VERSION} SOVERSION ${CRYPTO_MAJOR_VERSION})
if(ENABLE_LIBRESSL_INSTALL)
install(TARGETS crypto crypto-shared DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_LIBRESSL_INSTALL)
else()
add_library(crypto STATIC ${CRYPTO_SRC})
if(ENABLE_LIBRESSL_INSTALL)
install(TARGETS crypto DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_LIBRESSL_INSTALL)
endif()

1
crypto/VERSION Normal file
View File

@ -0,0 +1 @@
42:0:0

2547
crypto/aes/aes-elf-x86_64.S Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

65
crypto/aes/aes_cbc.c Normal file
View File

@ -0,0 +1,65 @@
/* $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);
}

84
crypto/aes/aes_cfb.c Normal file
View File

@ -0,0 +1,84 @@
/* $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);
}

1374
crypto/aes/aes_core.c Normal file

File diff suppressed because it is too large Load Diff

62
crypto/aes/aes_ctr.c Normal file
View File

@ -0,0 +1,62 @@
/* $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);
}

69
crypto/aes/aes_ecb.c Normal file
View File

@ -0,0 +1,69 @@
/* $OpenBSD: aes_ecb.c,v 1.6 2015/02/10 09:46:30 miod 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_locl.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);
}

194
crypto/aes/aes_ige.c Normal file
View File

@ -0,0 +1,194 @@
/* $OpenBSD: aes_ige.c,v 1.7 2015/02/10 09:46:30 miod 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_locl.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;
}
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
memcpy(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;
}
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
memcpy(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);
}
}
}

83
crypto/aes/aes_locl.h Normal file
View File

@ -0,0 +1,83 @@
/* $OpenBSD: aes_locl.h,v 1.11 2016/12/21 15:49:29 jsing 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_LOCL_H
#define HEADER_AES_LOCL_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_LOCL_H */

65
crypto/aes/aes_misc.c Normal file
View File

@ -0,0 +1,65 @@
/* $OpenBSD: aes_misc.c,v 1.10 2014/07/09 11:10:50 bcook 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/opensslv.h>
#include <openssl/crypto.h>
#include <openssl/aes.h>
#include "aes_locl.h"
const char *
AES_options(void)
{
#ifdef FULL_UNROLL
return "aes(full)";
#else
return "aes(partial)";
#endif
}

61
crypto/aes/aes_ofb.c Normal file
View File

@ -0,0 +1,61 @@
/* $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);
}

133
crypto/aes/aes_wrap.c Normal file
View File

@ -0,0 +1,133 @@
/* $OpenBSD: aes_wrap.c,v 1.10 2015/09/10 15:56:24 jsing 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 < 8))
return -1;
A = B;
t = 1;
memcpy(out + 8, in, inlen);
if (!iv)
iv = default_iv;
memcpy(A, iv, 8);
for (j = 0; j < 6; j++) {
R = out + 8;
for (i = 0; i < inlen; i += 8, t++, R += 8) {
memcpy(B + 8, R, 8);
AES_encrypt(B, B, key);
A[7] ^= (unsigned char)(t & 0xff);
if (t > 0xff) {
A[6] ^= (unsigned char)((t >> 8) & 0xff);
A[5] ^= (unsigned char)((t >> 16) & 0xff);
A[4] ^= (unsigned char)((t >> 24) & 0xff);
}
memcpy(R, B + 8, 8);
}
}
memcpy(out, A, 8);
return inlen + 8;
}
int
AES_unwrap_key(AES_KEY *key, const unsigned char *iv, unsigned char *out,
const unsigned char *in, unsigned int inlen)
{
unsigned char *A, B[16], *R;
unsigned int i, j, t;
inlen -= 8;
if (inlen & 0x7)
return -1;
if (inlen < 8)
return -1;
A = B;
t = 6 * (inlen >> 3);
memcpy(A, in, 8);
memcpy(out, in + 8, inlen);
for (j = 0; j < 6; j++) {
R = out + inlen - 8;
for (i = 0; i < inlen; i += 8, t--, R -= 8) {
A[7] ^= (unsigned char)(t & 0xff);
if (t > 0xff) {
A[6] ^= (unsigned char)((t >> 8) & 0xff);
A[5] ^= (unsigned char)((t >> 16) & 0xff);
A[4] ^= (unsigned char)((t >> 24) & 0xff);
}
memcpy(B + 8, R, 8);
AES_decrypt(B, B, key);
memcpy(R, B + 8, 8);
}
}
if (!iv)
iv = default_iv;
if (memcmp(A, iv, 8)) {
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

View File

@ -0,0 +1,832 @@
#include "x86_arch.h"
.text
.type _vpaes_encrypt_core,@function
.align 16
_vpaes_encrypt_core:
movq %rdx,%r9
movq $16,%r11
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa .Lk_ipt(%rip),%xmm2
pandn %xmm0,%xmm1
movdqu (%r9),%xmm5
psrld $4,%xmm1
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa .Lk_ipt+16(%rip),%xmm0
.byte 102,15,56,0,193
pxor %xmm5,%xmm2
pxor %xmm2,%xmm0
addq $16,%r9
leaq .Lk_mc_backward(%rip),%r10
jmp .Lenc_entry
.align 16
.Lenc_loop:
movdqa %xmm13,%xmm4
.byte 102,15,56,0,226
pxor %xmm5,%xmm4
movdqa %xmm12,%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
movdqa %xmm15,%xmm5
.byte 102,15,56,0,234
movdqa -64(%r11,%r10,1),%xmm1
movdqa %xmm14,%xmm2
.byte 102,15,56,0,211
pxor %xmm5,%xmm2
movdqa (%r11,%r10,1),%xmm4
movdqa %xmm0,%xmm3
.byte 102,15,56,0,193
addq $16,%r9
pxor %xmm2,%xmm0
.byte 102,15,56,0,220
addq $16,%r11
pxor %xmm0,%xmm3
.byte 102,15,56,0,193
andq $48,%r11
pxor %xmm3,%xmm0
subq $1,%rax
.Lenc_entry:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm5
.byte 102,15,56,0,232
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm5,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm5,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
movdqu (%r9),%xmm5
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
jnz .Lenc_loop
movdqa -96(%r10),%xmm4
movdqa -80(%r10),%xmm0
.byte 102,15,56,0,226
pxor %xmm5,%xmm4
.byte 102,15,56,0,195
movdqa 64(%r11,%r10,1),%xmm1
pxor %xmm4,%xmm0
.byte 102,15,56,0,193
.byte 0xf3,0xc3
.size _vpaes_encrypt_core,.-_vpaes_encrypt_core
.type _vpaes_decrypt_core,@function
.align 16
_vpaes_decrypt_core:
movq %rdx,%r9
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa .Lk_dipt(%rip),%xmm2
pandn %xmm0,%xmm1
movq %rax,%r11
psrld $4,%xmm1
movdqu (%r9),%xmm5
shlq $4,%r11
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa .Lk_dipt+16(%rip),%xmm0
xorq $48,%r11
leaq .Lk_dsbd(%rip),%r10
.byte 102,15,56,0,193
andq $48,%r11
pxor %xmm5,%xmm2
movdqa .Lk_mc_forward+48(%rip),%xmm5
pxor %xmm2,%xmm0
addq $16,%r9
addq %r10,%r11
jmp .Ldec_entry
.align 16
.Ldec_loop:
movdqa -32(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa -16(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
addq $16,%r9
.byte 102,15,56,0,197
movdqa 0(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 16(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
subq $1,%rax
.byte 102,15,56,0,197
movdqa 32(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 48(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,56,0,197
movdqa 64(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 80(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,58,15,237,12
.Ldec_entry:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm2
.byte 102,15,56,0,208
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
movdqu (%r9),%xmm0
jnz .Ldec_loop
movdqa 96(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 112(%r10),%xmm0
movdqa -352(%r11),%xmm2
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,56,0,194
.byte 0xf3,0xc3
.size _vpaes_decrypt_core,.-_vpaes_decrypt_core
.type _vpaes_schedule_core,@function
.align 16
_vpaes_schedule_core:
call _vpaes_preheat
movdqa .Lk_rcon(%rip),%xmm8
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm3
leaq .Lk_ipt(%rip),%r11
call _vpaes_schedule_transform
movdqa %xmm0,%xmm7
leaq .Lk_sr(%rip),%r10
testq %rcx,%rcx
jnz .Lschedule_am_decrypting
movdqu %xmm0,(%rdx)
jmp .Lschedule_go
.Lschedule_am_decrypting:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
movdqu %xmm3,(%rdx)
xorq $48,%r8
.Lschedule_go:
cmpl $192,%esi
ja .Lschedule_256
je .Lschedule_192
.Lschedule_128:
movl $10,%esi
.Loop_schedule_128:
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
jmp .Loop_schedule_128
.align 16
.Lschedule_192:
movdqu 8(%rdi),%xmm0
call _vpaes_schedule_transform
movdqa %xmm0,%xmm6
pxor %xmm4,%xmm4
movhlps %xmm4,%xmm6
movl $4,%esi
.Loop_schedule_192:
call _vpaes_schedule_round
.byte 102,15,58,15,198,8
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
call _vpaes_schedule_mangle
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
jmp .Loop_schedule_192
.align 16
.Lschedule_256:
movdqu 16(%rdi),%xmm0
call _vpaes_schedule_transform
movl $7,%esi
.Loop_schedule_256:
call _vpaes_schedule_mangle
movdqa %xmm0,%xmm6
call _vpaes_schedule_round
decq %rsi
jz .Lschedule_mangle_last
call _vpaes_schedule_mangle
pshufd $255,%xmm0,%xmm0
movdqa %xmm7,%xmm5
movdqa %xmm6,%xmm7
call _vpaes_schedule_low_round
movdqa %xmm5,%xmm7
jmp .Loop_schedule_256
.align 16
.Lschedule_mangle_last:
leaq .Lk_deskew(%rip),%r11
testq %rcx,%rcx
jnz .Lschedule_mangle_last_dec
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,193
leaq .Lk_opt(%rip),%r11
addq $32,%rdx
.Lschedule_mangle_last_dec:
addq $-16,%rdx
pxor .Lk_s63(%rip),%xmm0
call _vpaes_schedule_transform
movdqu %xmm0,(%rdx)
pxor %xmm0,%xmm0
pxor %xmm1,%xmm1
pxor %xmm2,%xmm2
pxor %xmm3,%xmm3
pxor %xmm4,%xmm4
pxor %xmm5,%xmm5
pxor %xmm6,%xmm6
pxor %xmm7,%xmm7
.byte 0xf3,0xc3
.size _vpaes_schedule_core,.-_vpaes_schedule_core
.type _vpaes_schedule_192_smear,@function
.align 16
_vpaes_schedule_192_smear:
pshufd $128,%xmm6,%xmm0
pxor %xmm0,%xmm6
pshufd $254,%xmm7,%xmm0
pxor %xmm0,%xmm6
movdqa %xmm6,%xmm0
pxor %xmm1,%xmm1
movhlps %xmm1,%xmm6
.byte 0xf3,0xc3
.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear
.type _vpaes_schedule_round,@function
.align 16
_vpaes_schedule_round:
pxor %xmm1,%xmm1
.byte 102,65,15,58,15,200,15
.byte 102,69,15,58,15,192,15
pxor %xmm1,%xmm7
pshufd $255,%xmm0,%xmm0
.byte 102,15,58,15,192,1
_vpaes_schedule_low_round:
movdqa %xmm7,%xmm1
pslldq $4,%xmm7
pxor %xmm1,%xmm7
movdqa %xmm7,%xmm1
pslldq $8,%xmm7
pxor %xmm1,%xmm7
pxor .Lk_s63(%rip),%xmm7
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm2
.byte 102,15,56,0,208
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
movdqa %xmm13,%xmm4
.byte 102,15,56,0,226
movdqa %xmm12,%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
pxor %xmm7,%xmm0
movdqa %xmm0,%xmm7
.byte 0xf3,0xc3
.size _vpaes_schedule_round,.-_vpaes_schedule_round
.type _vpaes_schedule_transform,@function
.align 16
_vpaes_schedule_transform:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa (%r11),%xmm2
.byte 102,15,56,0,208
movdqa 16(%r11),%xmm0
.byte 102,15,56,0,193
pxor %xmm2,%xmm0
.byte 0xf3,0xc3
.size _vpaes_schedule_transform,.-_vpaes_schedule_transform
.type _vpaes_schedule_mangle,@function
.align 16
_vpaes_schedule_mangle:
movdqa %xmm0,%xmm4
movdqa .Lk_mc_forward(%rip),%xmm5
testq %rcx,%rcx
jnz .Lschedule_mangle_dec
addq $16,%rdx
pxor .Lk_s63(%rip),%xmm4
.byte 102,15,56,0,229
movdqa %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
jmp .Lschedule_mangle_both
.align 16
.Lschedule_mangle_dec:
leaq .Lk_dksd(%rip),%r11
movdqa %xmm9,%xmm1
pandn %xmm4,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm4
movdqa 0(%r11),%xmm2
.byte 102,15,56,0,212
movdqa 16(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 32(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 48(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 64(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 80(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 96(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 112(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
addq $-16,%rdx
.Lschedule_mangle_both:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
addq $-16,%r8
andq $48,%r8
movdqu %xmm3,(%rdx)
.byte 0xf3,0xc3
.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle
.globl vpaes_set_encrypt_key
.type vpaes_set_encrypt_key,@function
.align 16
vpaes_set_encrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
movl $0,%ecx
movl $48,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.size vpaes_set_encrypt_key,.-vpaes_set_encrypt_key
.globl vpaes_set_decrypt_key
.type vpaes_set_decrypt_key,@function
.align 16
vpaes_set_decrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
shll $4,%eax
leaq 16(%rdx,%rax,1),%rdx
movl $1,%ecx
movl %esi,%r8d
shrl $1,%r8d
andl $32,%r8d
xorl $32,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.size vpaes_set_decrypt_key,.-vpaes_set_decrypt_key
.globl vpaes_encrypt
.type vpaes_encrypt,@function
.align 16
vpaes_encrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_encrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.size vpaes_encrypt,.-vpaes_encrypt
.globl vpaes_decrypt
.type vpaes_decrypt,@function
.align 16
vpaes_decrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_decrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.size vpaes_decrypt,.-vpaes_decrypt
.globl vpaes_cbc_encrypt
.type vpaes_cbc_encrypt,@function
.align 16
vpaes_cbc_encrypt:
xchgq %rcx,%rdx
subq $16,%rcx
jc .Lcbc_abort
movdqu (%r8),%xmm6
subq %rdi,%rsi
call _vpaes_preheat
cmpl $0,%r9d
je .Lcbc_dec_loop
jmp .Lcbc_enc_loop
.align 16
.Lcbc_enc_loop:
movdqu (%rdi),%xmm0
pxor %xmm6,%xmm0
call _vpaes_encrypt_core
movdqa %xmm0,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc .Lcbc_enc_loop
jmp .Lcbc_done
.align 16
.Lcbc_dec_loop:
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm7
call _vpaes_decrypt_core
pxor %xmm6,%xmm0
movdqa %xmm7,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc .Lcbc_dec_loop
.Lcbc_done:
movdqu %xmm6,(%r8)
.Lcbc_abort:
.byte 0xf3,0xc3
.size vpaes_cbc_encrypt,.-vpaes_cbc_encrypt
.type _vpaes_preheat,@function
.align 16
_vpaes_preheat:
leaq .Lk_s0F(%rip),%r10
movdqa -32(%r10),%xmm10
movdqa -16(%r10),%xmm11
movdqa 0(%r10),%xmm9
movdqa 48(%r10),%xmm13
movdqa 64(%r10),%xmm12
movdqa 80(%r10),%xmm15
movdqa 96(%r10),%xmm14
.byte 0xf3,0xc3
.size _vpaes_preheat,.-_vpaes_preheat
.type _vpaes_consts,@object
.align 64
_vpaes_consts:
.Lk_inv:
.quad 0x0E05060F0D080180, 0x040703090A0B0C02
.quad 0x01040A060F0B0780, 0x030D0E0C02050809
.Lk_s0F:
.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
.Lk_ipt:
.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808
.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
.Lk_sb1:
.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
.Lk_sb2:
.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD
.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A
.Lk_sbo:
.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878
.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
.Lk_mc_forward:
.quad 0x0407060500030201, 0x0C0F0E0D080B0A09
.quad 0x080B0A0904070605, 0x000302010C0F0E0D
.quad 0x0C0F0E0D080B0A09, 0x0407060500030201
.quad 0x000302010C0F0E0D, 0x080B0A0904070605
.Lk_mc_backward:
.quad 0x0605040702010003, 0x0E0D0C0F0A09080B
.quad 0x020100030E0D0C0F, 0x0A09080B06050407
.quad 0x0E0D0C0F0A09080B, 0x0605040702010003
.quad 0x0A09080B06050407, 0x020100030E0D0C0F
.Lk_sr:
.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908
.quad 0x030E09040F0A0500, 0x0B06010C07020D08
.quad 0x0F060D040B020900, 0x070E050C030A0108
.quad 0x0B0E0104070A0D00, 0x0306090C0F020508
.Lk_rcon:
.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
.Lk_s63:
.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
.Lk_opt:
.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808
.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
.Lk_deskew:
.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
.Lk_dksd:
.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E
.Lk_dksb:
.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99
.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
.Lk_dkse:
.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086
.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487
.Lk_dks9:
.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC
.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE
.Lk_dipt:
.quad 0x0F505B040B545F00, 0x154A411E114E451A
.quad 0x86E383E660056500, 0x12771772F491F194
.Lk_dsb9:
.quad 0x851C03539A86D600, 0xCAD51F504F994CC9
.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565
.Lk_dsbd:
.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
.Lk_dsbb:
.quad 0xD022649296B44200, 0x602646F6B0F2D404
.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
.Lk_dsbe:
.quad 0x46F2929626D4D000, 0x2242600464B4F6B0
.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32
.Lk_dsbo:
.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C
.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
.align 64
.size _vpaes_consts,.-_vpaes_consts
#if defined(HAVE_GNU_STACK)
.section .note.GNU-stack,"",%progbits
#endif

View File

@ -0,0 +1,829 @@
#include "x86_arch.h"
.text
.p2align 4
_vpaes_encrypt_core:
movq %rdx,%r9
movq $16,%r11
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa L$k_ipt(%rip),%xmm2
pandn %xmm0,%xmm1
movdqu (%r9),%xmm5
psrld $4,%xmm1
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa L$k_ipt+16(%rip),%xmm0
.byte 102,15,56,0,193
pxor %xmm5,%xmm2
pxor %xmm2,%xmm0
addq $16,%r9
leaq L$k_mc_backward(%rip),%r10
jmp L$enc_entry
.p2align 4
L$enc_loop:
movdqa %xmm13,%xmm4
.byte 102,15,56,0,226
pxor %xmm5,%xmm4
movdqa %xmm12,%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
movdqa %xmm15,%xmm5
.byte 102,15,56,0,234
movdqa -64(%r11,%r10,1),%xmm1
movdqa %xmm14,%xmm2
.byte 102,15,56,0,211
pxor %xmm5,%xmm2
movdqa (%r11,%r10,1),%xmm4
movdqa %xmm0,%xmm3
.byte 102,15,56,0,193
addq $16,%r9
pxor %xmm2,%xmm0
.byte 102,15,56,0,220
addq $16,%r11
pxor %xmm0,%xmm3
.byte 102,15,56,0,193
andq $48,%r11
pxor %xmm3,%xmm0
subq $1,%rax
L$enc_entry:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm5
.byte 102,15,56,0,232
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm5,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm5,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
movdqu (%r9),%xmm5
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
jnz L$enc_loop
movdqa -96(%r10),%xmm4
movdqa -80(%r10),%xmm0
.byte 102,15,56,0,226
pxor %xmm5,%xmm4
.byte 102,15,56,0,195
movdqa 64(%r11,%r10,1),%xmm1
pxor %xmm4,%xmm0
.byte 102,15,56,0,193
.byte 0xf3,0xc3
.p2align 4
_vpaes_decrypt_core:
movq %rdx,%r9
movl 240(%rdx),%eax
movdqa %xmm9,%xmm1
movdqa L$k_dipt(%rip),%xmm2
pandn %xmm0,%xmm1
movq %rax,%r11
psrld $4,%xmm1
movdqu (%r9),%xmm5
shlq $4,%r11
pand %xmm9,%xmm0
.byte 102,15,56,0,208
movdqa L$k_dipt+16(%rip),%xmm0
xorq $48,%r11
leaq L$k_dsbd(%rip),%r10
.byte 102,15,56,0,193
andq $48,%r11
pxor %xmm5,%xmm2
movdqa L$k_mc_forward+48(%rip),%xmm5
pxor %xmm2,%xmm0
addq $16,%r9
addq %r10,%r11
jmp L$dec_entry
.p2align 4
L$dec_loop:
movdqa -32(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa -16(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
addq $16,%r9
.byte 102,15,56,0,197
movdqa 0(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 16(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
subq $1,%rax
.byte 102,15,56,0,197
movdqa 32(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 48(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,56,0,197
movdqa 64(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 80(%r10),%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,58,15,237,12
L$dec_entry:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm2
.byte 102,15,56,0,208
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
movdqu (%r9),%xmm0
jnz L$dec_loop
movdqa 96(%r10),%xmm4
.byte 102,15,56,0,226
pxor %xmm0,%xmm4
movdqa 112(%r10),%xmm0
movdqa -352(%r11),%xmm2
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
.byte 102,15,56,0,194
.byte 0xf3,0xc3
.p2align 4
_vpaes_schedule_core:
call _vpaes_preheat
movdqa L$k_rcon(%rip),%xmm8
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm3
leaq L$k_ipt(%rip),%r11
call _vpaes_schedule_transform
movdqa %xmm0,%xmm7
leaq L$k_sr(%rip),%r10
testq %rcx,%rcx
jnz L$schedule_am_decrypting
movdqu %xmm0,(%rdx)
jmp L$schedule_go
L$schedule_am_decrypting:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
movdqu %xmm3,(%rdx)
xorq $48,%r8
L$schedule_go:
cmpl $192,%esi
ja L$schedule_256
je L$schedule_192
L$schedule_128:
movl $10,%esi
L$oop_schedule_128:
call _vpaes_schedule_round
decq %rsi
jz L$schedule_mangle_last
call _vpaes_schedule_mangle
jmp L$oop_schedule_128
.p2align 4
L$schedule_192:
movdqu 8(%rdi),%xmm0
call _vpaes_schedule_transform
movdqa %xmm0,%xmm6
pxor %xmm4,%xmm4
movhlps %xmm4,%xmm6
movl $4,%esi
L$oop_schedule_192:
call _vpaes_schedule_round
.byte 102,15,58,15,198,8
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
call _vpaes_schedule_mangle
call _vpaes_schedule_round
decq %rsi
jz L$schedule_mangle_last
call _vpaes_schedule_mangle
call _vpaes_schedule_192_smear
jmp L$oop_schedule_192
.p2align 4
L$schedule_256:
movdqu 16(%rdi),%xmm0
call _vpaes_schedule_transform
movl $7,%esi
L$oop_schedule_256:
call _vpaes_schedule_mangle
movdqa %xmm0,%xmm6
call _vpaes_schedule_round
decq %rsi
jz L$schedule_mangle_last
call _vpaes_schedule_mangle
pshufd $255,%xmm0,%xmm0
movdqa %xmm7,%xmm5
movdqa %xmm6,%xmm7
call _vpaes_schedule_low_round
movdqa %xmm5,%xmm7
jmp L$oop_schedule_256
.p2align 4
L$schedule_mangle_last:
leaq L$k_deskew(%rip),%r11
testq %rcx,%rcx
jnz L$schedule_mangle_last_dec
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,193
leaq L$k_opt(%rip),%r11
addq $32,%rdx
L$schedule_mangle_last_dec:
addq $-16,%rdx
pxor L$k_s63(%rip),%xmm0
call _vpaes_schedule_transform
movdqu %xmm0,(%rdx)
pxor %xmm0,%xmm0
pxor %xmm1,%xmm1
pxor %xmm2,%xmm2
pxor %xmm3,%xmm3
pxor %xmm4,%xmm4
pxor %xmm5,%xmm5
pxor %xmm6,%xmm6
pxor %xmm7,%xmm7
.byte 0xf3,0xc3
.p2align 4
_vpaes_schedule_192_smear:
pshufd $128,%xmm6,%xmm0
pxor %xmm0,%xmm6
pshufd $254,%xmm7,%xmm0
pxor %xmm0,%xmm6
movdqa %xmm6,%xmm0
pxor %xmm1,%xmm1
movhlps %xmm1,%xmm6
.byte 0xf3,0xc3
.p2align 4
_vpaes_schedule_round:
pxor %xmm1,%xmm1
.byte 102,65,15,58,15,200,15
.byte 102,69,15,58,15,192,15
pxor %xmm1,%xmm7
pshufd $255,%xmm0,%xmm0
.byte 102,15,58,15,192,1
_vpaes_schedule_low_round:
movdqa %xmm7,%xmm1
pslldq $4,%xmm7
pxor %xmm1,%xmm7
movdqa %xmm7,%xmm1
pslldq $8,%xmm7
pxor %xmm1,%xmm7
pxor L$k_s63(%rip),%xmm7
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa %xmm11,%xmm2
.byte 102,15,56,0,208
pxor %xmm1,%xmm0
movdqa %xmm10,%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
movdqa %xmm10,%xmm4
.byte 102,15,56,0,224
pxor %xmm2,%xmm4
movdqa %xmm10,%xmm2
.byte 102,15,56,0,211
pxor %xmm0,%xmm2
movdqa %xmm10,%xmm3
.byte 102,15,56,0,220
pxor %xmm1,%xmm3
movdqa %xmm13,%xmm4
.byte 102,15,56,0,226
movdqa %xmm12,%xmm0
.byte 102,15,56,0,195
pxor %xmm4,%xmm0
pxor %xmm7,%xmm0
movdqa %xmm0,%xmm7
.byte 0xf3,0xc3
.p2align 4
_vpaes_schedule_transform:
movdqa %xmm9,%xmm1
pandn %xmm0,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm0
movdqa (%r11),%xmm2
.byte 102,15,56,0,208
movdqa 16(%r11),%xmm0
.byte 102,15,56,0,193
pxor %xmm2,%xmm0
.byte 0xf3,0xc3
.p2align 4
_vpaes_schedule_mangle:
movdqa %xmm0,%xmm4
movdqa L$k_mc_forward(%rip),%xmm5
testq %rcx,%rcx
jnz L$schedule_mangle_dec
addq $16,%rdx
pxor L$k_s63(%rip),%xmm4
.byte 102,15,56,0,229
movdqa %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
.byte 102,15,56,0,229
pxor %xmm4,%xmm3
jmp L$schedule_mangle_both
.p2align 4
L$schedule_mangle_dec:
leaq L$k_dksd(%rip),%r11
movdqa %xmm9,%xmm1
pandn %xmm4,%xmm1
psrld $4,%xmm1
pand %xmm9,%xmm4
movdqa 0(%r11),%xmm2
.byte 102,15,56,0,212
movdqa 16(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 32(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 48(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 64(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 80(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
.byte 102,15,56,0,221
movdqa 96(%r11),%xmm2
.byte 102,15,56,0,212
pxor %xmm3,%xmm2
movdqa 112(%r11),%xmm3
.byte 102,15,56,0,217
pxor %xmm2,%xmm3
addq $-16,%rdx
L$schedule_mangle_both:
movdqa (%r8,%r10,1),%xmm1
.byte 102,15,56,0,217
addq $-16,%r8
andq $48,%r8
movdqu %xmm3,(%rdx)
.byte 0xf3,0xc3
.globl _vpaes_set_encrypt_key
.p2align 4
_vpaes_set_encrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
movl $0,%ecx
movl $48,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.globl _vpaes_set_decrypt_key
.p2align 4
_vpaes_set_decrypt_key:
movl %esi,%eax
shrl $5,%eax
addl $5,%eax
movl %eax,240(%rdx)
shll $4,%eax
leaq 16(%rdx,%rax,1),%rdx
movl $1,%ecx
movl %esi,%r8d
shrl $1,%r8d
andl $32,%r8d
xorl $32,%r8d
call _vpaes_schedule_core
xorl %eax,%eax
.byte 0xf3,0xc3
.globl _vpaes_encrypt
.p2align 4
_vpaes_encrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_encrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.globl _vpaes_decrypt
.p2align 4
_vpaes_decrypt:
movdqu (%rdi),%xmm0
call _vpaes_preheat
call _vpaes_decrypt_core
movdqu %xmm0,(%rsi)
.byte 0xf3,0xc3
.globl _vpaes_cbc_encrypt
.p2align 4
_vpaes_cbc_encrypt:
xchgq %rcx,%rdx
subq $16,%rcx
jc L$cbc_abort
movdqu (%r8),%xmm6
subq %rdi,%rsi
call _vpaes_preheat
cmpl $0,%r9d
je L$cbc_dec_loop
jmp L$cbc_enc_loop
.p2align 4
L$cbc_enc_loop:
movdqu (%rdi),%xmm0
pxor %xmm6,%xmm0
call _vpaes_encrypt_core
movdqa %xmm0,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc L$cbc_enc_loop
jmp L$cbc_done
.p2align 4
L$cbc_dec_loop:
movdqu (%rdi),%xmm0
movdqa %xmm0,%xmm7
call _vpaes_decrypt_core
pxor %xmm6,%xmm0
movdqa %xmm7,%xmm6
movdqu %xmm0,(%rsi,%rdi,1)
leaq 16(%rdi),%rdi
subq $16,%rcx
jnc L$cbc_dec_loop
L$cbc_done:
movdqu %xmm6,(%r8)
L$cbc_abort:
.byte 0xf3,0xc3
.p2align 4
_vpaes_preheat:
leaq L$k_s0F(%rip),%r10
movdqa -32(%r10),%xmm10
movdqa -16(%r10),%xmm11
movdqa 0(%r10),%xmm9
movdqa 48(%r10),%xmm13
movdqa 64(%r10),%xmm12
movdqa 80(%r10),%xmm15
movdqa 96(%r10),%xmm14
.byte 0xf3,0xc3
.p2align 6
_vpaes_consts:
L$k_inv:
.quad 0x0E05060F0D080180, 0x040703090A0B0C02
.quad 0x01040A060F0B0780, 0x030D0E0C02050809
L$k_s0F:
.quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F
L$k_ipt:
.quad 0xC2B2E8985A2A7000, 0xCABAE09052227808
.quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81
L$k_sb1:
.quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544
.quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF
L$k_sb2:
.quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD
.quad 0x69EB88400AE12900, 0xC2A163C8AB82234A
L$k_sbo:
.quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878
.quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA
L$k_mc_forward:
.quad 0x0407060500030201, 0x0C0F0E0D080B0A09
.quad 0x080B0A0904070605, 0x000302010C0F0E0D
.quad 0x0C0F0E0D080B0A09, 0x0407060500030201
.quad 0x000302010C0F0E0D, 0x080B0A0904070605
L$k_mc_backward:
.quad 0x0605040702010003, 0x0E0D0C0F0A09080B
.quad 0x020100030E0D0C0F, 0x0A09080B06050407
.quad 0x0E0D0C0F0A09080B, 0x0605040702010003
.quad 0x0A09080B06050407, 0x020100030E0D0C0F
L$k_sr:
.quad 0x0706050403020100, 0x0F0E0D0C0B0A0908
.quad 0x030E09040F0A0500, 0x0B06010C07020D08
.quad 0x0F060D040B020900, 0x070E050C030A0108
.quad 0x0B0E0104070A0D00, 0x0306090C0F020508
L$k_rcon:
.quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81
L$k_s63:
.quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B
L$k_opt:
.quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808
.quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0
L$k_deskew:
.quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A
.quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77
L$k_dksd:
.quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9
.quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E
L$k_dksb:
.quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99
.quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8
L$k_dkse:
.quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086
.quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487
L$k_dks9:
.quad 0xB6116FC87ED9A700, 0x4AED933482255BFC
.quad 0x4576516227143300, 0x8BB89FACE9DAFDCE
L$k_dipt:
.quad 0x0F505B040B545F00, 0x154A411E114E451A
.quad 0x86E383E660056500, 0x12771772F491F194
L$k_dsb9:
.quad 0x851C03539A86D600, 0xCAD51F504F994CC9
.quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565
L$k_dsbd:
.quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439
.quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3
L$k_dsbb:
.quad 0xD022649296B44200, 0x602646F6B0F2D404
.quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B
L$k_dsbe:
.quad 0x46F2929626D4D000, 0x2242600464B4F6B0
.quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32
L$k_dsbo:
.quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D
.quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C
.byte 86,101,99,116,111,114,32,80,101,114,109,117,116,97,116,105,111,110,32,65,69,83,32,102,111,114,32,120,56,54,95,54,52,47,83,83,83,69,51,44,32,77,105,107,101,32,72,97,109,98,117,114,103,32,40,83,116,97,110,102,111,114,100,32,85,110,105,118,101,114,115,105,116,121,41,0
.p2align 6

259
crypto/asn1/a_bitstr.c Normal file
View File

@ -0,0 +1,259 @@
/* $OpenBSD: a_bitstr.c,v 1.24 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
int
ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{
return ASN1_STRING_set(x, d, len);
}
int
i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
int ret, j, bits, len;
unsigned char *p, *d;
if (a == NULL)
return (0);
len = a->length;
if (len > 0) {
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
bits = (int)a->flags & 0x07;
} else {
for (; len > 0; len--) {
if (a->data[len - 1])
break;
}
j = a->data[len - 1];
if (j & 0x01)
bits = 0;
else if (j & 0x02)
bits = 1;
else if (j & 0x04)
bits = 2;
else if (j & 0x08)
bits = 3;
else if (j & 0x10)
bits = 4;
else if (j & 0x20)
bits = 5;
else if (j & 0x40)
bits = 6;
else if (j & 0x80)
bits = 7;
else
bits = 0; /* should not happen */
}
} else
bits = 0;
ret = 1 + len;
if (pp == NULL)
return (ret);
p= *pp;
*(p++) = (unsigned char)bits;
d = a->data;
memcpy(p, d, len);
p += len;
if (len > 0)
p[-1]&=(0xff << bits);
*pp = p;
return (ret);
}
ASN1_BIT_STRING *
c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len)
{
ASN1_BIT_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
int i;
if (len < 1) {
i = ASN1_R_STRING_TOO_SHORT;
goto err;
}
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_BIT_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
p = *pp;
i = *(p++);
/* We do this to preserve the settings. If we modify
* the settings, via the _set_bit function, we will recalculate
* on output */
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
if (len-- > 1) /* using one because of the bits left byte */
{
s = malloc(len);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s, p, len);
s[len - 1] &= (0xff << i);
p += len;
} else
s = NULL;
ret->length = (int)len;
free(ret->data);
ret->data = s;
ret->type = V_ASN1_BIT_STRING;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
ASN1error(i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_BIT_STRING_free(ret);
return (NULL);
}
/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
*/
int
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
{
int w, v, iv;
unsigned char *c;
w = n/8;
v = 1 << (7 - (n & 0x07));
iv = ~v;
if (!value)
v = 0;
if (a == NULL)
return 0;
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
if ((a->length < (w + 1)) || (a->data == NULL)) {
if (!value)
return(1); /* Don't need to set */
c = OPENSSL_realloc_clean(a->data, a->length, w + 1);
if (c == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
if (w + 1 - a->length > 0)
memset(c + a->length, 0, w + 1 - a->length);
a->data = c;
a->length = w + 1;
}
a->data[w] = ((a->data[w]) & iv) | v;
while ((a->length > 0) && (a->data[a->length - 1] == 0))
a->length--;
return (1);
}
int
ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
{
int w, v;
w = n / 8;
v = 1 << (7 - (n & 0x07));
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
return (0);
return ((a->data[w] & v) != 0);
}
/*
* Checks if the given bit string contains only bits specified by
* the flags vector. Returns 0 if there is at least one bit set in 'a'
* which is not specified in 'flags', 1 otherwise.
* 'len' is the length of 'flags'.
*/
int
ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len)
{
int i, ok;
/* Check if there is one bit set at all. */
if (!a || !a->data)
return 1;
/* Check each byte of the internal representation of the bit string. */
ok = 1;
for (i = 0; i < a->length && ok; ++i) {
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
/* We are done if there is an unneeded bit set. */
ok = (a->data[i] & mask) == 0;
}
return ok;
}

115
crypto/asn1/a_bool.c Normal file
View File

@ -0,0 +1,115 @@
/* $OpenBSD: a_bool.c,v 1.8 2017/01/29 17:49:22 beck 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 <openssl/asn1t.h>
#include <openssl/err.h>
int
i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
{
int r;
unsigned char *p;
r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
if (pp == NULL)
return (r);
p = *pp;
ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
*(p++) = (unsigned char)a;
*pp = p;
return (r);
}
int
d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
{
int ret = -1;
const unsigned char *p;
long len;
int inf, tag, xclass;
int i = 0;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_BOOLEAN) {
i = ASN1_R_EXPECTING_A_BOOLEAN;
goto err;
}
if (len != 1) {
i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
goto err;
}
ret = (int)*(p++);
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
ASN1error(i);
return (ret);
}

306
crypto/asn1/a_bytes.c Normal file
View File

@ -0,0 +1,306 @@
/* $OpenBSD: a_bytes.c,v 1.19 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
/* type is a 'bitmap' of acceptable string types.
*/
ASN1_STRING *
d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int type)
{
ASN1_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i = 0;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80)
goto err;
if (tag >= 32) {
i = ASN1_R_TAG_VALUE_TOO_HIGH;
goto err;
}
if (!(ASN1_tag2bit(tag) & type)) {
i = ASN1_R_WRONG_TYPE;
goto err;
}
/* If a bit-string, exit early */
if (tag == V_ASN1_BIT_STRING)
return (d2i_ASN1_BIT_STRING(a, pp, length));
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
if (len != 0) {
s = malloc(len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
memcpy(s, p, len);
s[len]='\0';
p += len;
} else
s = NULL;
free(ret->data);
ret->length = (int)len;
ret->data = s;
ret->type = tag;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_STRING_free(ret);
return (NULL);
}
int
i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
{
int ret, r, constructed;
unsigned char *p;
if (a == NULL)
return (0);
if (tag == V_ASN1_BIT_STRING)
return (i2d_ASN1_BIT_STRING(a, pp));
ret = a->length;
r = ASN1_object_size(0, ret, tag);
if (pp == NULL)
return (r);
p = *pp;
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
constructed = 1;
else
constructed = 0;
ASN1_put_object(&p, constructed, ret, tag, xclass);
memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
return (r);
}
ASN1_STRING *
d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int Ptag, int Pclass)
{
ASN1_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i = 0;
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_STRING_new()) == NULL)
return (NULL);
} else
ret = (*a);
p= *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != Ptag) {
i = ASN1_R_WRONG_TAG;
goto err;
}
if (inf & V_ASN1_CONSTRUCTED) {
ASN1_const_CTX c;
c.pp = pp;
c.p = p;
c.inf = inf;
c.slen = len;
c.tag = Ptag;
c.xclass = Pclass;
c.max = (length == 0) ? 0 : (p + length);
if (!asn1_collate_primitive(ret, &c))
goto err;
else {
p = c.p;
}
} else {
if (len != 0) {
if ((ret->length < len) || (ret->data == NULL)) {
free(ret->data);
ret->data = NULL;
s = malloc(len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
} else
s = ret->data;
memcpy(s, p, len);
s[len] = '\0';
p += len;
} else {
s = NULL;
free(ret->data);
}
ret->length = (int)len;
ret->data = s;
ret->type = Ptag;
}
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
if (a == NULL || *a != ret)
ASN1_STRING_free(ret);
ASN1error(i);
return (NULL);
}
/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
* them into the one structure that is then returned */
/* There have been a few bug fixes for this function from
* Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
static int
asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
{
ASN1_STRING *os = NULL;
BUF_MEM b;
int num;
b.length = 0;
b.max = 0;
b.data = NULL;
if (a == NULL) {
c->error = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}
num = 0;
for (;;) {
if (c->inf & 1) {
c->eos = ASN1_const_check_infinite_end(&c->p,
(long)(c->max - c->p));
if (c->eos)
break;
} else {
if (c->slen <= 0)
break;
}
c->q = c->p;
if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag,
c->xclass) == NULL) {
c->error = ERR_R_ASN1_LIB;
goto err;
}
if (!BUF_MEM_grow_clean(&b, num + os->length)) {
c->error = ERR_R_BUF_LIB;
goto err;
}
memcpy(&(b.data[num]), os->data, os->length);
if (!(c->inf & 1))
c->slen -= (c->p - c->q);
num += os->length;
}
if (!asn1_const_Finish(c))
goto err;
a->length = num;
free(a->data);
a->data = (unsigned char *)b.data;
ASN1_STRING_free(os);
return (1);
err:
ASN1error(c->error);
ASN1_STRING_free(os);
free(b.data);
return (0);
}

289
crypto/asn1/a_d2i_fp.c Normal file
View File

@ -0,0 +1,289 @@
/* $OpenBSD: a_d2i_fp.c,v 1.16 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
#ifndef NO_OLD_ASN1
void *
ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
{
BIO *b;
void *ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_d2i_bio(xnew, d2i, b, x);
BIO_free(b);
return (ret);
}
void *
ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p = (unsigned char *)b->data;
ret = d2i(x, &p, len);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
#endif
void *
ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
{
BUF_MEM *b = NULL;
const unsigned char *p;
void *ret = NULL;
int len;
len = asn1_d2i_read_bio(in, &b);
if (len < 0)
goto err;
p = (const unsigned char *)b->data;
ret = ASN1_item_d2i(x, &p, len, it);
err:
if (b != NULL)
BUF_MEM_free(b);
return (ret);
}
void *
ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
{
BIO *b;
char *ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (NULL);
}
BIO_set_fp(b, in, BIO_NOCLOSE);
ret = ASN1_item_d2i_bio(it, b, x);
BIO_free(b);
return (ret);
}
#define HEADER_SIZE 8
#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
static int
asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
int i;
ASN1_const_CTX c;
size_t want = HEADER_SIZE;
int eos = 0;
size_t off = 0;
size_t len = 0;
b = BUF_MEM_new();
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return -1;
}
ERR_clear_error();
for (;;) {
if (want >= (len - off)) {
want -= (len - off);
if (len + want < len ||
!BUF_MEM_grow_clean(b, len + want)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
i = BIO_read(in, &(b->data[len]), want);
if ((i < 0) && ((len - off) == 0)) {
ASN1error(ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0) {
if (len + i < len) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
len += i;
}
}
/* else data already loaded */
p = (unsigned char *) & (b->data[off]);
c.p = p;
c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag),
&(c.xclass), len - off);
if (c.inf & 0x80) {
unsigned long e;
e = ERR_GET_REASON(ERR_peek_error());
if (e != ASN1_R_TOO_LONG)
goto err;
else
ERR_clear_error(); /* clear error */
}
i = c.p - p; /* header length */
off += i; /* end of data */
if (c.inf & 1) {
/* no data body so go round again */
eos++;
if (eos < 0) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
goto err;
}
want = HEADER_SIZE;
} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
/* eos value, so go back and read another header */
eos--;
if (eos <= 0)
break;
else
want = HEADER_SIZE;
} else {
/* suck in c.slen bytes of data */
want = c.slen;
if (want > (len - off)) {
size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
want -= (len - off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
while (want > 0) {
/*
* Read content in chunks of increasing size
* so we can return an error for EOF without
* having to allocate the entire content length
* in one go.
*/
size_t chunk = want > chunk_max ? chunk_max : want;
if (!BUF_MEM_grow_clean(b, len + chunk)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
want -= chunk;
while (chunk > 0) {
i = BIO_read(in, &(b->data[len]), chunk);
if (i <= 0) {
ASN1error(ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/*
* This can't overflow because |len+want|
* didn't overflow.
*/
len += i;
chunk -= i;
}
if (chunk_max < INT_MAX/2)
chunk_max *= 2;
}
}
if (off + c.slen < off) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
off += c.slen;
if (eos <= 0) {
break;
} else
want = HEADER_SIZE;
}
}
if (off > INT_MAX) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
*pb = b;
return off;
err:
if (b != NULL)
BUF_MEM_free(b);
return -1;
}

84
crypto/asn1/a_digest.c Normal file
View File

@ -0,0 +1,84 @@
/* $OpenBSD: a_digest.c,v 1.15 2014/07/11 08:44:47 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.]
*/
#include <sys/types.h>
#include <stdio.h>
#include <time.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
int
ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
unsigned char *md, unsigned int *len)
{
int i;
unsigned char *str = NULL;
i = ASN1_item_i2d(asn, &str, it);
if (!str)
return (0);
if (!EVP_Digest(str, i, md, len, type, NULL))
return 0;
free(str);
return (1);
}

118
crypto/asn1/a_dup.c Normal file
View File

@ -0,0 +1,118 @@
/* $OpenBSD: a_dup.c,v 1.14 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/err.h>
#ifndef NO_OLD_ASN1
void *
ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
{
unsigned char *b, *p;
const unsigned char *p2;
int i;
char *ret;
if (x == NULL)
return (NULL);
i = i2d(x, NULL);
b = malloc(i + 10);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
i = i2d(x, &p);
p2 = b;
ret = d2i(NULL, &p2, i);
free(b);
return (ret);
}
#endif
/* ASN1_ITEM version of dup: this follows the model above except we don't need
* to allocate the buffer. At some point this could be rewritten to directly dup
* the underlying structure instead of doing and encode and decode.
*/
void *
ASN1_item_dup(const ASN1_ITEM *it, void *x)
{
unsigned char *b = NULL;
const unsigned char *p;
long i;
void *ret;
if (x == NULL)
return (NULL);
i = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
p = b;
ret = ASN1_item_d2i(NULL, &p, i, it);
free(b);
return (ret);
}

189
crypto/asn1/a_enum.c Normal file
View File

@ -0,0 +1,189 @@
/* $OpenBSD: a_enum.c,v 1.18 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
/*
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
* for comments on encoding see a_int.c
*/
int
ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type = V_ASN1_ENUMERATED;
if (a->length < (int)(sizeof(long) + 1)) {
free(a->data);
a->data = calloc(1, sizeof(long) + 1);
}
if (a->data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_ENUMERATED;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
long
ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
{
int neg = 0, i;
long r = 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_ENUMERATED)
neg = 1;
else if (i != V_ASN1_ENUMERATED)
return -1;
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly */
return -1;
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (neg)
r = -r;
return (r);
}
ASN1_ENUMERATED *
BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
{
ASN1_ENUMERATED *ret;
int len, j;
if (ai == NULL)
ret = ASN1_ENUMERATED_new();
else
ret = ai;
if (ret == NULL) {
ASN1error(ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_ENUMERATED;
else
ret->type = V_ASN1_ENUMERATED;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = realloc(ret->data, len + 4);
if (!new_data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length = BN_bn2bin(bn, ret->data);
/* Correct zero case */
if (!ret->length) {
ret->data[0] = 0;
ret->length = 1;
}
return (ret);
err:
if (ret != ai)
ASN1_ENUMERATED_free(ret);
return (NULL);
}
BIGNUM *
ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
{
BIGNUM *ret;
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
ASN1error(ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_ENUMERATED)
BN_set_negative(ret, 1);
return (ret);
}

158
crypto/asn1/a_i2d_fp.c Normal file
View File

@ -0,0 +1,158 @@
/* $OpenBSD: a_i2d_fp.c,v 1.15 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#ifndef NO_OLD_ASN1
int
ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_i2d_bio(i2d, b, x);
BIO_free(b);
return (ret);
}
int
ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
{
char *b;
unsigned char *p;
int i, j = 0, n, ret = 1;
n = i2d(x, NULL);
b = malloc(n);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
p = (unsigned char *)b;
i2d(x, &p);
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
free(b);
return (ret);
}
#endif
int
ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
ASN1error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, out, BIO_NOCLOSE);
ret = ASN1_item_i2d_bio(it, b, x);
BIO_free(b);
return (ret);
}
int
ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
{
unsigned char *b = NULL;
int i, j = 0, n, ret = 1;
n = ASN1_item_i2d(x, &b, it);
if (b == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
for (;;) {
i = BIO_write(out, &(b[j]), n);
if (i == n)
break;
if (i <= 0) {
ret = 0;
break;
}
j += i;
n -= i;
}
free(b);
return (ret);
}

461
crypto/asn1/a_int.c Normal file
View File

@ -0,0 +1,461 @@
/* $OpenBSD: a_int.c,v 1.31 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
ASN1_INTEGER *
ASN1_INTEGER_dup(const ASN1_INTEGER *x)
{
return ASN1_STRING_dup(x);
}
int
ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
{
int neg, ret;
/* Compare signs */
neg = x->type & V_ASN1_NEG;
if (neg != (y->type & V_ASN1_NEG)) {
if (neg)
return -1;
else
return 1;
}
ret = ASN1_STRING_cmp(x, y);
if (neg)
return -ret;
else
return ret;
}
/*
* This converts an ASN1 INTEGER into its content encoding.
* The internal representation is an ASN1_STRING whose data is a big endian
* representation of the value, ignoring the sign. The sign is determined by
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
*
* Positive integers are no problem: they are almost the same as the DER
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
*
* Negative integers are a bit trickier...
* The DER representation of negative integers is in 2s complement form.
* The internal form is converted by complementing each octet and finally
* adding one to the result. This can be done less messily with a little trick.
* If the internal form has trailing zeroes then they will become FF by the
* complement and 0 by the add one (due to carry) so just copy as many trailing
* zeros to the destination as there are in the source. The carry will add one
* to the last none zero octet: so complement this octet and add one and finally
* complement any left over until you get to the start of the string.
*
* Padding is a little trickier too. If the first bytes is > 0x80 then we pad
* with 0xff. However if the first byte is 0x80 and one of the following bytes
* is non-zero we pad with 0xff. The reason for this distinction is that 0x80
* followed by optional zeros isn't padded.
*/
int
i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
{
int pad = 0, ret, i, neg;
unsigned char *p, *n, pb = 0;
if (a == NULL)
return (0);
neg = a->type & V_ASN1_NEG;
if (a->length == 0)
ret = 1;
else {
ret = a->length;
i = a->data[0];
if (!neg && (i > 127)) {
pad = 1;
pb = 0;
} else if (neg) {
if (i > 128) {
pad = 1;
pb = 0xFF;
} else if (i == 128) {
/*
* Special case: if any other bytes non zero we pad:
* otherwise we don't.
*/
for (i = 1; i < a->length; i++) if (a->data[i]) {
pad = 1;
pb = 0xFF;
break;
}
}
}
ret += pad;
}
if (pp == NULL)
return (ret);
p= *pp;
if (pad)
*(p++) = pb;
if (a->length == 0)
*(p++) = 0;
else if (!neg)
memcpy(p, a->data, a->length);
else {
/* Begin at the end of the encoding */
n = a->data + a->length - 1;
p += a->length - 1;
i = a->length;
/* Copy zeros to destination as long as source is zero */
while (!*n) {
*(p--) = 0;
n--;
i--;
}
/* Complement and increment next octet */
*(p--) = ((*(n--)) ^ 0xff) + 1;
i--;
/* Complement any octets left */
for (; i > 0; i--)
*(p--) = *(n--) ^ 0xff;
}
*pp += ret;
return (ret);
}
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
ASN1_INTEGER *
c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
{
ASN1_INTEGER *ret = NULL;
const unsigned char *p, *pend;
unsigned char *to, *s;
int i;
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_INTEGER_new()) == NULL)
return (NULL);
} else
ret = (*a);
p = *pp;
pend = p + len;
/* We must malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s = malloc(len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
to = s;
if (!len) {
/* Strictly speaking this is an illegal INTEGER but we
* tolerate it.
*/
ret->type = V_ASN1_INTEGER;
} else if (*p & 0x80) /* a negative number */ {
ret->type = V_ASN1_NEG_INTEGER;
if ((*p == 0xff) && (len != 1)) {
p++;
len--;
}
i = len;
p += i - 1;
to += i - 1;
while((!*p) && i) {
*(to--) = 0;
i--;
p--;
}
/* Special case: if all zeros then the number will be of
* the form FF followed by n zero bytes: this corresponds to
* 1 followed by n zero bytes. We've already written n zeros
* so we just append an extra one and set the first byte to
* a 1. This is treated separately because it is the only case
* where the number of bytes is larger than len.
*/
if (!i) {
*s = 1;
s[len] = 0;
len++;
} else {
*(to--) = (*(p--) ^ 0xff) + 1;
i--;
for (; i > 0; i--)
*(to--) = *(p--) ^ 0xff;
}
} else {
ret->type = V_ASN1_INTEGER;
if ((*p == 0) && (len != 1)) {
p++;
len--;
}
memcpy(s, p, len);
}
free(ret->data);
ret->data = s;
ret->length = (int)len;
if (a != NULL)
(*a) = ret;
*pp = pend;
return (ret);
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_INTEGER_free(ret);
return (NULL);
}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
* ASN1 integers: some broken software can encode a positive INTEGER
* with its MSB set as negative (it doesn't add a padding zero).
*/
ASN1_INTEGER *
d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
{
ASN1_INTEGER *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
int i;
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_INTEGER_new()) == NULL)
return (NULL);
} else
ret = (*a);
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_INTEGER) {
i = ASN1_R_EXPECTING_AN_INTEGER;
goto err;
}
/* We must malloc stuff, even for 0 bytes otherwise it
* signifies a missing NULL parameter. */
s = malloc(len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
ret->type = V_ASN1_INTEGER;
if (len) {
if ((*p == 0) && (len != 1)) {
p++;
len--;
}
memcpy(s, p, len);
p += len;
}
free(ret->data);
ret->data = s;
ret->length = (int)len;
if (a != NULL)
(*a) = ret;
*pp = p;
return (ret);
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_INTEGER_free(ret);
return (NULL);
}
int
ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
{
int j, k;
unsigned int i;
unsigned char buf[sizeof(long) + 1];
long d;
a->type = V_ASN1_INTEGER;
/* XXX ssl/ssl_asn1.c:i2d_SSL_SESSION() depends upon this bound vae */
if (a->length < (int)(sizeof(long) + 1)) {
free(a->data);
a->data = calloc(1, sizeof(long) + 1);
}
if (a->data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
d = v;
if (d < 0) {
d = -d;
a->type = V_ASN1_NEG_INTEGER;
}
for (i = 0; i < sizeof(long); i++) {
if (d == 0)
break;
buf[i] = (int)d & 0xff;
d >>= 8;
}
j = 0;
for (k = i - 1; k >= 0; k--)
a->data[j++] = buf[k];
a->length = j;
return (1);
}
long
ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
long r = 0;
if (a == NULL)
return (0L);
i = a->type;
if (i == V_ASN1_NEG_INTEGER)
neg = 1;
else if (i != V_ASN1_INTEGER)
return -1;
if (a->length > (int)sizeof(long)) {
/* hmm... a bit ugly, return all ones */
return -1;
}
if (a->data == NULL)
return 0;
for (i = 0; i < a->length; i++) {
r <<= 8;
r |= (unsigned char)a->data[i];
}
if (neg)
r = -r;
return (r);
}
ASN1_INTEGER *
BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
{
ASN1_INTEGER *ret;
int len, j;
if (ai == NULL)
ret = ASN1_INTEGER_new();
else
ret = ai;
if (ret == NULL) {
ASN1error(ERR_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn))
ret->type = V_ASN1_NEG_INTEGER;
else
ret->type = V_ASN1_INTEGER;
j = BN_num_bits(bn);
len = ((j == 0) ? 0 : ((j / 8) + 1));
if (ret->length < len + 4) {
unsigned char *new_data = realloc(ret->data, len + 4);
if (!new_data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data = new_data;
}
ret->length = BN_bn2bin(bn, ret->data);
/* Correct zero case */
if (!ret->length) {
ret->data[0] = 0;
ret->length = 1;
}
return (ret);
err:
if (ret != ai)
ASN1_INTEGER_free(ret);
return (NULL);
}
BIGNUM *
ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
{
BIGNUM *ret;
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
ASN1error(ASN1_R_BN_LIB);
else if (ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return (ret);
}

447
crypto/asn1/a_mbstr.c Normal file
View File

@ -0,0 +1,447 @@
/* $OpenBSD: a_mbstr.c,v 1.23 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "asn1_locl.h"
static int traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg);
static int in_utf8(unsigned long value, void *arg);
static int out_utf8(unsigned long value, void *arg);
static int type_str(unsigned long value, void *arg);
static int cpy_asc(unsigned long value, void *arg);
static int cpy_bmp(unsigned long value, void *arg);
static int cpy_univ(unsigned long value, void *arg);
static int cpy_utf8(unsigned long value, void *arg);
static int is_printable(unsigned long value);
/* These functions take a string in UTF8, ASCII or multibyte form and
* a mask of permissible ASN1 string types. It then works out the minimal
* type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
* and creates a string of the correct type with the supplied data.
* Yes this is horrible: it has to be :-(
* The 'ncopy' form checks minimum and maximum size limits too.
*/
int
ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask)
{
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
}
int
ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask, long minsize, long maxsize)
{
int str_type;
int ret;
char free_out;
int outform, outlen = 0;
ASN1_STRING *dest;
unsigned char *p;
int nchar;
int (*cpyfunc)(unsigned long, void *) = NULL;
if (len < 0)
len = strlen((const char *)in);
if (!mask)
mask = DIRSTRING_TYPE;
/* First do a string check and work out the number of characters */
switch (inform) {
case MBSTRING_BMP:
if (len & 1) {
ASN1error(ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
break;
case MBSTRING_UNIV:
if (len & 3) {
ASN1error(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
break;
case MBSTRING_UTF8:
nchar = 0;
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if (ret < 0) {
ASN1error(ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
case MBSTRING_ASC:
nchar = len;
break;
default:
ASN1error(ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if ((minsize > 0) && (nchar < minsize)) {
ASN1error(ASN1_R_STRING_TOO_SHORT);
ERR_asprintf_error_data("minsize=%ld", minsize);
return -1;
}
if ((maxsize > 0) && (nchar > maxsize)) {
ASN1error(ASN1_R_STRING_TOO_LONG);
ERR_asprintf_error_data("maxsize=%ld", maxsize);
return -1;
}
/* Now work out minimal type (if any) */
if (traverse_string(in, len, inform, type_str, &mask) < 0) {
ASN1error(ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
/* Now work out output format and string type */
outform = MBSTRING_ASC;
if (mask & B_ASN1_PRINTABLESTRING)
str_type = V_ASN1_PRINTABLESTRING;
else if (mask & B_ASN1_IA5STRING)
str_type = V_ASN1_IA5STRING;
else if (mask & B_ASN1_T61STRING)
str_type = V_ASN1_T61STRING;
else if (mask & B_ASN1_BMPSTRING) {
str_type = V_ASN1_BMPSTRING;
outform = MBSTRING_BMP;
} else if (mask & B_ASN1_UNIVERSALSTRING) {
str_type = V_ASN1_UNIVERSALSTRING;
outform = MBSTRING_UNIV;
} else {
str_type = V_ASN1_UTF8STRING;
outform = MBSTRING_UTF8;
}
if (!out)
return str_type;
if (*out) {
free_out = 0;
dest = *out;
if (dest->data) {
dest->length = 0;
free(dest->data);
dest->data = NULL;
}
dest->type = str_type;
} else {
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if (!dest) {
ASN1error(ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
}
/* If both the same type just copy across */
if (inform == outform) {
if (!ASN1_STRING_set(dest, in, len)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
return str_type;
}
/* Work out how much space the destination will need */
switch (outform) {
case MBSTRING_ASC:
outlen = nchar;
cpyfunc = cpy_asc;
break;
case MBSTRING_BMP:
outlen = nchar << 1;
cpyfunc = cpy_bmp;
break;
case MBSTRING_UNIV:
outlen = nchar << 2;
cpyfunc = cpy_univ;
break;
case MBSTRING_UTF8:
outlen = 0;
if (traverse_string(in, len, inform, out_utf8, &outlen) < 0) {
ASN1error(ASN1_R_ILLEGAL_CHARACTERS);
goto err;
}
cpyfunc = cpy_utf8;
break;
}
if (!(p = malloc(outlen + 1))) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
dest->length = outlen;
dest->data = p;
p[outlen] = 0;
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
err:
if (free_out) {
ASN1_STRING_free(dest);
*out = NULL;
}
return -1;
}
/* This function traverses a string and passes the value of each character
* to an optional function along with a void * argument.
*/
static int
traverse_string(const unsigned char *p, int len, int inform,
int (*rfunc)(unsigned long value, void *in), void *arg)
{
unsigned long value;
int ret;
while (len) {
switch (inform) {
case MBSTRING_ASC:
value = *p++;
len--;
break;
case MBSTRING_BMP:
value = *p++ << 8;
value |= *p++;
/* BMP is explictly defined to not support surrogates */
if (UNICODE_IS_SURROGATE(value))
return -1;
len -= 2;
break;
case MBSTRING_UNIV:
value = (unsigned long)*p++ << 24;
value |= *p++ << 16;
value |= *p++ << 8;
value |= *p++;
if (value > UNICODE_MAX || UNICODE_IS_SURROGATE(value))
return -1;
len -= 4;
break;
default:
ret = UTF8_getc(p, len, &value);
if (ret < 0)
return -1;
len -= ret;
p += ret;
break;
}
if (rfunc) {
ret = rfunc(value, arg);
if (ret <= 0)
return ret;
}
}
return 1;
}
/* Various utility functions for traverse_string */
/* Just count number of characters */
static int
in_utf8(unsigned long value, void *arg)
{
int *nchar;
nchar = arg;
(*nchar)++;
return 1;
}
/* Determine size of output as a UTF8 String */
static int
out_utf8(unsigned long value, void *arg)
{
int *outlen;
int ret;
outlen = arg;
ret = UTF8_putc(NULL, -1, value);
if (ret < 0)
return ret;
*outlen += ret;
return 1;
}
/* Determine the "type" of a string: check each character against a
* supplied "mask".
*/
static int
type_str(unsigned long value, void *arg)
{
unsigned long types;
types = *((unsigned long *)arg);
if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
types &= ~B_ASN1_PRINTABLESTRING;
if ((types & B_ASN1_IA5STRING) && (value > 127))
types &= ~B_ASN1_IA5STRING;
if ((types & B_ASN1_T61STRING) && (value > 0xff))
types &= ~B_ASN1_T61STRING;
if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
types &= ~B_ASN1_BMPSTRING;
if (!types)
return -1;
*((unsigned long *)arg) = types;
return 1;
}
/* Copy one byte per character ASCII like strings */
static int
cpy_asc(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q = value;
(*p)++;
return 1;
}
/* Copy two byte per character BMPStrings */
static int
cpy_bmp(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (value >> 8) & 0xff;
*q = value & 0xff;
*p += 2;
return 1;
}
/* Copy four byte per character UniversalStrings */
static int
cpy_univ(unsigned long value, void *arg)
{
unsigned char **p, *q;
p = arg;
q = *p;
*q++ = (value >> 24) & 0xff;
*q++ = (value >> 16) & 0xff;
*q++ = (value >> 8) & 0xff;
*q = value & 0xff;
*p += 4;
return 1;
}
/* Copy to a UTF8String */
static int
cpy_utf8(unsigned long value, void *arg)
{
unsigned char **p;
int ret;
p = arg;
/* We already know there is enough room so pass 0xff as the length */
ret = UTF8_putc(*p, 0xff, value);
*p += ret;
return 1;
}
/* Return 1 if the character is permitted in a PrintableString */
static int
is_printable(unsigned long value)
{
int ch;
if (value > 0x7f)
return 0;
ch = (int)value;
/* Note: we can't use 'isalnum' because certain accented
* characters may count as alphanumeric in some environments.
*/
if ((ch >= 'a') && (ch <= 'z'))
return 1;
if ((ch >= 'A') && (ch <= 'Z'))
return 1;
if ((ch >= '0') && (ch <= '9'))
return 1;
if ((ch == ' ') || strchr("'()+,-./:=?", ch))
return 1;
return 0;
}

401
crypto/asn1/a_object.c Normal file
View File

@ -0,0 +1,401 @@
/* $OpenBSD: a_object.c,v 1.30 2017/05/02 03:59:44 deraadt 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/buffer.h>
#include <openssl/objects.h>
int
i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
if ((a == NULL) || (a->data == NULL))
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
if (pp == NULL)
return objsize;
p = *pp;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
p += a->length;
*pp = p;
return (objsize);
}
int
a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
int i, first, len = 0, c, use_bn;
char ftmp[24], *tmp = ftmp;
int tmpsize = sizeof ftmp;
const char *p;
unsigned long l;
BIGNUM *bl = NULL;
if (num == 0)
return (0);
else if (num == -1)
num = strlen(buf);
p = buf;
c = *(p++);
num--;
if ((c >= '0') && (c <= '2')) {
first= c-'0';
} else {
ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0) {
ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c = *(p++);
num--;
for (;;) {
if (num <= 0)
break;
if ((c != '.') && (c != ' ')) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
goto err;
}
l = 0;
use_bn = 0;
for (;;) {
if (num <= 0)
break;
num--;
c = *(p++);
if ((c == ' ') || (c == '.'))
break;
if ((c < '0') || (c > '9')) {
ASN1error(ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
use_bn = 1;
if (!bl)
bl = BN_new();
if (!bl || !BN_set_word(bl, l))
goto err;
}
if (use_bn) {
if (!BN_mul_word(bl, 10L) ||
!BN_add_word(bl, c-'0'))
goto err;
} else
l = l * 10L + (long)(c - '0');
}
if (len == 0) {
if ((first < 2) && (l >= 40)) {
ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn) {
if (!BN_add_word(bl, first * 40))
goto err;
} else
l += (long)first * 40;
}
i = 0;
if (use_bn) {
int blsize;
blsize = BN_num_bits(bl);
blsize = (blsize + 6) / 7;
if (blsize > tmpsize) {
if (tmp != ftmp)
free(tmp);
tmpsize = blsize + 32;
tmp = malloc(tmpsize);
if (!tmp)
goto err;
}
while (blsize--)
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
} else {
for (;;) {
tmp[i++] = (unsigned char)l & 0x7f;
l >>= 7L;
if (l == 0L)
break;
}
}
if (out != NULL) {
if (len + i > olen) {
ASN1error(ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
out[len++] = tmp[i]|0x80;
out[len++] = tmp[0];
} else
len += i;
}
if (tmp != ftmp)
free(tmp);
BN_free(bl);
return (len);
err:
if (tmp != ftmp)
free(tmp);
BN_free(bl);
return (0);
}
int
i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int
i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
{
char *tmp = NULL;
size_t tlen = 256;
int i = -1;
if ((a == NULL) || (a->data == NULL))
return(BIO_write(bp, "NULL", 4));
if ((tmp = malloc(tlen)) == NULL)
return -1;
i = i2t_ASN1_OBJECT(tmp, tlen, a);
if (i > (int)(tlen - 1)) {
freezero(tmp, tlen);
if ((tmp = malloc(i + 1)) == NULL)
return -1;
tlen = i + 1;
i = i2t_ASN1_OBJECT(tmp, tlen, a);
}
if (i <= 0)
i = BIO_write(bp, "<INVALID>", 9);
else
i = BIO_write(bp, tmp, i);
freezero(tmp, tlen);
return (i);
}
ASN1_OBJECT *
d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long length)
{
const unsigned char *p;
long len;
int tag, xclass;
int inf, i;
ASN1_OBJECT *ret = NULL;
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
i = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != V_ASN1_OBJECT) {
i = ASN1_R_EXPECTING_AN_OBJECT;
goto err;
}
ret = c2i_ASN1_OBJECT(a, &p, len);
if (ret)
*pp = p;
return ret;
err:
ASN1error(i);
return (NULL);
}
ASN1_OBJECT *
c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, long len)
{
ASN1_OBJECT *ret;
const unsigned char *p;
unsigned char *data;
int i, length;
/*
* Sanity check OID encoding:
* - need at least one content octet
* - MSB must be clear in the last octet
* - can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
*/
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
return (NULL);
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
length = (int)len;
for (i = 0; i < length; i++, p++) {
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
return (NULL);
}
}
/* only the ASN1_OBJECTs from the 'table' will have values
* for ->sn or ->ln */
if ((a == NULL) || ((*a) == NULL) ||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
if ((ret = ASN1_OBJECT_new()) == NULL)
return (NULL);
} else
ret = *a;
p = *pp;
/* detach data from object */
data = (unsigned char *)ret->data;
freezero(data, ret->length);
data = malloc(length);
if (data == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(data, p, length);
/* reattach data to object, after which it remains const */
ret->data = data;
ret->length = length;
ret->sn = NULL;
ret->ln = NULL;
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
p += length;
if (a != NULL)
*a = ret;
*pp = p;
return (ret);
err:
if (a == NULL || ret != *a)
ASN1_OBJECT_free(ret);
return (NULL);
}
ASN1_OBJECT *
ASN1_OBJECT_new(void)
{
ASN1_OBJECT *ret;
ret = malloc(sizeof(ASN1_OBJECT));
if (ret == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->data = NULL;
ret->nid = 0;
ret->sn = NULL;
ret->ln = NULL;
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
return (ret);
}
void
ASN1_OBJECT_free(ASN1_OBJECT *a)
{
if (a == NULL)
return;
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
free((void *)a->sn);
free((void *)a->ln);
a->sn = a->ln = NULL;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
freezero((void *)a->data, a->length);
a->data = NULL;
a->length = 0;
}
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
free(a);
}
ASN1_OBJECT *
ASN1_OBJECT_create(int nid, unsigned char *data, int len,
const char *sn, const char *ln)
{
ASN1_OBJECT o;
o.sn = sn;
o.ln = ln;
o.data = data;
o.nid = nid;
o.length = len;
o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return (OBJ_dup(&o));
}

79
crypto/asn1/a_octet.c Normal file
View File

@ -0,0 +1,79 @@
/* $OpenBSD: a_octet.c,v 1.10 2015/07/29 14:58:34 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.]
*/
#include <stdio.h>
#include <openssl/asn1.h>
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
{
return ASN1_STRING_dup(x);
}
int
ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
{
return ASN1_STRING_cmp(a, b);
}
int
ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{
return ASN1_STRING_set(x, d, len);
}

125
crypto/asn1/a_print.c Normal file
View File

@ -0,0 +1,125 @@
/* $OpenBSD: a_print.c,v 1.11 2014/07/11 08:44:47 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.]
*/
#include <stdio.h>
#include <openssl/asn1.h>
int
ASN1_PRINTABLE_type(const unsigned char *s, int len)
{
int c;
int ia5 = 0;
int t61 = 0;
if (len <= 0)
len = -1;
if (s == NULL)
return (V_ASN1_PRINTABLESTRING);
while ((*s) && (len-- != 0)) {
c= *(s++);
if (!(((c >= 'a') && (c <= 'z')) ||
((c >= 'A') && (c <= 'Z')) ||
(c == ' ') ||
((c >= '0') && (c <= '9')) ||
(c == ' ') || (c == '\'') ||
(c == '(') || (c == ')') ||
(c == '+') || (c == ',') ||
(c == '-') || (c == '.') ||
(c == '/') || (c == ':') ||
(c == '=') || (c == '?')))
ia5 = 1;
if (c & 0x80)
t61 = 1;
}
if (t61)
return (V_ASN1_T61STRING);
if (ia5)
return (V_ASN1_IA5STRING);
return (V_ASN1_PRINTABLESTRING);
}
int
ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
{
int i;
unsigned char *p;
if (s->type != V_ASN1_UNIVERSALSTRING)
return (0);
if ((s->length % 4) != 0)
return (0);
p = s->data;
for (i = 0; i < s->length; i += 4) {
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
break;
else
p += 4;
}
if (i < s->length)
return (0);
p = s->data;
for (i = 3; i < s->length; i += 4) {
*(p++) = s->data[i];
}
*(p) = '\0';
s->length /= 4;
s->type = ASN1_PRINTABLE_type(s->data, s->length);
return (1);
}

236
crypto/asn1/a_set.c Normal file
View File

@ -0,0 +1,236 @@
/* $OpenBSD: a_set.c,v 1.18 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/asn1_mac.h>
#include <openssl/err.h>
#ifndef NO_ASN1_OLD
typedef struct {
unsigned char *pbData;
int cbData;
} MYBLOB;
/* SetBlobCmp
* This function compares two elements of SET_OF block
*/
static int
SetBlobCmp(const void *elem1, const void *elem2)
{
const MYBLOB *b1 = (const MYBLOB *)elem1;
const MYBLOB *b2 = (const MYBLOB *)elem2;
int r;
r = memcmp(b1->pbData, b2->pbData,
b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
if (r != 0)
return r;
return b1->cbData - b2->cbData;
}
/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
int
i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, i2d_of_void *i2d,
int ex_tag, int ex_class, int is_set)
{
int ret = 0, r;
int i;
unsigned char *p;
unsigned char *pStart, *pTempMem;
MYBLOB *rgSetBlob;
int totSize;
if (a == NULL)
return 0;
for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
r = ASN1_object_size(1, ret, ex_tag);
if (pp == NULL)
return r;
p = *pp;
ASN1_put_object(&p, 1, ret, ex_tag, ex_class);
/* Modified by gp@nsj.co.jp */
/* And then again by Ben */
/* And again by Steve */
if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
*pp = p;
return r;
}
pStart = p; /* Catch the beg of Setblobs*/
/* In this array we will store the SET blobs */
rgSetBlob = reallocarray(NULL, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB));
if (rgSetBlob == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
rgSetBlob[i].pbData = p; /* catch each set encode blob */
i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
/* Length of this SetBlob */
rgSetBlob[i].cbData = p - rgSetBlob[i].pbData;
}
*pp = p;
totSize = p - pStart; /* This is the total size of all set blobs */
/* Now we have to sort the blobs. I am using a simple algo.
* Sort ptrs
* Copy to temp-mem
* Copy from temp-mem to user-mem
*/
qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
if ((pTempMem = malloc(totSize)) == NULL) {
free(rgSetBlob);
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
/* Copy to temp mem */
p = pTempMem;
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
p += rgSetBlob[i].cbData;
}
/* Copy back to user mem*/
memcpy(pStart, pTempMem, totSize);
free(pTempMem);
free(rgSetBlob);
return r;
}
STACK_OF(OPENSSL_BLOCK) *
d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, const unsigned char **pp, long length,
d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK), int ex_tag,
int ex_class)
{
ASN1_const_CTX c;
STACK_OF(OPENSSL_BLOCK) *ret = NULL;
if (a == NULL || (*a) == NULL) {
if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
} else
ret = *a;
c.p = *pp;
c.max = (length == 0) ? 0 : (c.p + length);
c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p);
if (c.inf & 0x80)
goto err;
if (ex_class != c.xclass) {
ASN1error(ASN1_R_BAD_CLASS);
goto err;
}
if (ex_tag != c.tag) {
ASN1error(ASN1_R_BAD_TAG);
goto err;
}
if (c.slen + c.p > c.max) {
ASN1error(ASN1_R_LENGTH_ERROR);
goto err;
}
/* check for infinite constructed - it can be as long
* as the amount of data passed to us */
if (c.inf == (V_ASN1_CONSTRUCTED + 1))
c.slen = length + *pp - c.p;
c.max = c.p + c.slen;
while (c.p < c.max) {
char *s;
if (M_ASN1_D2I_end_sequence())
break;
if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
ASN1error(ASN1_R_ERROR_PARSING_SET_ELEMENT);
asn1_add_error(*pp, (int)(c.p - *pp));
goto err;
}
if (!sk_OPENSSL_BLOCK_push(ret, s))
goto err;
}
if (a != NULL)
*a = ret;
*pp = c.p;
return ret;
err:
if (a == NULL || *a != ret) {
if (free_func != NULL)
sk_OPENSSL_BLOCK_pop_free(ret, free_func);
else
sk_OPENSSL_BLOCK_free(ret);
}
return NULL;
}
#endif

233
crypto/asn1/a_sign.c Normal file
View File

@ -0,0 +1,233 @@
/* $OpenBSD: a_sign.c,v 1.23 2017/05/02 03:59:44 deraadt 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-2003 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 <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
int
ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type)
{
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
}
int
ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
{
const EVP_MD *type;
EVP_PKEY *pkey;
unsigned char *buf_in = NULL, *buf_out = NULL;
size_t inl = 0, outl = 0, outll = 0;
int signid, paramtype;
int rv;
type = EVP_MD_CTX_md(ctx);
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!type || !pkey) {
ASN1error(ASN1_R_CONTEXT_NOT_INITIALISED);
return 0;
}
if (pkey->ameth->item_sign) {
rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
signature);
if (rv == 1)
outl = signature->length;
/* Return value meanings:
* <=0: error.
* 1: method does everything.
* 2: carry on as normal.
* 3: ASN1 method sets algorithm identifiers: just sign.
*/
if (rv <= 0)
ASN1error(ERR_R_EVP_LIB);
if (rv <= 1)
goto err;
} else
rv = 2;
if (rv == 2) {
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
if (!pkey->ameth ||
!OBJ_find_sigid_by_algs(&signid,
EVP_MD_nid(type), pkey->ameth->pkey_id)) {
ASN1error(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
}
} else
signid = type->pkey_type;
if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
paramtype = V_ASN1_NULL;
else
paramtype = V_ASN1_UNDEF;
if (algor1)
X509_ALGOR_set0(algor1,
OBJ_nid2obj(signid), paramtype, NULL);
if (algor2)
X509_ALGOR_set0(algor2,
OBJ_nid2obj(signid), paramtype, NULL);
}
inl = ASN1_item_i2d(asn, &buf_in, it);
outll = outl = EVP_PKEY_size(pkey);
buf_out = malloc(outl);
if ((buf_in == NULL) || (buf_out == NULL)) {
outl = 0;
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestSignUpdate(ctx, buf_in, inl) ||
!EVP_DigestSignFinal(ctx, buf_out, &outl)) {
outl = 0;
ASN1error(ERR_R_EVP_LIB);
goto err;
}
free(signature->data);
signature->data = buf_out;
buf_out = NULL;
signature->length = outl;
/* In the interests of compatibility, I'll make sure that
* the bit string has a 'not-used bits' value of 0
*/
signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
err:
EVP_MD_CTX_cleanup(ctx);
freezero((char *)buf_in, inl);
freezero((char *)buf_out, outll);
return (outl);
}

646
crypto/asn1/a_strex.c Normal file
View File

@ -0,0 +1,646 @@
/* $OpenBSD: a_strex.c,v 1.25 2015/02/07 13:19:15 doug 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 <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "charmap.h"
/* ASN1_STRING_print_ex() and X509_NAME_print_ex().
* Enhanced string and name printing routines handling
* multibyte characters, RFC2253 and a host of other
* options.
*/
#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253)
#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \
ASN1_STRFLGS_ESC_QUOTE | \
ASN1_STRFLGS_ESC_CTRL | \
ASN1_STRFLGS_ESC_MSB)
/* Three IO functions for sending data to memory, a BIO and
* and a FILE pointer.
*/
static int
send_bio_chars(void *arg, const void *buf, int len)
{
if (!arg)
return 1;
if (BIO_write(arg, buf, len) != len)
return 0;
return 1;
}
static int
send_fp_chars(void *arg, const void *buf, int len)
{
if (!arg)
return 1;
if (fwrite(buf, 1, (size_t)len, arg) != (size_t)len)
return 0;
return 1;
}
typedef int char_io(void *arg, const void *buf, int len);
/* This function handles display of
* strings, one character at a time.
* It is passed an unsigned long for each
* character because it could come from 2 or even
* 4 byte forms.
*/
static int
do_esc_char(unsigned long c, unsigned char flags, char *do_quotes,
char_io *io_ch, void *arg)
{
unsigned char chflgs, chtmp;
char tmphex[sizeof(long) * 2 + 3];
if (c > 0xffffffffL)
return -1;
if (c > 0xffff) {
snprintf(tmphex, sizeof tmphex, "\\W%08lX", c);
if (!io_ch(arg, tmphex, 10))
return -1;
return 10;
}
if (c > 0xff) {
snprintf(tmphex, sizeof tmphex, "\\U%04lX", c);
if (!io_ch(arg, tmphex, 6))
return -1;
return 6;
}
chtmp = (unsigned char)c;
if (chtmp > 0x7f)
chflgs = flags & ASN1_STRFLGS_ESC_MSB;
else
chflgs = char_type[chtmp] & flags;
if (chflgs & CHARTYPE_BS_ESC) {
/* If we don't escape with quotes, signal we need quotes */
if (chflgs & ASN1_STRFLGS_ESC_QUOTE) {
if (do_quotes)
*do_quotes = 1;
if (!io_ch(arg, &chtmp, 1))
return -1;
return 1;
}
if (!io_ch(arg, "\\", 1))
return -1;
if (!io_ch(arg, &chtmp, 1))
return -1;
return 2;
}
if (chflgs & (ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_ESC_MSB)) {
snprintf(tmphex, sizeof tmphex, "\\%02X", chtmp);
if (!io_ch(arg, tmphex, 3))
return -1;
return 3;
}
/* If we get this far and do any escaping at all must escape
* the escape character itself: backslash.
*/
if (chtmp == '\\' && flags & ESC_FLAGS) {
if (!io_ch(arg, "\\\\", 2))
return -1;
return 2;
}
if (!io_ch(arg, &chtmp, 1))
return -1;
return 1;
}
#define BUF_TYPE_WIDTH_MASK 0x7
#define BUF_TYPE_CONVUTF8 0x8
/* This function sends each character in a buffer to
* do_esc_char(). It interprets the content formats
* and converts to or from UTF8 as appropriate.
*/
static int
do_buf(unsigned char *buf, int buflen, int type, unsigned char flags,
char *quotes, char_io *io_ch, void *arg)
{
int i, outlen, len;
unsigned char orflags, *p, *q;
unsigned long c;
p = buf;
q = buf + buflen;
outlen = 0;
while (p != q) {
if (p == buf && flags & ASN1_STRFLGS_ESC_2253)
orflags = CHARTYPE_FIRST_ESC_2253;
else
orflags = 0;
switch (type & BUF_TYPE_WIDTH_MASK) {
case 4:
c = ((unsigned long)*p++) << 24;
c |= ((unsigned long)*p++) << 16;
c |= ((unsigned long)*p++) << 8;
c |= *p++;
if (c > UNICODE_MAX || UNICODE_IS_SURROGATE(c))
return -1;
break;
case 2:
c = ((unsigned long)*p++) << 8;
c |= *p++;
if (UNICODE_IS_SURROGATE(c))
return -1;
break;
case 1:
c = *p++;
break;
case 0:
i = UTF8_getc(p, q - p, &c);
if (i < 0)
return -1; /* Invalid UTF8String */
p += i;
break;
default:
return -1; /* invalid width */
}
if (p == q && flags & ASN1_STRFLGS_ESC_2253)
orflags = CHARTYPE_LAST_ESC_2253;
if (type & BUF_TYPE_CONVUTF8) {
unsigned char utfbuf[6];
int utflen;
utflen = UTF8_putc(utfbuf, sizeof utfbuf, c);
if (utflen < 0)
return -1;
for (i = 0; i < utflen; i++) {
/* We don't need to worry about setting orflags correctly
* because if utflen==1 its value will be correct anyway
* otherwise each character will be > 0x7f and so the
* character will never be escaped on first and last.
*/
len = do_esc_char(utfbuf[i],
(unsigned char)(flags | orflags), quotes,
io_ch, arg);
if (len < 0)
return -1;
outlen += len;
}
} else {
len = do_esc_char(c, (unsigned char)(flags | orflags),
quotes, io_ch, arg);
if (len < 0)
return -1;
outlen += len;
}
}
return outlen;
}
/* This function hex dumps a buffer of characters */
static int
do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, int buflen)
{
static const char hexdig[] = "0123456789ABCDEF";
unsigned char *p, *q;
char hextmp[2];
if (arg) {
p = buf;
q = buf + buflen;
while (p != q) {
hextmp[0] = hexdig[*p >> 4];
hextmp[1] = hexdig[*p & 0xf];
if (!io_ch(arg, hextmp, 2))
return -1;
p++;
}
}
return buflen << 1;
}
/* "dump" a string. This is done when the type is unknown,
* or the flags request it. We can either dump the content
* octets or the entire DER encoding. This uses the RFC2253
* #01234 format.
*/
static int
do_dump(unsigned long lflags, char_io *io_ch, void *arg, ASN1_STRING *str)
{
/* Placing the ASN1_STRING in a temp ASN1_TYPE allows
* the DER encoding to readily obtained
*/
ASN1_TYPE t;
unsigned char *der_buf, *p;
int outlen, der_len;
if (!io_ch(arg, "#", 1))
return -1;
/* If we don't dump DER encoding just dump content octets */
if (!(lflags & ASN1_STRFLGS_DUMP_DER)) {
outlen = do_hex_dump(io_ch, arg, str->data, str->length);
if (outlen < 0)
return -1;
return outlen + 1;
}
t.type = str->type;
t.value.ptr = (char *)str;
der_len = i2d_ASN1_TYPE(&t, NULL);
der_buf = malloc(der_len);
if (!der_buf)
return -1;
p = der_buf;
i2d_ASN1_TYPE(&t, &p);
outlen = do_hex_dump(io_ch, arg, der_buf, der_len);
free(der_buf);
if (outlen < 0)
return -1;
return outlen + 1;
}
/* Lookup table to convert tags to character widths,
* 0 = UTF8 encoded, -1 is used for non string types
* otherwise it is the number of bytes per character
*/
static const signed char tag2nbyte[] = {
-1, -1, -1, -1, -1, /* 0-4 */
-1, -1, -1, -1, -1, /* 5-9 */
-1, -1, 0, -1, /* 10-13 */
-1, -1, -1, -1, /* 15-17 */
-1, 1, 1, /* 18-20 */
-1, 1, 1, 1, /* 21-24 */
-1, 1, -1, /* 25-27 */
4, -1, 2 /* 28-30 */
};
/* This is the main function, print out an
* ASN1_STRING taking note of various escape
* and display options. Returns number of
* characters written or -1 if an error
* occurred.
*/
static int
do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, ASN1_STRING *str)
{
int outlen, len;
int type;
char quotes;
unsigned char flags;
quotes = 0;
/* Keep a copy of escape flags */
flags = (unsigned char)(lflags & ESC_FLAGS);
type = str->type;
outlen = 0;
if (lflags & ASN1_STRFLGS_SHOW_TYPE) {
const char *tagname;
tagname = ASN1_tag2str(type);
outlen += strlen(tagname);
if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1))
return -1;
outlen++;
}
/* Decide what to do with type, either dump content or display it */
/* Dump everything */
if (lflags & ASN1_STRFLGS_DUMP_ALL)
type = -1;
/* Ignore the string type */
else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
type = 1;
else {
/* Else determine width based on type */
if ((type > 0) && (type < 31))
type = tag2nbyte[type];
else
type = -1;
if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
type = 1;
}
if (type == -1) {
len = do_dump(lflags, io_ch, arg, str);
if (len < 0)
return -1;
outlen += len;
return outlen;
}
if (lflags & ASN1_STRFLGS_UTF8_CONVERT) {
/* Note: if string is UTF8 and we want
* to convert to UTF8 then we just interpret
* it as 1 byte per character to avoid converting
* twice.
*/
if (!type)
type = 1;
else
type |= BUF_TYPE_CONVUTF8;
}
len = do_buf(str->data, str->length, type, flags, &quotes, io_ch, NULL);
if (len < 0)
return -1;
outlen += len;
if (quotes)
outlen += 2;
if (!arg)
return outlen;
if (quotes && !io_ch(arg, "\"", 1))
return -1;
if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0)
return -1;
if (quotes && !io_ch(arg, "\"", 1))
return -1;
return outlen;
}
/* Used for line indenting: print 'indent' spaces */
static int
do_indent(char_io *io_ch, void *arg, int indent)
{
int i;
for (i = 0; i < indent; i++)
if (!io_ch(arg, " ", 1))
return 0;
return 1;
}
#define FN_WIDTH_LN 25
#define FN_WIDTH_SN 10
static int
do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, int indent,
unsigned long flags)
{
int i, prev = -1, orflags, cnt;
int fn_opt, fn_nid;
ASN1_OBJECT *fn;
ASN1_STRING *val;
X509_NAME_ENTRY *ent;
char objtmp[80];
const char *objbuf;
int outlen, len;
char *sep_dn, *sep_mv, *sep_eq;
int sep_dn_len, sep_mv_len, sep_eq_len;
if (indent < 0)
indent = 0;
outlen = indent;
if (!do_indent(io_ch, arg, indent))
return -1;
switch (flags & XN_FLAG_SEP_MASK) {
case XN_FLAG_SEP_MULTILINE:
sep_dn = "\n";
sep_dn_len = 1;
sep_mv = " + ";
sep_mv_len = 3;
break;
case XN_FLAG_SEP_COMMA_PLUS:
sep_dn = ",";
sep_dn_len = 1;
sep_mv = "+";
sep_mv_len = 1;
indent = 0;
break;
case XN_FLAG_SEP_CPLUS_SPC:
sep_dn = ", ";
sep_dn_len = 2;
sep_mv = " + ";
sep_mv_len = 3;
indent = 0;
break;
case XN_FLAG_SEP_SPLUS_SPC:
sep_dn = "; ";
sep_dn_len = 2;
sep_mv = " + ";
sep_mv_len = 3;
indent = 0;
break;
default:
return -1;
}
if (flags & XN_FLAG_SPC_EQ) {
sep_eq = " = ";
sep_eq_len = 3;
} else {
sep_eq = "=";
sep_eq_len = 1;
}
fn_opt = flags & XN_FLAG_FN_MASK;
cnt = X509_NAME_entry_count(n);
for (i = 0; i < cnt; i++) {
if (flags & XN_FLAG_DN_REV)
ent = X509_NAME_get_entry(n, cnt - i - 1);
else
ent = X509_NAME_get_entry(n, i);
if (prev != -1) {
if (prev == ent->set) {
if (!io_ch(arg, sep_mv, sep_mv_len))
return -1;
outlen += sep_mv_len;
} else {
if (!io_ch(arg, sep_dn, sep_dn_len))
return -1;
outlen += sep_dn_len;
if (!do_indent(io_ch, arg, indent))
return -1;
outlen += indent;
}
}
prev = ent->set;
fn = X509_NAME_ENTRY_get_object(ent);
val = X509_NAME_ENTRY_get_data(ent);
fn_nid = OBJ_obj2nid(fn);
if (fn_opt != XN_FLAG_FN_NONE) {
int objlen, fld_len;
if ((fn_opt == XN_FLAG_FN_OID) ||
(fn_nid == NID_undef)) {
OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1);
fld_len = 0; /* XXX: what should this be? */
objbuf = objtmp;
} else {
if (fn_opt == XN_FLAG_FN_SN) {
fld_len = FN_WIDTH_SN;
objbuf = OBJ_nid2sn(fn_nid);
} else if (fn_opt == XN_FLAG_FN_LN) {
fld_len = FN_WIDTH_LN;
objbuf = OBJ_nid2ln(fn_nid);
} else {
fld_len = 0; /* XXX: what should this be? */
objbuf = "";
}
}
objlen = strlen(objbuf);
if (!io_ch(arg, objbuf, objlen))
return -1;
if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
if (!do_indent(io_ch, arg, fld_len - objlen))
return -1;
outlen += fld_len - objlen;
}
if (!io_ch(arg, sep_eq, sep_eq_len))
return -1;
outlen += objlen + sep_eq_len;
}
/* If the field name is unknown then fix up the DER dump
* flag. We might want to limit this further so it will
* DER dump on anything other than a few 'standard' fields.
*/
if ((fn_nid == NID_undef) &&
(flags & XN_FLAG_DUMP_UNKNOWN_FIELDS))
orflags = ASN1_STRFLGS_DUMP_ALL;
else
orflags = 0;
len = do_print_ex(io_ch, arg, flags | orflags, val);
if (len < 0)
return -1;
outlen += len;
}
return outlen;
}
/* Wrappers round the main functions */
int
X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags)
{
if (flags == XN_FLAG_COMPAT)
return X509_NAME_print(out, nm, indent);
return do_name_ex(send_bio_chars, out, nm, indent, flags);
}
int
X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags)
{
if (flags == XN_FLAG_COMPAT) {
BIO *btmp;
int ret;
btmp = BIO_new_fp(fp, BIO_NOCLOSE);
if (!btmp)
return -1;
ret = X509_NAME_print(btmp, nm, indent);
BIO_free(btmp);
return ret;
}
return do_name_ex(send_fp_chars, fp, nm, indent, flags);
}
int
ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags)
{
return do_print_ex(send_bio_chars, out, flags, str);
}
int
ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags)
{
return do_print_ex(send_fp_chars, fp, flags, str);
}
/* Utility function: convert any string type to UTF8, returns number of bytes
* in output string or a negative error code
*/
int
ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in)
{
ASN1_STRING stmp, *str = &stmp;
int mbflag, type, ret;
if (!in)
return -1;
type = in->type;
if ((type < 0) || (type > 30))
return -1;
mbflag = tag2nbyte[type];
if (mbflag == -1)
return -1;
mbflag |= MBSTRING_FLAG;
stmp.data = NULL;
stmp.length = 0;
ret = ASN1_mbstring_copy(&str, in->data, in->length, mbflag,
B_ASN1_UTF8STRING);
if (ret < 0)
return ret;
*out = stmp.data;
return stmp.length;
}

306
crypto/asn1/a_strnid.c Normal file
View File

@ -0,0 +1,306 @@
/* $OpenBSD: a_strnid.c,v 1.21 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/objects.h>
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static void st_free(ASN1_STRING_TABLE *tbl);
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
const ASN1_STRING_TABLE * const *b);
/* This is the global mask for the mbstring functions: this is use to
* mask out certain types (such as BMPString and UTF8String) because
* certain software (e.g. Netscape) has problems with them.
*/
static unsigned long global_mask = B_ASN1_UTF8STRING;
void
ASN1_STRING_set_default_mask(unsigned long mask)
{
global_mask = mask;
}
unsigned long
ASN1_STRING_get_default_mask(void)
{
return global_mask;
}
/* This function sets the default to various "flavours" of configuration.
* based on an ASCII string. Currently this is:
* MASK:XXXX : a numerical mask value.
* nobmp : Don't use BMPStrings (just Printable, T61).
* pkix : PKIX recommendation in RFC2459.
* utf8only : only use UTF8Strings (RFC2459 recommendation for 2004).
* default: the default value, Printable, T61, BMP.
*/
int
ASN1_STRING_set_default_mask_asc(const char *p)
{
unsigned long mask;
char *end;
if (!strncmp(p, "MASK:", 5)) {
if (!p[5])
return 0;
mask = strtoul(p + 5, &end, 0);
if (*end)
return 0;
} else if (!strcmp(p, "nombstr"))
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
else if (!strcmp(p, "pkix"))
mask = ~((unsigned long)B_ASN1_T61STRING);
else if (!strcmp(p, "utf8only"))
mask = B_ASN1_UTF8STRING;
else if (!strcmp(p, "default"))
mask = 0xFFFFFFFFL;
else
return 0;
ASN1_STRING_set_default_mask(mask);
return 1;
}
/* The following function generates an ASN1_STRING based on limits in a table.
* Frequently the types and length of an ASN1_STRING are restricted by a
* corresponding OID. For example certificates and certificate requests.
*/
ASN1_STRING *
ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
int inform, int nid)
{
ASN1_STRING_TABLE *tbl;
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if (!out)
out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if (tbl) {
mask = tbl->mask;
if (!(tbl->flags & STABLE_NO_MASK))
mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
} else
ret = ASN1_mbstring_copy(out, in, inlen, inform,
DIRSTRING_TYPE & global_mask);
if (ret <= 0)
return NULL;
return *out;
}
/* Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
#define ub_name 32768
#define ub_common_name 64
#define ub_locality_name 128
#define ub_state_name 128
#define ub_organization_name 64
#define ub_organization_unit_name 64
#define ub_title 64
#define ub_email_address 128
#define ub_serial_number 64
/* This table must be kept in NID order */
static const ASN1_STRING_TABLE tbl_standard[] = {
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
};
static int
sk_table_cmp(const ASN1_STRING_TABLE * const *a,
const ASN1_STRING_TABLE * const *b)
{
return (*a)->nid - (*b)->nid;
}
static int table_cmp_BSEARCH_CMP_FN(const void *, const void *);
static int table_cmp(ASN1_STRING_TABLE const *, ASN1_STRING_TABLE const *);
static ASN1_STRING_TABLE *OBJ_bsearch_table(ASN1_STRING_TABLE *key, ASN1_STRING_TABLE const *base, int num);
static int
table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
{
return a->nid - b->nid;
}
static int
table_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
ASN1_STRING_TABLE const *a = a_;
ASN1_STRING_TABLE const *b = b_;
return table_cmp(a, b);
}
static ASN1_STRING_TABLE *
OBJ_bsearch_table(ASN1_STRING_TABLE *key, ASN1_STRING_TABLE const *base, int num)
{
return (ASN1_STRING_TABLE *)OBJ_bsearch_(key, base, num, sizeof(ASN1_STRING_TABLE),
table_cmp_BSEARCH_CMP_FN);
}
ASN1_STRING_TABLE *
ASN1_STRING_TABLE_get(int nid)
{
int idx;
ASN1_STRING_TABLE *ttmp;
ASN1_STRING_TABLE fnd;
fnd.nid = nid;
ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
if (ttmp)
return ttmp;
if (!stable)
return NULL;
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
if (idx < 0)
return NULL;
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
int
ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize, unsigned long mask,
unsigned long flags)
{
ASN1_STRING_TABLE *tmp;
char new_nid = 0;
flags &= ~STABLE_FLAGS_MALLOC;
if (!stable)
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if (!stable) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = malloc(sizeof(ASN1_STRING_TABLE));
if (!tmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
new_nid = 1;
} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
if (minsize != -1)
tmp->minsize = minsize;
if (maxsize != -1)
tmp->maxsize = maxsize;
tmp->mask = mask;
if (new_nid) {
if (sk_ASN1_STRING_TABLE_push(stable, tmp) == 0) {
free(tmp);
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
}
return 1;
}
void
ASN1_STRING_TABLE_cleanup(void)
{
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if (!tmp)
return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
}
static void
st_free(ASN1_STRING_TABLE *tbl)
{
if (tbl->flags & STABLE_FLAGS_MALLOC)
free(tbl);
}

107
crypto/asn1/a_time.c Normal file
View File

@ -0,0 +1,107 @@
/* $OpenBSD: a_time.c,v 1.27 2015/10/19 16:32:37 beck Exp $ */
/* ====================================================================
* 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).
*
*/
/* This is an implementation of the ASN1 Time structure which is:
* Time ::= CHOICE {
* utcTime UTCTime,
* generalTime GeneralizedTime }
* written by Steve Henson.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include "o_time.h"
#include "asn1_locl.h"
const ASN1_ITEM ASN1_TIME_it = {
.itype = ASN1_ITYPE_MSTRING,
.utype = B_ASN1_TIME,
.templates = NULL,
.tcount = 0,
.funcs = NULL,
.size = sizeof(ASN1_STRING),
.sname = "ASN1_TIME",
};
ASN1_TIME *
d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len)
{
return (ASN1_TIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_TIME_it);
}
int
i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_TIME_it);
}
ASN1_TIME *
ASN1_TIME_new(void)
{
return (ASN1_TIME *)ASN1_item_new(&ASN1_TIME_it);
}
void
ASN1_TIME_free(ASN1_TIME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_TIME_it);
}

472
crypto/asn1/a_time_tm.c Normal file
View File

@ -0,0 +1,472 @@
/* $OpenBSD: a_time_tm.c,v 1.14 2017/08/28 17:42:47 jsing Exp $ */
/*
* Copyright (c) 2015 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 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 <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include "o_time.h"
#define RFC5280 0
#define GENTIME_LENGTH 15
#define UTCTIME_LENGTH 13
int
ASN1_time_tm_cmp(struct tm *tm1, struct tm *tm2)
{
if (tm1->tm_year < tm2->tm_year)
return (-1);
if (tm1->tm_year > tm2->tm_year)
return (1);
if (tm1->tm_mon < tm2->tm_mon)
return (-1);
if (tm1->tm_mon > tm2->tm_mon)
return (1);
if (tm1->tm_mday < tm2->tm_mday)
return (-1);
if (tm1->tm_mday > tm2->tm_mday)
return (1);
if (tm1->tm_hour < tm2->tm_hour)
return (-1);
if (tm1->tm_hour > tm2->tm_hour)
return (1);
if (tm1->tm_min < tm2->tm_min)
return (-1);
if (tm1->tm_min > tm2->tm_min)
return (1);
if (tm1->tm_sec < tm2->tm_sec)
return (-1);
if (tm1->tm_sec > tm2->tm_sec)
return (1);
return 0;
}
int
ASN1_time_tm_clamp_notafter(struct tm *tm)
{
#ifdef SMALL_TIME_T
struct tm broken_os_epoch_tm;
time_t broken_os_epoch_time = INT_MAX;
if (gmtime_r(&broken_os_epoch_time, &broken_os_epoch_tm) == NULL)
return 0;
if (ASN1_time_tm_cmp(tm, &broken_os_epoch_tm) == 1)
memcpy(tm, &broken_os_epoch_tm, sizeof(*tm));
#endif
return 1;
}
/* Format a time as an RFC 5280 format Generalized time */
char *
gentime_string_from_tm(struct tm *tm)
{
char *ret = NULL;
int year;
year = tm->tm_year + 1900;
if (year < 0 || year > 9999)
return (NULL);
if (asprintf(&ret, "%04u%02u%02u%02u%02u%02uZ", year,
tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec) == -1)
ret = NULL;
return (ret);
}
/* Format a time as an RFC 5280 format UTC time */
char *
utctime_string_from_tm(struct tm *tm)
{
char *ret = NULL;
if (tm->tm_year >= 150 || tm->tm_year < 50)
return (NULL);
if (asprintf(&ret, "%02u%02u%02u%02u%02u%02uZ",
tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec) == -1)
ret = NULL;
return (ret);
}
/* Format a time correctly for an X509 object as per RFC 5280 */
char *
rfc5280_string_from_tm(struct tm *tm)
{
char *ret = NULL;
int year;
year = tm->tm_year + 1900;
if (year < 1950 || year > 9999)
return (NULL);
if (year < 2050)
ret = utctime_string_from_tm(tm);
else
ret = gentime_string_from_tm(tm);
return (ret);
}
/*
* Parse an RFC 5280 format ASN.1 time string.
*
* mode must be:
* 0 if we expect to parse a time as specified in RFC 5280 for an X509 object.
* V_ASN1_UTCTIME if we wish to parse an RFC5280 format UTC time.
* V_ASN1_GENERALIZEDTIME if we wish to parse an RFC5280 format Generalized time.
*
* Returns:
* -1 if the string was invalid.
* V_ASN1_UTCTIME if the string validated as a UTC time string.
* V_ASN1_GENERALIZEDTIME if the string validated as a Generalized time string.
*
* Fills in *tm with the corresponding time if tm is non NULL.
*/
#define ATOI2(ar) ((ar) += 2, ((ar)[-2] - '0') * 10 + ((ar)[-1] - '0'))
int
ASN1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode)
{
size_t i;
int type = 0;
struct tm ltm;
struct tm *lt;
const char *p;
if (bytes == NULL)
return (-1);
/* Constrain to valid lengths. */
if (len != UTCTIME_LENGTH && len != GENTIME_LENGTH)
return (-1);
lt = tm;
if (lt == NULL) {
memset(&ltm, 0, sizeof(ltm));
lt = &ltm;
}
/* Timezone is required and must be GMT (Zulu). */
if (bytes[len - 1] != 'Z')
return (-1);
/* Make sure everything else is digits. */
for (i = 0; i < len - 1; i++) {
if (isdigit((unsigned char)bytes[i]))
continue;
return (-1);
}
/*
* Validate and convert the time
*/
p = bytes;
switch (len) {
case GENTIME_LENGTH:
if (mode == V_ASN1_UTCTIME)
return (-1);
lt->tm_year = (ATOI2(p) * 100) - 1900; /* cc */
type = V_ASN1_GENERALIZEDTIME;
/* FALLTHROUGH */
case UTCTIME_LENGTH:
if (type == 0) {
if (mode == V_ASN1_GENERALIZEDTIME)
return (-1);
type = V_ASN1_UTCTIME;
}
lt->tm_year += ATOI2(p); /* yy */
if (type == V_ASN1_UTCTIME) {
if (lt->tm_year < 50)
lt->tm_year += 100;
}
lt->tm_mon = ATOI2(p) - 1; /* mm */
if (lt->tm_mon < 0 || lt->tm_mon > 11)
return (-1);
lt->tm_mday = ATOI2(p); /* dd */
if (lt->tm_mday < 1 || lt->tm_mday > 31)
return (-1);
lt->tm_hour = ATOI2(p); /* HH */
if (lt->tm_hour < 0 || lt->tm_hour > 23)
return (-1);
lt->tm_min = ATOI2(p); /* MM */
if (lt->tm_min < 0 || lt->tm_min > 59)
return (-1);
lt->tm_sec = ATOI2(p); /* SS */
/* Leap second 60 is not accepted. Reconsider later? */
if (lt->tm_sec < 0 || lt->tm_sec > 59)
return (-1);
break;
default:
return (-1);
}
return (type);
}
/*
* ASN1_TIME generic functions.
*/
static int
ASN1_TIME_set_string_internal(ASN1_TIME *s, const char *str, int mode)
{
int type;
char *tmp;
if ((type = ASN1_time_parse(str, strlen(str), NULL, mode)) == -1)
return (0);
if (mode != 0 && mode != type)
return (0);
if (s == NULL)
return (1);
if ((tmp = strdup(str)) == NULL)
return (0);
free(s->data);
s->data = tmp;
s->length = strlen(tmp);
s->type = type;
return (1);
}
static ASN1_TIME *
ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
int mode)
{
int allocated = 0;
struct tm tm;
size_t len;
char * p;
if (gmtime_r(&t, &tm) == NULL)
return (NULL);
if (offset_day || offset_sec) {
if (!OPENSSL_gmtime_adj(&tm, offset_day, offset_sec))
return (NULL);
}
switch (mode) {
case V_ASN1_UTCTIME:
p = utctime_string_from_tm(&tm);
break;
case V_ASN1_GENERALIZEDTIME:
p = gentime_string_from_tm(&tm);
break;
case RFC5280:
p = rfc5280_string_from_tm(&tm);
break;
default:
return (NULL);
}
if (p == NULL) {
ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
return (NULL);
}
if (s == NULL) {
if ((s = ASN1_TIME_new()) == NULL)
return (NULL);
allocated = 1;
}
len = strlen(p);
switch (len) {
case GENTIME_LENGTH:
s->type = V_ASN1_GENERALIZEDTIME;
break;
case UTCTIME_LENGTH:
s->type = V_ASN1_UTCTIME;
break;
default:
if (allocated)
ASN1_TIME_free(s);
free(p);
return (NULL);
}
free(s->data);
s->data = p;
s->length = len;
return (s);
}
ASN1_TIME *
ASN1_TIME_set(ASN1_TIME *s, time_t t)
{
return (ASN1_TIME_adj(s, t, 0, 0));
}
ASN1_TIME *
ASN1_TIME_set_tm(ASN1_TIME *s, struct tm *tm)
{
time_t t;
if ((t = timegm(tm)) == -1)
return NULL;
return (ASN1_TIME_adj(s, t, 0, 0));
}
ASN1_TIME *
ASN1_TIME_adj(ASN1_TIME *s, time_t t, int offset_day, long offset_sec)
{
return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec, RFC5280));
}
int
ASN1_TIME_check(ASN1_TIME *t)
{
if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
return (0);
return (t->type == ASN1_time_parse(t->data, t->length, NULL, t->type));
}
ASN1_GENERALIZEDTIME *
ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
{
ASN1_GENERALIZEDTIME *tmp = NULL;
struct tm tm;
char *str;
if (t->type != V_ASN1_GENERALIZEDTIME && t->type != V_ASN1_UTCTIME)
return (NULL);
memset(&tm, 0, sizeof(tm));
if (t->type != ASN1_time_parse(t->data, t->length, &tm, t->type))
return (NULL);
if ((str = gentime_string_from_tm(&tm)) == NULL)
return (NULL);
if (out != NULL)
tmp = *out;
if (tmp == NULL && (tmp = ASN1_GENERALIZEDTIME_new()) == NULL) {
free(str);
return (NULL);
}
if (out != NULL)
*out = tmp;
free(tmp->data);
tmp->data = str;
tmp->length = strlen(str);
return (tmp);
}
int
ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
{
return (ASN1_TIME_set_string_internal(s, str, 0));
}
/*
* ASN1_UTCTIME wrappers
*/
int
ASN1_UTCTIME_check(ASN1_UTCTIME *d)
{
if (d->type != V_ASN1_UTCTIME)
return (0);
return (d->type == ASN1_time_parse(d->data, d->length, NULL, d->type));
}
int
ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
{
if (s != NULL && s->type != V_ASN1_UTCTIME)
return (0);
return (ASN1_TIME_set_string_internal(s, str, V_ASN1_UTCTIME));
}
ASN1_UTCTIME *
ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
{
return (ASN1_UTCTIME_adj(s, t, 0, 0));
}
ASN1_UTCTIME *
ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec)
{
return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec,
V_ASN1_UTCTIME));
}
int
ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t2)
{
struct tm tm1, tm2;
/*
* This function has never handled failure conditions properly
* and should be deprecated. The OpenSSL version used to
* simply follow NULL pointers on failure. BoringSSL and
* OpenSSL now make it return -2 on failure.
*
* The danger is that users of this function will not
* differentiate the -2 failure case from t1 < t2.
*/
if (ASN1_time_parse(s->data, s->length, &tm1, V_ASN1_UTCTIME) == -1)
return (-2); /* XXX */
if (gmtime_r(&t2, &tm2) == NULL)
return (-2); /* XXX */
return ASN1_time_tm_cmp(&tm1, &tm2);
}
/*
* ASN1_GENERALIZEDTIME wrappers
*/
int
ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
{
if (d->type != V_ASN1_GENERALIZEDTIME)
return (0);
return (d->type == ASN1_time_parse(d->data, d->length, NULL, d->type));
}
int
ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
{
if (s != NULL && s->type != V_ASN1_GENERALIZEDTIME)
return (0);
return (ASN1_TIME_set_string_internal(s, str, V_ASN1_GENERALIZEDTIME));
}
ASN1_GENERALIZEDTIME *
ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, time_t t)
{
return (ASN1_GENERALIZEDTIME_adj(s, t, 0, 0));
}
ASN1_GENERALIZEDTIME *
ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day,
long offset_sec)
{
return (ASN1_TIME_adj_internal(s, t, offset_day, offset_sec,
V_ASN1_GENERALIZEDTIME));
}

156
crypto/asn1/a_type.c Normal file
View File

@ -0,0 +1,156 @@
/* $OpenBSD: a_type.c,v 1.19 2016/05/04 15:00:24 tedu 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 <openssl/asn1t.h>
#include <openssl/objects.h>
int
ASN1_TYPE_get(ASN1_TYPE *a)
{
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
return (a->type);
else
return (0);
}
void
ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
{
if (a->value.ptr != NULL) {
ASN1_TYPE **tmp_a = &a;
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
}
a->type = type;
if (type == V_ASN1_BOOLEAN)
a->value.boolean = value ? 0xff : 0;
else
a->value.ptr = value;
}
int
ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
{
if (!value || (type == V_ASN1_BOOLEAN)) {
void *p = (void *)value;
ASN1_TYPE_set(a, type, p);
} else if (type == V_ASN1_OBJECT) {
ASN1_OBJECT *odup;
odup = OBJ_dup(value);
if (!odup)
return 0;
ASN1_TYPE_set(a, type, odup);
} else {
ASN1_STRING *sdup;
sdup = ASN1_STRING_dup(value);
if (!sdup)
return 0;
ASN1_TYPE_set(a, type, sdup);
}
return 1;
}
/* Returns 0 if they are equal, != 0 otherwise. */
int
ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
{
int result = -1;
if (!a || !b || a->type != b->type)
return -1;
switch (a->type) {
case V_ASN1_OBJECT:
result = OBJ_cmp(a->value.object, b->value.object);
break;
case V_ASN1_BOOLEAN:
result = a->value.boolean - b->value.boolean;
break;
case V_ASN1_NULL:
result = 0; /* They do not have content. */
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_OTHER:
default:
result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
(ASN1_STRING *)b->value.ptr);
break;
}
return result;
}

199
crypto/asn1/a_utf8.c Normal file
View File

@ -0,0 +1,199 @@
/* $OpenBSD: a_utf8.c,v 1.8 2014/07/11 08:44:47 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.]
*/
#include <stdio.h>
#include <openssl/asn1.h>
#include "asn1_locl.h"
/* UTF8 utilities */
/*
* This parses a UTF8 string one character at a time. It is passed a pointer
* to the string and the length of the string. It sets 'value' to the value of
* the current character. It returns the number of characters read or a
* negative error code:
* -1 = string too short
* -2 = illegal character
* -3 = subsequent characters not of the form 10xxxxxx
* -4 = character encoded incorrectly (not minimal length).
*/
int
UTF8_getc(const unsigned char *str, int len, unsigned long *val)
{
const unsigned char *p;
unsigned long value;
int ret;
if (len <= 0)
return 0;
p = str;
/* Check syntax and work out the encoded value (if correct) */
if ((*p & 0x80) == 0) {
value = *p++ & 0x7f;
ret = 1;
} else if ((*p & 0xe0) == 0xc0) {
if (*p < 0xc2)
return -2;
if (len < 2)
return -1;
if ((p[1] & 0xc0) != 0x80)
return -3;
value = (*p++ & 0x1f) << 6;
value |= *p++ & 0x3f;
if (value < 0x80)
return -4;
ret = 2;
} else if ((*p & 0xf0) == 0xe0) {
if (len < 3)
return -1;
if (((p[1] & 0xc0) != 0x80) ||
((p[2] & 0xc0) != 0x80))
return -3;
value = (*p++ & 0xf) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x800)
return -4;
/* surrogate pair code points are not valid */
if (value >= 0xd800 && value < 0xe000)
return -2;
ret = 3;
} else if ((*p & 0xf8) == 0xf0 && (*p < 0xf5)) {
if (len < 4)
return -1;
if (((p[1] & 0xc0) != 0x80) ||
((p[2] & 0xc0) != 0x80) ||
((p[3] & 0xc0) != 0x80))
return -3;
value = ((unsigned long)(*p++ & 0x7)) << 18;
value |= (*p++ & 0x3f) << 12;
value |= (*p++ & 0x3f) << 6;
value |= *p++ & 0x3f;
if (value < 0x10000)
return -4;
if (value > UNICODE_MAX)
return -2;
ret = 4;
} else
return -2;
*val = value;
return ret;
}
/* This takes a Unicode code point 'value' and writes its UTF-8 encoded form
* in 'str' where 'str' is a buffer of at least length 'len'. If 'str'
* is NULL, then nothing is written and just the return code is determined.
* Returns less than zero on error:
* -1 if 'str' is not NULL and 'len' is too small
* -2 if 'value' is an invalid character (surrogate or out-of-range)
*
* Otherwise, returns the number of bytes in 'value's encoded form
* (i.e., the number of bytes written to 'str' when it's not NULL).
*
* It will need at most 4 characters.
*/
int
UTF8_putc(unsigned char *str, int len, unsigned long value)
{
if (value < 0x80) {
if (str != NULL) {
if (len < 1)
return -1;
str[0] = (unsigned char)value;
}
return 1;
}
if (value < 0x800) {
if (str != NULL) {
if (len < 2)
return -1;
str[0] = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
str[1] = (unsigned char)((value & 0x3f) | 0x80);
}
return 2;
}
if (value < 0x10000) {
if (UNICODE_IS_SURROGATE(value))
return -2;
if (str != NULL) {
if (len < 3)
return -1;
str[0] = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
str[1] = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
str[2] = (unsigned char)((value & 0x3f) | 0x80);
}
return 3;
}
if (value <= UNICODE_MAX) {
if (str != NULL) {
if (len < 4)
return -1;
str[0] = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
str[1] = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
str[2] = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
str[3] = (unsigned char)((value & 0x3f) | 0x80);
}
return 4;
}
return -2;
}

167
crypto/asn1/a_verify.c Normal file
View File

@ -0,0 +1,167 @@
/* $OpenBSD: a_verify.c,v 1.24 2017/05/02 03:59:44 deraadt 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/types.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
int
ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
{
EVP_MD_CTX ctx;
unsigned char *buf_in = NULL;
int ret = -1, inl;
int mdnid, pknid;
if (!pkey) {
ASN1error(ERR_R_PASSED_NULL_PARAMETER);
return -1;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
ASN1error(ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
return -1;
}
EVP_MD_CTX_init(&ctx);
/* Convert signature OID into digest and public key OIDs */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
if (mdnid == NID_undef) {
if (!pkey->ameth || !pkey->ameth->item_verify) {
ASN1error(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
goto err;
}
ret = pkey->ameth->item_verify(&ctx, it, asn, a,
signature, pkey);
/* Return value of 2 means carry on, anything else means we
* exit straight away: either a fatal error of the underlying
* verification routine handles all verification.
*/
if (ret != 2)
goto err;
ret = -1;
} else {
const EVP_MD *type;
type = EVP_get_digestbynid(mdnid);
if (type == NULL) {
ASN1error(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
goto err;
}
/* Check public key OID matches public key type */
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
ASN1error(ASN1_R_WRONG_PUBLIC_KEY_TYPE);
goto err;
}
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
}
inl = ASN1_item_i2d(asn, &buf_in, it);
if (buf_in == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
freezero(buf_in, (unsigned int)inl);
if (EVP_DigestVerifyFinal(&ctx, signature->data,
(size_t)signature->length) <= 0) {
ASN1error(ERR_R_EVP_LIB);
ret = 0;
goto err;
}
/* we don't need to zero the 'ctx' because we just checked
* public information */
/* memset(&ctx,0,sizeof(ctx)); */
ret = 1;
err:
EVP_MD_CTX_cleanup(&ctx);
return (ret);
}

471
crypto/asn1/ameth_lib.c Normal file
View File

@ -0,0 +1,471 @@
/* $OpenBSD: ameth_lib.c,v 1.16 2017/01/21 04:31:25 jsing 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 <openssl/opensslconf.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_locl.h"
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
/* Keep this sorted in type order !! */
static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
#ifndef OPENSSL_NO_RSA
&rsa_asn1_meths[0],
&rsa_asn1_meths[1],
#endif
#ifndef OPENSSL_NO_DH
&dh_asn1_meth,
#endif
#ifndef OPENSSL_NO_DSA
&dsa_asn1_meths[0],
&dsa_asn1_meths[1],
&dsa_asn1_meths[2],
&dsa_asn1_meths[3],
&dsa_asn1_meths[4],
#endif
#ifndef OPENSSL_NO_EC
&eckey_asn1_meth,
#endif
#ifndef OPENSSL_NO_GOST
&gostr01_asn1_meths[0],
&gostimit_asn1_meth,
#endif
&hmac_asn1_meth,
&cmac_asn1_meth,
#ifndef OPENSSL_NO_GOST
&gostr01_asn1_meths[1],
&gostr01_asn1_meths[2],
#endif
};
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
static int ameth_cmp_BSEARCH_CMP_FN(const void *, const void *);
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *, const EVP_PKEY_ASN1_METHOD * const *);
static const EVP_PKEY_ASN1_METHOD * *OBJ_bsearch_ameth(const EVP_PKEY_ASN1_METHOD * *key, const EVP_PKEY_ASN1_METHOD * const *base, int num);
static int
ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
const EVP_PKEY_ASN1_METHOD * const *b)
{
return ((*a)->pkey_id - (*b)->pkey_id);
}
static int
ameth_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_)
{
const EVP_PKEY_ASN1_METHOD * const *a = a_;
const EVP_PKEY_ASN1_METHOD * const *b = b_;
return ameth_cmp(a, b);
}
static const EVP_PKEY_ASN1_METHOD * *
OBJ_bsearch_ameth(const EVP_PKEY_ASN1_METHOD * *key, const EVP_PKEY_ASN1_METHOD * const *base, int num)
{
return (const EVP_PKEY_ASN1_METHOD * *)OBJ_bsearch_(key, base, num, sizeof(const EVP_PKEY_ASN1_METHOD *),
ameth_cmp_BSEARCH_CMP_FN);
}
int
EVP_PKEY_asn1_get_count(void)
{
int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
if (app_methods)
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
return num;
}
const EVP_PKEY_ASN1_METHOD *
EVP_PKEY_asn1_get0(int idx)
{
int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
if (idx < 0)
return NULL;
if (idx < num)
return standard_methods[idx];
idx -= num;
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
}
static const EVP_PKEY_ASN1_METHOD *
pkey_asn1_find(int type)
{
EVP_PKEY_ASN1_METHOD tmp;
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
tmp.pkey_id = type;
if (app_methods) {
int idx;
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
if (idx >= 0)
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
}
ret = OBJ_bsearch_ameth(&t, standard_methods,
sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *));
if (!ret || !*ret)
return NULL;
return *ret;
}
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
* also search through engines and set *pe to a functional reference
* to the engine implementing 'type' or NULL if no engine implements
* it.
*/
const EVP_PKEY_ASN1_METHOD *
EVP_PKEY_asn1_find(ENGINE **pe, int type)
{
const EVP_PKEY_ASN1_METHOD *t;
for (;;) {
t = pkey_asn1_find(type);
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
break;
type = t->pkey_base_id;
}
if (pe) {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
/* type will contain the final unaliased type */
e = ENGINE_get_pkey_asn1_meth_engine(type);
if (e) {
*pe = e;
return ENGINE_get_pkey_asn1_meth(e, type);
}
#endif
*pe = NULL;
}
return t;
}
const EVP_PKEY_ASN1_METHOD *
EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len)
{
int i;
const EVP_PKEY_ASN1_METHOD *ameth;
if (len == -1)
len = strlen(str);
if (pe) {
#ifndef OPENSSL_NO_ENGINE
ENGINE *e;
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
if (ameth) {
/* Convert structural into
* functional reference
*/
if (!ENGINE_init(e))
ameth = NULL;
ENGINE_free(e);
*pe = e;
return ameth;
}
#endif
*pe = NULL;
}
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
ameth = EVP_PKEY_asn1_get0(i);
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
continue;
if (((int)strlen(ameth->pem_str) == len) &&
!strncasecmp(ameth->pem_str, str, len))
return ameth;
}
return NULL;
}
int
EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
{
if (app_methods == NULL) {
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
if (!app_methods)
return 0;
}
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
return 0;
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
return 1;
}
int
EVP_PKEY_asn1_add_alias(int to, int from)
{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
if (!ameth)
return 0;
ameth->pkey_base_id = to;
if (!EVP_PKEY_asn1_add0(ameth)) {
EVP_PKEY_asn1_free(ameth);
return 0;
}
return 1;
}
int
EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
const char **pinfo, const char **ppem_str,
const EVP_PKEY_ASN1_METHOD *ameth)
{
if (!ameth)
return 0;
if (ppkey_id)
*ppkey_id = ameth->pkey_id;
if (ppkey_base_id)
*ppkey_base_id = ameth->pkey_base_id;
if (ppkey_flags)
*ppkey_flags = ameth->pkey_flags;
if (pinfo)
*pinfo = ameth->info;
if (ppem_str)
*ppem_str = ameth->pem_str;
return 1;
}
const EVP_PKEY_ASN1_METHOD*
EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
{
return pkey->ameth;
}
EVP_PKEY_ASN1_METHOD*
EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info)
{
EVP_PKEY_ASN1_METHOD *ameth;
ameth = calloc(1, sizeof(EVP_PKEY_ASN1_METHOD));
if (!ameth)
return NULL;
ameth->pkey_id = id;
ameth->pkey_base_id = id;
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
if (info) {
ameth->info = strdup(info);
if (!ameth->info)
goto err;
} else
ameth->info = NULL;
if (pem_str) {
ameth->pem_str = strdup(pem_str);
if (!ameth->pem_str)
goto err;
} else
ameth->pem_str = NULL;
ameth->pub_decode = 0;
ameth->pub_encode = 0;
ameth->pub_cmp = 0;
ameth->pub_print = 0;
ameth->priv_decode = 0;
ameth->priv_encode = 0;
ameth->priv_print = 0;
ameth->old_priv_encode = 0;
ameth->old_priv_decode = 0;
ameth->item_verify = 0;
ameth->item_sign = 0;
ameth->pkey_size = 0;
ameth->pkey_bits = 0;
ameth->param_decode = 0;
ameth->param_encode = 0;
ameth->param_missing = 0;
ameth->param_copy = 0;
ameth->param_cmp = 0;
ameth->param_print = 0;
ameth->pkey_free = 0;
ameth->pkey_ctrl = 0;
return ameth;
err:
EVP_PKEY_asn1_free(ameth);
return NULL;
}
void
EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, const EVP_PKEY_ASN1_METHOD *src)
{
dst->pub_decode = src->pub_decode;
dst->pub_encode = src->pub_encode;
dst->pub_cmp = src->pub_cmp;
dst->pub_print = src->pub_print;
dst->priv_decode = src->priv_decode;
dst->priv_encode = src->priv_encode;
dst->priv_print = src->priv_print;
dst->old_priv_encode = src->old_priv_encode;
dst->old_priv_decode = src->old_priv_decode;
dst->pkey_size = src->pkey_size;
dst->pkey_bits = src->pkey_bits;
dst->param_decode = src->param_decode;
dst->param_encode = src->param_encode;
dst->param_missing = src->param_missing;
dst->param_copy = src->param_copy;
dst->param_cmp = src->param_cmp;
dst->param_print = src->param_print;
dst->pkey_free = src->pkey_free;
dst->pkey_ctrl = src->pkey_ctrl;
dst->item_sign = src->item_sign;
dst->item_verify = src->item_verify;
}
void
EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
{
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
free(ameth->pem_str);
free(ameth->info);
free(ameth);
}
}
void
EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx),
int (*pkey_size)(const EVP_PKEY *pk),
int (*pkey_bits)(const EVP_PKEY *pk))
{
ameth->pub_decode = pub_decode;
ameth->pub_encode = pub_encode;
ameth->pub_cmp = pub_cmp;
ameth->pub_print = pub_print;
ameth->pkey_size = pkey_size;
ameth->pkey_bits = pkey_bits;
}
void
EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
{
ameth->priv_decode = priv_decode;
ameth->priv_encode = priv_encode;
ameth->priv_print = priv_print;
}
void
EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen),
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
int (*param_missing)(const EVP_PKEY *pk),
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx))
{
ameth->param_decode = param_decode;
ameth->param_encode = param_encode;
ameth->param_missing = param_missing;
ameth->param_copy = param_copy;
ameth->param_cmp = param_cmp;
ameth->param_print = param_print;
}
void
EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
void (*pkey_free)(EVP_PKEY *pkey))
{
ameth->pkey_free = pkey_free;
}
void
EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2))
{
ameth->pkey_ctrl = pkey_ctrl;
}

213
crypto/asn1/asn1_err.c Normal file
View File

@ -0,0 +1,213 @@
/* $OpenBSD: asn1_err.c,v 1.20 2017/01/29 17:49:22 beck Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
* made to it will be overwritten when the script next updates this file,
* only reason strings will be preserved.
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/err.h>
#include <openssl/asn1.h>
/* BEGIN ERROR CODES */
#ifndef OPENSSL_NO_ERR
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
static ERR_STRING_DATA ASN1_str_functs[] = {
{ERR_FUNC(0xfff), "CRYPTO_internal"},
{0, NULL}
};
static ERR_STRING_DATA ASN1_str_reasons[] = {
{ERR_REASON(ASN1_R_ADDING_OBJECT) , "adding object"},
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) , "asn1 parse error"},
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) , "asn1 sig parse error"},
{ERR_REASON(ASN1_R_AUX_ERROR) , "aux error"},
{ERR_REASON(ASN1_R_BAD_CLASS) , "bad class"},
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) , "bad object header"},
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ) , "bad password read"},
{ERR_REASON(ASN1_R_BAD_TAG) , "bad tag"},
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), "bmpstring is wrong length"},
{ERR_REASON(ASN1_R_BN_LIB) , "bn lib"},
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) , "buffer too small"},
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), "cipher has no object identifier"},
{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
{ERR_REASON(ASN1_R_DATA_IS_WRONG) , "data is wrong"},
{ERR_REASON(ASN1_R_DECODE_ERROR) , "decode error"},
{ERR_REASON(ASN1_R_DECODING_ERROR) , "decoding error"},
{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) , "depth exceeded"},
{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), "digest and key type not supported"},
{ERR_REASON(ASN1_R_ENCODE_ERROR) , "encode error"},
{ERR_REASON(ASN1_R_ERROR_GETTING_TIME) , "error getting time"},
{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT), "error parsing set element"},
{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS), "error setting cipher params"},
{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) , "expecting an integer"},
{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT) , "expecting an object"},
{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN) , "expecting a boolean"},
{ERR_REASON(ASN1_R_EXPECTING_A_TIME) , "expecting a time"},
{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), "explicit tag not constructed"},
{ERR_REASON(ASN1_R_FIELD_MISSING) , "field missing"},
{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE) , "first num too large"},
{ERR_REASON(ASN1_R_HEADER_TOO_LONG) , "header too long"},
{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN) , "illegal boolean"},
{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS) , "illegal characters"},
{ERR_REASON(ASN1_R_ILLEGAL_FORMAT) , "illegal format"},
{ERR_REASON(ASN1_R_ILLEGAL_HEX) , "illegal hex"},
{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) , "illegal implicit tag"},
{ERR_REASON(ASN1_R_ILLEGAL_INTEGER) , "illegal integer"},
{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
{ERR_REASON(ASN1_R_ILLEGAL_NULL) , "illegal null"},
{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE) , "illegal null value"},
{ERR_REASON(ASN1_R_ILLEGAL_OBJECT) , "illegal object"},
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) , "illegal optional any"},
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), "illegal options on item template"},
{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY) , "illegal tagged any"},
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) , "illegal time value"},
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), "integer too large for long"},
{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT), "invalid bit string bits left"},
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
{ERR_REASON(ASN1_R_INVALID_DIGIT) , "invalid digit"},
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) , "invalid mime type"},
{ERR_REASON(ASN1_R_INVALID_MODIFIER) , "invalid modifier"},
{ERR_REASON(ASN1_R_INVALID_NUMBER) , "invalid number"},
{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) , "invalid separator"},
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) , "invalid time format"},
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), "invalid universalstring length"},
{ERR_REASON(ASN1_R_INVALID_UTF8STRING) , "invalid utf8string"},
{ERR_REASON(ASN1_R_IV_TOO_LARGE) , "iv too large"},
{ERR_REASON(ASN1_R_LENGTH_ERROR) , "length error"},
{ERR_REASON(ASN1_R_LIST_ERROR) , "list error"},
{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) , "mime no content type"},
{ERR_REASON(ASN1_R_MIME_PARSE_ERROR) , "mime parse error"},
{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) , "mime sig parse error"},
{ERR_REASON(ASN1_R_MISSING_EOC) , "missing eoc"},
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
{ERR_REASON(ASN1_R_MISSING_VALUE) , "missing value"},
{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG) , "mstring wrong tag"},
{ERR_REASON(ASN1_R_NESTED_ASN1_STRING) , "nested asn1 string"},
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) , "non hex characters"},
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) , "not ascii format"},
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) , "not enough data"},
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) , "no content type"},
{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST) , "no default digest"},
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE), "no multipart body failure"},
{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE) , "no sig content type"},
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) , "null is wrong length"},
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) , "odd number of chars"},
{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING), "private key header missing"},
{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), "sequence or set needs config"},
{ERR_REASON(ASN1_R_SHORT_LINE) , "short line"},
{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
{ERR_REASON(ASN1_R_STRING_TOO_LONG) , "string too long"},
{ERR_REASON(ASN1_R_STRING_TOO_SHORT) , "string too short"},
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) , "tag value too high"},
{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), "the asn1 object identifier is not known for this md"},
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
{ERR_REASON(ASN1_R_TOO_LONG) , "too long"},
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) , "type not constructed"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"},
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), "unable to decode rsa private key"},
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) , "unexpected eoc"},
{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), "universalstring is wrong length"},
{ERR_REASON(ASN1_R_UNKNOWN_FORMAT) , "unknown format"},
{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), "unknown message digest algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) , "unknown object type"},
{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), "unknown signature algorithm"},
{ERR_REASON(ASN1_R_UNKNOWN_TAG) , "unknown tag"},
{ERR_REASON(ASN1_R_UNKOWN_FORMAT) , "unknown format"},
{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), "unsupported any defined by type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER) , "unsupported cipher"},
{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), "unsupported encryption algorithm"},
{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), "unsupported public key type"},
{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) , "unsupported type"},
{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
{ERR_REASON(ASN1_R_WRONG_TAG) , "wrong tag"},
{ERR_REASON(ASN1_R_WRONG_TYPE) , "wrong type"},
{0, NULL}
};
#endif
void
ERR_load_ASN1_strings(void)
{
#ifndef OPENSSL_NO_ERR
if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
ERR_load_strings(0, ASN1_str_functs);
ERR_load_strings(0, ASN1_str_reasons);
}
#endif
}

801
crypto/asn1/asn1_gen.c Normal file
View File

@ -0,0 +1,801 @@
/* $OpenBSD: asn1_gen.c,v 1.16 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2002.
*/
/* ====================================================================
* Copyright (c) 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
* 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 <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
#define ASN1_GEN_FLAG 0x10000
#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1)
#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2)
#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3)
#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4)
#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5)
#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6)
#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7)
#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8)
#define ASN1_GEN_STR(str,val){str, sizeof(str) - 1, val}
#define ASN1_FLAG_EXP_MAX 20
/* Input formats */
/* ASCII: default */
#define ASN1_GEN_FORMAT_ASCII 1
/* UTF8 */
#define ASN1_GEN_FORMAT_UTF8 2
/* Hex */
#define ASN1_GEN_FORMAT_HEX 3
/* List of bits */
#define ASN1_GEN_FORMAT_BITLIST 4
struct tag_name_st {
const char *strnam;
int len;
int tag;
};
typedef struct {
int exp_tag;
int exp_class;
int exp_constructed;
int exp_pad;
long exp_len;
} tag_exp_type;
typedef struct {
int imp_tag;
int imp_class;
int utype;
int format;
const char *str;
tag_exp_type exp_list[ASN1_FLAG_EXP_MAX];
int exp_count;
} tag_exp_arg;
static int bitstr_cb(const char *elem, int len, void *bitstr);
static int asn1_cb(const char *elem, int len, void *bitstr);
static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class,
int exp_constructed, int exp_pad, int imp_ok);
static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass);
static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf);
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype);
static int asn1_str2tag(const char *tagstr, int len);
ASN1_TYPE *
ASN1_generate_nconf(char *str, CONF *nconf)
{
X509V3_CTX cnf;
if (!nconf)
return ASN1_generate_v3(str, NULL);
X509V3_set_nconf(&cnf, nconf);
return ASN1_generate_v3(str, &cnf);
}
ASN1_TYPE *
ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
ASN1_TYPE *ret;
tag_exp_arg asn1_tags;
tag_exp_type *etmp;
int i, len;
unsigned char *orig_der = NULL, *new_der = NULL;
const unsigned char *cpy_start;
unsigned char *p;
const unsigned char *cp;
int cpy_len;
long hdr_len = 0;
int hdr_constructed = 0, hdr_tag, hdr_class;
int r;
asn1_tags.imp_tag = -1;
asn1_tags.imp_class = -1;
asn1_tags.format = ASN1_GEN_FORMAT_ASCII;
asn1_tags.exp_count = 0;
if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0)
return NULL;
if ((asn1_tags.utype == V_ASN1_SEQUENCE) ||
(asn1_tags.utype == V_ASN1_SET)) {
if (!cnf) {
ASN1error(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
}
ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
} else
ret = asn1_str2type(asn1_tags.str, asn1_tags.format,
asn1_tags.utype);
if (!ret)
return NULL;
/* If no tagging return base type */
if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0))
return ret;
/* Generate the encoding */
cpy_len = i2d_ASN1_TYPE(ret, &orig_der);
ASN1_TYPE_free(ret);
ret = NULL;
/* Set point to start copying for modified encoding */
cpy_start = orig_der;
/* Do we need IMPLICIT tagging? */
if (asn1_tags.imp_tag != -1) {
/* If IMPLICIT we will replace the underlying tag */
/* Skip existing tag+len */
r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag,
&hdr_class, cpy_len);
if (r & 0x80)
goto err;
/* Update copy length */
cpy_len -= cpy_start - orig_der;
/* For IMPLICIT tagging the length should match the
* original length and constructed flag should be
* consistent.
*/
if (r & 0x1) {
/* Indefinite length constructed */
hdr_constructed = 2;
hdr_len = 0;
} else
/* Just retain constructed flag */
hdr_constructed = r & V_ASN1_CONSTRUCTED;
/* Work out new length with IMPLICIT tag: ignore constructed
* because it will mess up if indefinite length
*/
len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag);
} else
len = cpy_len;
/* Work out length in any EXPLICIT, starting from end */
for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1;
i < asn1_tags.exp_count; i++, etmp--) {
/* Content length: number of content octets + any padding */
len += etmp->exp_pad;
etmp->exp_len = len;
/* Total object length: length including new header */
len = ASN1_object_size(0, len, etmp->exp_tag);
}
/* Allocate buffer for new encoding */
new_der = malloc(len);
if (!new_der)
goto err;
/* Generate tagged encoding */
p = new_der;
/* Output explicit tags first */
for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count;
i++, etmp++) {
ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len,
etmp->exp_tag, etmp->exp_class);
if (etmp->exp_pad)
*p++ = 0;
}
/* If IMPLICIT, output tag */
if (asn1_tags.imp_tag != -1) {
if (asn1_tags.imp_class == V_ASN1_UNIVERSAL &&
(asn1_tags.imp_tag == V_ASN1_SEQUENCE ||
asn1_tags.imp_tag == V_ASN1_SET))
hdr_constructed = V_ASN1_CONSTRUCTED;
ASN1_put_object(&p, hdr_constructed, hdr_len,
asn1_tags.imp_tag, asn1_tags.imp_class);
}
/* Copy across original encoding */
memcpy(p, cpy_start, cpy_len);
cp = new_der;
/* Obtain new ASN1_TYPE structure */
ret = d2i_ASN1_TYPE(NULL, &cp, len);
err:
free(orig_der);
free(new_der);
return ret;
}
static int
asn1_cb(const char *elem, int len, void *bitstr)
{
tag_exp_arg *arg = bitstr;
int i;
int utype;
int vlen = 0;
const char *p, *vstart = NULL;
int tmp_tag, tmp_class;
for (i = 0, p = elem; i < len; p++, i++) {
/* Look for the ':' in name value pairs */
if (*p == ':') {
vstart = p + 1;
vlen = len - (vstart - elem);
len = p - elem;
break;
}
}
utype = asn1_str2tag(elem, len);
if (utype == -1) {
ASN1error(ASN1_R_UNKNOWN_TAG);
ERR_asprintf_error_data("tag=%s", elem);
return -1;
}
/* If this is not a modifier mark end of string and exit */
if (!(utype & ASN1_GEN_FLAG)) {
arg->utype = utype;
arg->str = vstart;
/* If no value and not end of string, error */
if (!vstart && elem[len]) {
ASN1error(ASN1_R_MISSING_VALUE);
return -1;
}
return 0;
}
switch (utype) {
case ASN1_GEN_FLAG_IMP:
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1) {
ASN1error(ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
}
if (!parse_tagging(vstart, vlen, &arg->imp_tag,
&arg->imp_class))
return -1;
break;
case ASN1_GEN_FLAG_EXP:
if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class))
return -1;
if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0))
return -1;
break;
case ASN1_GEN_FLAG_SEQWRAP:
if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_SETWRAP:
if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_BITWRAP:
if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1))
return -1;
break;
case ASN1_GEN_FLAG_OCTWRAP:
if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1))
return -1;
break;
case ASN1_GEN_FLAG_FORMAT:
if (vstart == NULL) {
ASN1error(ASN1_R_ILLEGAL_FORMAT);
return -1;
}
if (!strncmp(vstart, "ASCII", 5))
arg->format = ASN1_GEN_FORMAT_ASCII;
else if (!strncmp(vstart, "UTF8", 4))
arg->format = ASN1_GEN_FORMAT_UTF8;
else if (!strncmp(vstart, "HEX", 3))
arg->format = ASN1_GEN_FORMAT_HEX;
else if (!strncmp(vstart, "BITLIST", 7))
arg->format = ASN1_GEN_FORMAT_BITLIST;
else {
ASN1error(ASN1_R_UNKOWN_FORMAT);
return -1;
}
break;
}
return 1;
}
static int
parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
{
long tag_num;
char *eptr;
if (!vstart)
return 0;
tag_num = strtoul(vstart, &eptr, 10);
/* Check we haven't gone past max length: should be impossible */
if (eptr && *eptr && (eptr > vstart + vlen))
return 0;
if (tag_num < 0) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
*ptag = tag_num;
/* If we have non numeric characters, parse them */
if (eptr)
vlen -= eptr - vstart;
else
vlen = 0;
if (vlen) {
switch (*eptr) {
case 'U':
*pclass = V_ASN1_UNIVERSAL;
break;
case 'A':
*pclass = V_ASN1_APPLICATION;
break;
case 'P':
*pclass = V_ASN1_PRIVATE;
break;
case 'C':
*pclass = V_ASN1_CONTEXT_SPECIFIC;
break;
default:
ASN1error(ASN1_R_INVALID_MODIFIER);
ERR_asprintf_error_data("Char=%c", *eptr);
return 0;
break;
}
} else
*pclass = V_ASN1_CONTEXT_SPECIFIC;
return 1;
}
/* Handle multiple types: SET and SEQUENCE */
static ASN1_TYPE *
asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
{
ASN1_TYPE *ret = NULL;
STACK_OF(ASN1_TYPE) *sk = NULL;
STACK_OF(CONF_VALUE) *sect = NULL;
unsigned char *der = NULL;
int derlen;
int i;
sk = sk_ASN1_TYPE_new_null();
if (!sk)
goto bad;
if (section) {
if (!cnf)
goto bad;
sect = X509V3_get_section(cnf, (char *)section);
if (!sect)
goto bad;
for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
ASN1_TYPE *typ = ASN1_generate_v3(
sk_CONF_VALUE_value(sect, i)->value, cnf);
if (!typ)
goto bad;
if (!sk_ASN1_TYPE_push(sk, typ))
goto bad;
}
}
/* Now we has a STACK of the components, convert to the correct form */
if (utype == V_ASN1_SET)
derlen = i2d_ASN1_SET_ANY(sk, &der);
else
derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der);
if (derlen < 0)
goto bad;
if (!(ret = ASN1_TYPE_new()))
goto bad;
if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype)))
goto bad;
ret->type = utype;
ret->value.asn1_string->data = der;
ret->value.asn1_string->length = derlen;
der = NULL;
bad:
free(der);
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
if (sect)
X509V3_section_free(cnf, sect);
return ret;
}
static int
append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_constructed,
int exp_pad, int imp_ok)
{
tag_exp_type *exp_tmp;
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok) {
ASN1error(ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
}
if (arg->exp_count == ASN1_FLAG_EXP_MAX) {
ASN1error(ASN1_R_DEPTH_EXCEEDED);
return 0;
}
exp_tmp = &arg->exp_list[arg->exp_count++];
/* If IMPLICIT set tag to implicit value then
* reset implicit tag since it has been used.
*/
if (arg->imp_tag != -1) {
exp_tmp->exp_tag = arg->imp_tag;
exp_tmp->exp_class = arg->imp_class;
arg->imp_tag = -1;
arg->imp_class = -1;
} else {
exp_tmp->exp_tag = exp_tag;
exp_tmp->exp_class = exp_class;
}
exp_tmp->exp_constructed = exp_constructed;
exp_tmp->exp_pad = exp_pad;
return 1;
}
static int
asn1_str2tag(const char *tagstr, int len)
{
unsigned int i;
static const struct tag_name_st *tntmp, tnst [] = {
ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN),
ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN),
ASN1_GEN_STR("NULL", V_ASN1_NULL),
ASN1_GEN_STR("INT", V_ASN1_INTEGER),
ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER),
ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED),
ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED),
ASN1_GEN_STR("OID", V_ASN1_OBJECT),
ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT),
ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME),
ASN1_GEN_STR("UTC", V_ASN1_UTCTIME),
ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME),
ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING),
ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING),
ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING),
ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING),
ASN1_GEN_STR("IA5", V_ASN1_IA5STRING),
ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING),
ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING),
ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING),
ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING),
ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING),
ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING),
ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING),
ASN1_GEN_STR("T61", V_ASN1_T61STRING),
ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING),
ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING),
ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING),
ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING),
ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING),
ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING),
/* Special cases */
ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE),
ASN1_GEN_STR("SET", V_ASN1_SET),
/* type modifiers */
/* Explicit tag */
ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP),
ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP),
/* Implicit tag */
ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP),
ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP),
/* OCTET STRING wrapper */
ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP),
/* SEQUENCE wrapper */
ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP),
/* SET wrapper */
ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP),
/* BIT STRING wrapper */
ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP),
ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT),
ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT),
};
if (len == -1)
len = strlen(tagstr);
tntmp = tnst;
for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st);
i++, tntmp++) {
if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len))
return tntmp->tag;
}
return -1;
}
static ASN1_TYPE *
asn1_str2type(const char *str, int format, int utype)
{
ASN1_TYPE *atmp = NULL;
CONF_VALUE vtmp;
unsigned char *rdata;
long rdlen;
int no_unused = 1;
if (!(atmp = ASN1_TYPE_new())) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!str)
str = "";
switch (utype) {
case V_ASN1_NULL:
if (str && *str) {
ASN1error(ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
}
break;
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII) {
ASN1error(ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
}
vtmp.name = NULL;
vtmp.section = NULL;
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
ASN1error(ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
}
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII) {
ASN1error(ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.integer =
s2i_ASN1_INTEGER(NULL, (char *)str))) {
ASN1error(ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
}
break;
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII) {
ASN1error(ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.object = OBJ_txt2obj(str, 0))) {
ASN1error(ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
}
break;
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII) {
ASN1error(ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto bad_str;
}
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto bad_str;
}
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string)) {
ASN1error(ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
}
break;
case V_ASN1_BMPSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_IA5STRING:
case V_ASN1_T61STRING:
case V_ASN1_UTF8STRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_NUMERICSTRING:
if (format == ASN1_GEN_FORMAT_ASCII)
format = MBSTRING_ASC;
else if (format == ASN1_GEN_FORMAT_UTF8)
format = MBSTRING_UTF8;
else {
ASN1error(ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
}
if (ASN1_mbstring_copy(&atmp->value.asn1_string,
(unsigned char *)str, -1, format,
ASN1_tag2bit(utype)) <= 0) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto bad_str;
}
break;
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
if (!(atmp->value.asn1_string = ASN1_STRING_new())) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto bad_form;
}
if (format == ASN1_GEN_FORMAT_HEX) {
if (!(rdata = string_to_hex((char *)str, &rdlen))) {
ASN1error(ASN1_R_ILLEGAL_HEX);
goto bad_str;
}
atmp->value.asn1_string->data = rdata;
atmp->value.asn1_string->length = rdlen;
atmp->value.asn1_string->type = utype;
} else if (format == ASN1_GEN_FORMAT_ASCII) {
if (ASN1_STRING_set(atmp->value.asn1_string, str,
-1) == 0) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto bad_str;
}
} else if ((format == ASN1_GEN_FORMAT_BITLIST) &&
(utype == V_ASN1_BIT_STRING)) {
if (!CONF_parse_list(str, ',', 1, bitstr_cb,
atmp->value.bit_string)) {
ASN1error(ASN1_R_LIST_ERROR);
goto bad_str;
}
no_unused = 0;
} else {
ASN1error(ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
}
if ((utype == V_ASN1_BIT_STRING) && no_unused) {
atmp->value.asn1_string->flags &=
~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
atmp->value.asn1_string->flags |=
ASN1_STRING_FLAG_BITS_LEFT;
}
break;
default:
ASN1error(ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
}
atmp->type = utype;
return atmp;
bad_str:
ERR_asprintf_error_data("string=%s", str);
bad_form:
ASN1_TYPE_free(atmp);
return NULL;
}
static int
bitstr_cb(const char *elem, int len, void *bitstr)
{
long bitnum;
char *eptr;
if (!elem)
return 0;
bitnum = strtoul(elem, &eptr, 10);
if (eptr && *eptr && (eptr != elem + len))
return 0;
if (bitnum < 0) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}

486
crypto/asn1/asn1_lib.c Normal file
View File

@ -0,0 +1,486 @@
/* $OpenBSD: asn1_lib.c,v 1.39 2017/05/02 03:59:44 deraadt 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max);
static void asn1_put_length(unsigned char **pp, int length);
static int
_asn1_check_infinite_end(const unsigned char **p, long len)
{
/* If there is 0 or 1 byte left, the length check should pick
* things up */
if (len <= 0)
return (1);
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
(*p) += 2;
return (1);
}
return (0);
}
int
ASN1_check_infinite_end(unsigned char **p, long len)
{
return _asn1_check_infinite_end((const unsigned char **)p, len);
}
int
ASN1_const_check_infinite_end(const unsigned char **p, long len)
{
return _asn1_check_infinite_end(p, len);
}
int
ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
int *pclass, long omax)
{
int i, ret;
long l;
const unsigned char *p= *pp;
int tag, xclass, inf;
long max = omax;
if (!max)
goto err;
ret = (*p & V_ASN1_CONSTRUCTED);
xclass = (*p & V_ASN1_PRIVATE);
i= *p & V_ASN1_PRIMITIVE_TAG;
if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
p++;
if (--max == 0)
goto err;
l = 0;
while (*p & 0x80) {
l <<= 7L;
l |= *(p++) & 0x7f;
if (--max == 0)
goto err;
if (l > (INT_MAX >> 7L))
goto err;
}
l <<= 7L;
l |= *(p++) & 0x7f;
tag = (int)l;
if (--max == 0)
goto err;
} else {
tag = i;
p++;
if (--max == 0)
goto err;
}
*ptag = tag;
*pclass = xclass;
if (!asn1_get_length(&p, &inf, plength, (int)max))
goto err;
if (inf && !(ret & V_ASN1_CONSTRUCTED))
goto err;
if (*plength > (omax - (p - *pp))) {
ASN1error(ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret |= 0x80;
}
*pp = p;
return (ret | inf);
err:
ASN1error(ASN1_R_HEADER_TOO_LONG);
return (0x80);
}
static int
asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
{
const unsigned char *p= *pp;
unsigned long ret = 0;
unsigned int i;
if (max-- < 1)
return (0);
if (*p == 0x80) {
*inf = 1;
ret = 0;
p++;
} else {
*inf = 0;
i= *p & 0x7f;
if (*(p++) & 0x80) {
if (max < (int)i)
return (0);
/* skip leading zeroes */
while (i && *p == 0) {
p++;
i--;
}
if (i > sizeof(long))
return 0;
while (i-- > 0) {
ret <<= 8L;
ret |= *(p++);
}
} else
ret = i;
}
if (ret > LONG_MAX)
return 0;
*pp = p;
*rl = (long)ret;
return (1);
}
/* class 0 is constructed
* constructed == 2 for indefinite length constructed */
void
ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
int xclass)
{
unsigned char *p= *pp;
int i, ttag;
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
i |= (xclass & V_ASN1_PRIVATE);
if (tag < 31)
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
else {
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
for(i = 0, ttag = tag; ttag > 0; i++)
ttag >>= 7;
ttag = i;
while (i-- > 0) {
p[i] = tag & 0x7f;
if (i != (ttag - 1))
p[i] |= 0x80;
tag >>= 7;
}
p += ttag;
}
if (constructed == 2)
*(p++) = 0x80;
else
asn1_put_length(&p, length);
*pp = p;
}
int
ASN1_put_eoc(unsigned char **pp)
{
unsigned char *p = *pp;
*p++ = 0;
*p++ = 0;
*pp = p;
return 2;
}
static void
asn1_put_length(unsigned char **pp, int length)
{
unsigned char *p= *pp;
int i, l;
if (length <= 127)
*(p++) = (unsigned char)length;
else {
l = length;
for (i = 0; l > 0; i++)
l >>= 8;
*(p++) = i | 0x80;
l = i;
while (i-- > 0) {
p[i] = length & 0xff;
length >>= 8;
}
p += l;
}
*pp = p;
}
int
ASN1_object_size(int constructed, int length, int tag)
{
int ret;
ret = length;
ret++;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
if (constructed == 2)
return ret + 3;
ret++;
if (length > 127) {
while (length > 0) {
length >>= 8;
ret++;
}
}
return (ret);
}
static int
_asn1_Finish(ASN1_const_CTX *c)
{
if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos)) {
if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
c->error = ERR_R_MISSING_ASN1_EOS;
return (0);
}
}
if (((c->slen != 0) && !(c->inf & 1)) ||
((c->slen < 0) && (c->inf & 1))) {
c->error = ERR_R_ASN1_LENGTH_MISMATCH;
return (0);
}
return (1);
}
int
asn1_Finish(ASN1_CTX *c)
{
return _asn1_Finish((ASN1_const_CTX *)c);
}
int
asn1_const_Finish(ASN1_const_CTX *c)
{
return _asn1_Finish(c);
}
int
asn1_GetSequence(ASN1_const_CTX *c, long *length)
{
const unsigned char *q;
q = c->p;
c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
*length);
if (c->inf & 0x80) {
c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
return (0);
}
if (c->tag != V_ASN1_SEQUENCE) {
c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
return (0);
}
(*length) -= (c->p - q);
if (c->max && (*length < 0)) {
c->error = ERR_R_ASN1_LENGTH_MISMATCH;
return (0);
}
if (c->inf == (1|V_ASN1_CONSTRUCTED))
c->slen= *length+ *(c->pp) - c->p;
c->eos = 0;
return (1);
}
int
ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
if (str == NULL)
return 0;
dst->type = str->type;
if (!ASN1_STRING_set(dst, str->data, str->length))
return 0;
dst->flags = str->flags;
return 1;
}
ASN1_STRING *
ASN1_STRING_dup(const ASN1_STRING *str)
{
ASN1_STRING *ret;
if (!str)
return NULL;
ret = ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret, str)) {
ASN1_STRING_free(ret);
return NULL;
}
return ret;
}
int
ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
{
const char *data = _data;
if (len < 0) {
if (data == NULL)
return (0);
else
len = strlen(data);
}
if ((str->length < len) || (str->data == NULL)) {
unsigned char *tmp;
tmp = realloc(str->data, len + 1);
if (tmp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
str->data = tmp;
}
str->length = len;
if (data != NULL) {
memmove(str->data, data, len);
}
str->data[str->length]='\0';
return (1);
}
void
ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
freezero(str->data, str->length);
str->data = data;
str->length = len;
}
ASN1_STRING *
ASN1_STRING_new(void)
{
return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
}
ASN1_STRING *
ASN1_STRING_type_new(int type)
{
ASN1_STRING *ret;
ret = malloc(sizeof(ASN1_STRING));
if (ret == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->length = 0;
ret->type = type;
ret->data = NULL;
ret->flags = 0;
return (ret);
}
void
ASN1_STRING_free(ASN1_STRING *a)
{
if (a == NULL)
return;
if (a->data != NULL && !(a->flags & ASN1_STRING_FLAG_NDEF))
freezero(a->data, a->length);
free(a);
}
int
ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int i;
i = (a->length - b->length);
if (i == 0) {
i = memcmp(a->data, b->data, a->length);
if (i == 0)
return (a->type - b->type);
else
return (i);
} else
return (i);
}
void
asn1_add_error(const unsigned char *address, int offset)
{
ERR_asprintf_error_data("offset=%d", offset);
}
int
ASN1_STRING_length(const ASN1_STRING *x)
{
return (x->length);
}
void
ASN1_STRING_length_set(ASN1_STRING *x, int len)
{
x->length = len;
}
int
ASN1_STRING_type(ASN1_STRING *x)
{
return (x->type);
}
unsigned char *
ASN1_STRING_data(ASN1_STRING *x)
{
return (x->data);
}

155
crypto/asn1/asn1_locl.h Normal file
View File

@ -0,0 +1,155 @@
/* $OpenBSD: asn1_locl.h,v 1.10 2017/08/27 01:39:26 beck 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).
*
*/
__BEGIN_HIDDEN_DECLS
/* Internal ASN1 structures and functions: not for application use */
/* ASN1 print context structure */
struct asn1_pctx_st {
unsigned long flags;
unsigned long nm_flags;
unsigned long cert_flags;
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */;
/* ASN1 public key method structure */
struct evp_pkey_asn1_method_st {
int pkey_id;
int pkey_base_id;
unsigned long pkey_flags;
char *pem_str;
char *info;
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder,
int derlen);
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
int (*sig_print)(BIO *out, const X509_ALGOR *sigalg,
const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx);
void (*pkey_free)(EVP_PKEY *pkey);
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
/* Legacy functions for old PEM */
int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
int derlen);
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
/* Custom ASN1 signature verification */
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
} /* EVP_PKEY_ASN1_METHOD */;
/* Method to handle CRL access.
* In general a CRL could be very large (several Mb) and can consume large
* amounts of resources if stored in memory by multiple processes.
* This method allows general CRL operations to be redirected to more
* efficient callbacks: for example a CRL entry database.
*/
#define X509_CRL_METHOD_DYNAMIC 1
struct x509_crl_method_st {
int flags;
int (*crl_init)(X509_CRL *crl);
int (*crl_free)(X509_CRL *crl);
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *ser, X509_NAME *issuer);
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
};
/*
* Unicode codepoint constants
*/
#define UNICODE_MAX 0x10FFFF
#define UNICODE_SURROGATE_MIN 0x00D800
#define UNICODE_SURROGATE_MAX 0x00DFFF
#define UNICODE_IS_SURROGATE(x) \
((x) >= UNICODE_SURROGATE_MIN && (x) <= UNICODE_SURROGATE_MAX)
int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
int UTF8_putc(unsigned char *str, int len, unsigned long value);
__END_HIDDEN_DECLS

397
crypto/asn1/asn1_par.c Normal file
View File

@ -0,0 +1,397 @@
/* $OpenBSD: asn1_par.c,v 1.25 2015/09/30 19:01:14 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.]
*/
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/objects.h>
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
int offset, int depth, int indent, int dump);
static int
asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
{
char str[128];
const char *p;
if (constructed & V_ASN1_CONSTRUCTED)
p="cons: ";
else
p="prim: ";
if (BIO_write(bp, p, 6) < 6)
goto err;
BIO_indent(bp, indent, 128);
p = str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
snprintf(str, sizeof str, "priv [ %d ] ", tag);
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
snprintf(str, sizeof str, "cont [ %d ]", tag);
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
snprintf(str, sizeof str, "appl [ %d ]", tag);
else if (tag > 30)
snprintf(str, sizeof str, "<ASN1 %d>", tag);
else
p = ASN1_tag2str(tag);
if (BIO_printf(bp, "%-18s", p) <= 0)
goto err;
return (1);
err:
return (0);
}
int
ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
}
int
ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
}
static int
asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
int depth, int indent, int dump)
{
const unsigned char *p, *ep, *tot, *op, *opp;
long len;
int tag, xclass, ret = 0;
int nl, hl, j, r;
ASN1_OBJECT *o = NULL;
ASN1_OCTET_STRING *os = NULL;
/* ASN1_BMPSTRING *bmp=NULL;*/
int dump_indent;
dump_indent = 6; /* Because we know BIO_dump_indent() */
p = *pp;
tot = p + length;
op = p - 1;
while ((p < tot) && (op < p)) {
op = p;
j = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (j & 0x80) {
if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
goto end;
ret = 0;
goto end;
}
hl = (p - op);
length -= hl;
/* if j == 0x21 it is a constructed indefinite length object */
if (BIO_printf(bp, "%5ld:", (long)offset +
(long)(op - *pp)) <= 0)
goto end;
if (j != (V_ASN1_CONSTRUCTED | 1)) {
if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
depth, (long)hl, len) <= 0)
goto end;
} else {
if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ",
depth, (long)hl) <= 0)
goto end;
}
if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
goto end;
if (j & V_ASN1_CONSTRUCTED) {
ep = p + len;
if (BIO_write(bp, "\n", 1) <= 0)
goto end;
if (len > length) {
BIO_printf(bp, "length is greater than %ld\n",
length);
ret = 0;
goto end;
}
if ((j == 0x21) && (len == 0)) {
for (;;) {
r = asn1_parse2(bp, &p, (long)(tot - p),
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
if ((r == 2) || (p >= tot))
break;
}
} else
while (p < ep) {
r = asn1_parse2(bp, &p, (long)len,
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
}
} else if (xclass != 0) {
p += len;
if (BIO_write(bp, "\n", 1) <= 0)
goto end;
} else {
nl = 0;
if ((tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_IA5STRING) ||
(tag == V_ASN1_VISIBLESTRING) ||
(tag == V_ASN1_NUMERICSTRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) ||
(tag == V_ASN1_GENERALIZEDTIME)) {
if (BIO_write(bp, ":", 1) <= 0)
goto end;
if ((len > 0) &&
BIO_write(bp, (const char *)p, (int)len) !=
(int)len)
goto end;
} else if (tag == V_ASN1_OBJECT) {
opp = op;
if (d2i_ASN1_OBJECT(&o, &opp, len + hl) !=
NULL) {
if (BIO_write(bp, ":", 1) <= 0)
goto end;
i2a_ASN1_OBJECT(bp, o);
} else {
if (BIO_write(bp, ":BAD OBJECT",
11) <= 0)
goto end;
}
} else if (tag == V_ASN1_BOOLEAN) {
int ii;
opp = op;
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
if (ii < 0) {
if (BIO_write(bp, "Bad boolean\n",
12) <= 0)
goto end;
}
BIO_printf(bp, ":%d", ii);
} else if (tag == V_ASN1_BMPSTRING) {
/* do the BMP thang */
} else if (tag == V_ASN1_OCTET_STRING) {
int i, printable = 1;
opp = op;
os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
if (os != NULL && os->length > 0) {
opp = os->data;
/* testing whether the octet string is
* printable */
for (i = 0; i < os->length; i++) {
if (((opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) ||
(opp[i] > '~')) {
printable = 0;
break;
}
}
if (printable) {
/* printable string */
if (BIO_write(bp, ":", 1) <= 0)
goto end;
if (BIO_write(bp, (const char *)opp,
os->length) <= 0)
goto end;
} else if (!dump) {
/* not printable => print octet string
* as hex dump */
if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
goto end;
for (i = 0; i < os->length; i++) {
if (BIO_printf(bp,
"%02X", opp[i]) <= 0)
goto end;
}
} else {
/* print the normal dump */
if (!nl) {
if (BIO_write(bp, "\n", 1) <= 0)
goto end;
}
if (BIO_dump_indent(bp,
(const char *)opp,
((dump == -1 || dump >
os->length) ? os->length : dump),
dump_indent) <= 0)
goto end;
nl = 1;
}
}
ASN1_OCTET_STRING_free(os);
os = NULL;
} else if (tag == V_ASN1_INTEGER) {
ASN1_INTEGER *bs;
int i;
opp = op;
bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_write(bp, ":", 1) <= 0)
goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_write(bp, "-", 1) <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X",
bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_write(bp, "00", 2) <= 0)
goto end;
}
} else {
if (BIO_write(bp, "BAD INTEGER", 11) <= 0)
goto end;
}
ASN1_INTEGER_free(bs);
} else if (tag == V_ASN1_ENUMERATED) {
ASN1_ENUMERATED *bs;
int i;
opp = op;
bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_write(bp, ":", 1) <= 0)
goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_write(bp, "-", 1) <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X",
bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_write(bp, "00", 2) <= 0)
goto end;
}
} else {
if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0)
goto end;
}
ASN1_ENUMERATED_free(bs);
} else if (len > 0 && dump) {
if (!nl) {
if (BIO_write(bp, "\n", 1) <= 0)
goto end;
}
if (BIO_dump_indent(bp, (const char *)p,
((dump == -1 || dump > len) ? len : dump),
dump_indent) <= 0)
goto end;
nl = 1;
}
if (!nl) {
if (BIO_write(bp, "\n", 1) <= 0)
goto end;
}
p += len;
if ((tag == V_ASN1_EOC) && (xclass == 0)) {
ret = 2; /* End of sequence */
goto end;
}
}
length -= len;
}
ret = 1;
end:
if (o != NULL)
ASN1_OBJECT_free(o);
ASN1_OCTET_STRING_free(os);
*pp = p;
return (ret);
}
const char *
ASN1_tag2str(int tag)
{
static const char * const tag2str[] = {
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 */
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
};
if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
tag &= ~0x100;
if (tag < 0 || tag > 30)
return "(unknown)";
return tag2str[tag];
}

1011
crypto/asn1/asn_mime.c Normal file

File diff suppressed because it is too large Load Diff

158
crypto/asn1/asn_moid.c Normal file
View File

@ -0,0 +1,158 @@
/* $OpenBSD: asn_moid.c,v 1.13 2017/01/29 17:49:22 beck Exp $ */
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
/* ====================================================================
* Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
/* Simple ASN1 OID module: add all objects in a given section */
static int do_create(char *value, char *name);
static int
oid_module_init(CONF_IMODULE *md, const CONF *cnf)
{
int i;
const char *oid_section;
STACK_OF(CONF_VALUE) *sktmp;
CONF_VALUE *oval;
oid_section = CONF_imodule_get_value(md);
if (!(sktmp = NCONF_get_section(cnf, oid_section))) {
ASN1error(ASN1_R_ERROR_LOADING_SECTION);
return 0;
}
for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
oval = sk_CONF_VALUE_value(sktmp, i);
if (!do_create(oval->value, oval->name)) {
ASN1error(ASN1_R_ADDING_OBJECT);
return 0;
}
}
return 1;
}
static void
oid_module_finish(CONF_IMODULE *md)
{
OBJ_cleanup();
}
void
ASN1_add_oid_module(void)
{
CONF_module_add("oid_section", oid_module_init, oid_module_finish);
}
/* Create an OID based on a name value pair. Accept two formats.
* shortname = 1.2.3.4
* shortname = some long name, 1.2.3.4
*/
static int
do_create(char *value, char *name)
{
int nid;
ASN1_OBJECT *oid;
char *ln, *ostr, *p, *lntmp;
p = strrchr(value, ',');
if (!p) {
ln = name;
ostr = value;
} else {
ln = NULL;
ostr = p + 1;
if (!*ostr)
return 0;
while (isspace((unsigned char)*ostr))
ostr++;
}
nid = OBJ_create(ostr, name, ln);
if (nid == NID_undef)
return 0;
if (p) {
ln = value;
while (isspace((unsigned char)*ln))
ln++;
p--;
while (isspace((unsigned char)*p)) {
if (p == ln)
return 0;
p--;
}
p++;
lntmp = malloc((p - ln) + 1);
if (lntmp == NULL)
return 0;
memcpy(lntmp, ln, p - ln);
lntmp[p - ln] = 0;
oid = OBJ_nid2obj(nid);
oid->ln = lntmp;
}
return 1;
}

215
crypto/asn1/asn_pack.c Normal file
View File

@ -0,0 +1,215 @@
/* $OpenBSD: asn_pack.c,v 1.16 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#ifndef NO_ASN1_OLD
/* ASN1 packing and unpacking functions */
/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
STACK_OF(OPENSSL_BLOCK) *
ASN1_seq_unpack(const unsigned char *buf, int len, d2i_of_void *d2i,
void (*free_func)(OPENSSL_BLOCK))
{
STACK_OF(OPENSSL_BLOCK) *sk;
const unsigned char *pbuf;
pbuf = buf;
if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
ASN1error(ASN1_R_DECODE_ERROR);
return sk;
}
/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
* OPENSSL_malloc'ed buffer
*/
unsigned char *
ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
unsigned char **buf, int *len)
{
int safelen;
unsigned char *safe, *p;
if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
ASN1error(ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!(safe = malloc(safelen))) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
p = safe;
i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
IS_SEQUENCE);
if (len)
*len = safelen;
if (buf)
*buf = safe;
return safe;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *
ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
{
const unsigned char *p;
char *ret;
p = oct->data;
if (!(ret = d2i(NULL, &p, oct->length)))
ASN1error(ASN1_R_DECODE_ERROR);
return ret;
}
/* Pack an ASN1 object into an ASN1_STRING */
ASN1_STRING *
ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
{
unsigned char *p;
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new())) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
} else
octmp = *oct;
if (!(octmp->length = i2d(obj, NULL))) {
ASN1error(ASN1_R_ENCODE_ERROR);
goto err;
}
if (!(p = malloc (octmp->length))) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
octmp->data = p;
i2d (obj, &p);
if (oct)
*oct = octmp;
return octmp;
err:
if (!oct || octmp != *oct) {
ASN1_STRING_free(octmp);
if (oct)
*oct = NULL;
}
return NULL;
}
#endif
/* ASN1_ITEM versions of the above */
ASN1_STRING *
ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
{
ASN1_STRING *octmp;
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
} else
octmp = *oct;
free(octmp->data);
octmp->data = NULL;
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
ASN1error(ASN1_R_ENCODE_ERROR);
goto err;
}
if (!octmp->data) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (oct)
*oct = octmp;
return octmp;
err:
if (!oct || octmp != *oct)
ASN1_STRING_free(octmp);
return NULL;
}
/* Extract an ASN1 object from an ASN1_STRING */
void *
ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
{
const unsigned char *p;
void *ret;
p = oct->data;
if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
ASN1error(ASN1_R_DECODE_ERROR);
return ret;
}

496
crypto/asn1/bio_asn1.c Normal file
View File

@ -0,0 +1,496 @@
/* $OpenBSD: bio_asn1.c,v 1.12 2015/12/23 01:46:33 mmcc Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* 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).
*
*/
/* Experimental ASN1 BIO. When written through the data is converted
* to an ASN1 string type: default is OCTET STRING. Additional functions
* can be provided to add prefix and suffix data.
*/
#include <stdlib.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/asn1.h>
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum {
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_HEADER_COPY,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
} asn1_bio_state_t;
typedef struct BIO_ASN1_EX_FUNCS_st {
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_BUF_CTX_t {
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
unsigned char *buf;
/* Size of buffer */
int bufsize;
/* Current position in buffer */
int bufpos;
/* Current buffer length */
int buflen;
/* Amount of data to copy */
int copylen;
/* Class and tag to use */
int asn1_class, asn1_tag;
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
/* Extra buffer for prefix and suffix data */
unsigned char *ex_buf;
int ex_len;
int ex_pos;
void *ex_arg;
} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf, int num);
static int asn1_bio_read(BIO *h, char *buf, int size);
static int asn1_bio_puts(BIO *h, const char *str);
static int asn1_bio_gets(BIO *h, char *str, int size);
static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int asn1_bio_new(BIO *h);
static int asn1_bio_free(BIO *data);
static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup, asn1_bio_state_t ex_state,
asn1_bio_state_t other_state);
static BIO_METHOD methods_asn1 = {
.type = BIO_TYPE_ASN1,
.name = "asn1",
.bwrite = asn1_bio_write,
.bread = asn1_bio_read,
.bputs = asn1_bio_puts,
.bgets = asn1_bio_gets,
.ctrl = asn1_bio_ctrl,
.create = asn1_bio_new,
.destroy = asn1_bio_free,
.callback_ctrl = asn1_bio_callback_ctrl
};
BIO_METHOD *
BIO_f_asn1(void)
{
return (&methods_asn1);
}
static int
asn1_bio_new(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
free(ctx);
return 0;
}
b->init = 1;
b->ptr = (char *)ctx;
b->flags = 0;
return 1;
}
static int
asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
{
ctx->buf = malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = NULL;
ctx->ex_pos = 0;
ctx->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
}
static int
asn1_bio_free(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
free(ctx->buf);
free(ctx);
b->init = 0;
b->ptr = NULL;
b->flags = 0;
return 1;
}
static int
asn1_bio_write(BIO *b, const char *in , int inl)
{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret, buflen;
unsigned char *p;
if (!in || (inl < 0) || (b->next_bio == NULL))
return 0;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
wrlen = 0;
ret = -1;
for (;;) {
switch (ctx->state) {
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
return 0;
break;
/* Copy any pre data first */
case ASN1_STATE_PRE_COPY:
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
ASN1_STATE_HEADER);
if (ret <= 0)
goto done;
break;
case ASN1_STATE_HEADER:
buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
if (buflen <= 0 || buflen > ctx->bufsize)
return -1;
ctx->buflen = buflen;
p = ctx->buf;
ASN1_put_object(&p, 0, inl,
ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
ctx->state = ASN1_STATE_HEADER_COPY;
break;
case ASN1_STATE_HEADER_COPY:
ret = BIO_write(b->next_bio,
ctx->buf + ctx->bufpos, ctx->buflen);
if (ret <= 0)
goto done;
ctx->buflen -= ret;
if (ctx->buflen)
ctx->bufpos += ret;
else {
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
}
break;
case ASN1_STATE_DATA_COPY:
if (inl > ctx->copylen)
wrmax = ctx->copylen;
else
wrmax = inl;
ret = BIO_write(b->next_bio, in, wrmax);
if (ret <= 0)
break;
wrlen += ret;
ctx->copylen -= ret;
in += ret;
inl -= ret;
if (ctx->copylen == 0)
ctx->state = ASN1_STATE_HEADER;
if (inl == 0)
goto done;
break;
default:
BIO_clear_retry_flags(b);
return 0;
}
}
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (wrlen > 0) ? wrlen : ret;
}
static int
asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *cleanup,
asn1_bio_state_t next)
{
int ret;
if (ctx->ex_len <= 0)
return 1;
for (;;) {
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
ctx->ex_len);
if (ret <= 0)
break;
ctx->ex_len -= ret;
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else {
if (cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
&ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
}
}
return ret;
}
static int
asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, asn1_ps_func *setup,
asn1_bio_state_t ex_state, asn1_bio_state_t other_state)
{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
BIO_clear_retry_flags(b);
return 0;
}
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
}
static int
asn1_bio_read(BIO *b, char *in , int inl)
{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in , inl);
}
static int
asn1_bio_puts(BIO *b, const char *str)
{
return asn1_bio_write(b, str, strlen(str));
}
static int
asn1_bio_gets(BIO *b, char *str, int size)
{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str , size);
}
static long
asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
{
if (b->next_bio == NULL)
return (0);
return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static long
asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
if (ctx == NULL)
return 0;
switch (cmd) {
case BIO_C_SET_PREFIX:
ex_func = arg2;
ctx->prefix = ex_func->ex_func;
ctx->prefix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_PREFIX:
ex_func = arg2;
ex_func->ex_func = ctx->prefix;
ex_func->ex_free_func = ctx->prefix_free;
break;
case BIO_C_SET_SUFFIX:
ex_func = arg2;
ctx->suffix = ex_func->ex_func;
ctx->suffix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_SUFFIX:
ex_func = arg2;
ex_func->ex_func = ctx->suffix;
ex_func->ex_free_func = ctx->suffix_free;
break;
case BIO_C_SET_EX_ARG:
ctx->ex_arg = arg2;
break;
case BIO_C_GET_EX_ARG:
*(void **)arg2 = ctx->ex_arg;
break;
case BIO_CTRL_FLUSH:
if (!b->next_bio)
return 0;
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER) {
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
}
if (ctx->state == ASN1_STATE_POST_COPY) {
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
}
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else {
BIO_clear_retry_flags(b);
return 0;
}
break;
default:
if (!b->next_bio)
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
}
return ret;
}
static int
asn1_bio_set_ex(BIO *b, int cmd, asn1_ps_func *ex_func, asn1_ps_func
*ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
}
static int
asn1_bio_get_ex(BIO *b, int cmd, asn1_ps_func **ex_func,
asn1_ps_func **ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0) {
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
}
return ret;
}
int
BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
}
int
BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
}
int
BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
}
int
BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
}

243
crypto/asn1/bio_ndef.c Normal file
View File

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

19
crypto/asn1/charmap.h Normal file
View File

@ -0,0 +1,19 @@
/* $OpenBSD: charmap.h,v 1.5 2016/12/21 15:49:29 jsing Exp $ */
/* Auto generated with chartype.pl script.
* Mask of various character properties
*/
__BEGIN_HIDDEN_DECLS
static const unsigned char char_type[] = {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
};
__END_HIDDEN_DECLS

169
crypto/asn1/d2i_pr.c Normal file
View File

@ -0,0 +1,169 @@
/* $OpenBSD: d2i_pr.c,v 1.15 2017/01/29 17:49:22 beck 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 <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_ENGINE
#include <openssl/engine.h>
#endif
#include "asn1_locl.h"
EVP_PKEY *
d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
{
EVP_PKEY *ret;
if ((a == NULL) || (*a == NULL)) {
if ((ret = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_EVP_LIB);
return (NULL);
}
} else {
ret = *a;
#ifndef OPENSSL_NO_ENGINE
if (ret->engine) {
ENGINE_finish(ret->engine);
ret->engine = NULL;
}
#endif
}
if (!EVP_PKEY_set_type(ret, type)) {
ASN1error(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
}
if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, pp, length)) {
if (ret->ameth->priv_decode) {
PKCS8_PRIV_KEY_INFO *p8 = NULL;
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, pp, length);
if (!p8)
goto err;
EVP_PKEY_free(ret);
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
} else {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
}
if (a != NULL)
(*a) = ret;
return (ret);
err:
if (a == NULL || *a != ret)
EVP_PKEY_free(ret);
return (NULL);
}
/* This works like d2i_PrivateKey() except it automatically works out the type */
EVP_PKEY *
d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, long length)
{
STACK_OF(ASN1_TYPE) *inkey;
const unsigned char *p;
int keytype;
p = *pp;
/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
* by analyzing it we can determine the passed structure: this
* assumes the input is surrounded by an ASN1 SEQUENCE.
*/
inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
/* Since we only need to discern "traditional format" RSA and DSA
* keys we can just count the elements.
*/
if (sk_ASN1_TYPE_num(inkey) == 6)
keytype = EVP_PKEY_DSA;
else if (sk_ASN1_TYPE_num(inkey) == 4)
keytype = EVP_PKEY_EC;
else if (sk_ASN1_TYPE_num(inkey) == 3) {
/* This seems to be PKCS8, not traditional format */
PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(
NULL, pp, length);
EVP_PKEY *ret;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
if (!p8) {
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return NULL;
}
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
if (a) {
*a = ret;
}
return ret;
} else
keytype = EVP_PKEY_RSA;
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
return d2i_PrivateKey(keytype, a, pp, length);
}

136
crypto/asn1/d2i_pu.c Normal file
View File

@ -0,0 +1,136 @@
/* $OpenBSD: d2i_pu.c,v 1.14 2017/01/29 17:49:22 beck 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 <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
EVP_PKEY *
d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
{
EVP_PKEY *ret;
if ((a == NULL) || (*a == NULL)) {
if ((ret = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_EVP_LIB);
return (NULL);
}
} else
ret = *a;
if (!EVP_PKEY_set_type(ret, type)) {
ASN1error(ERR_R_EVP_LIB);
goto err;
}
switch (EVP_PKEY_id(ret)) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, pp, length)) ==
NULL) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if (!d2i_DSAPublicKey(&(ret->pkey.dsa), pp, length)) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
if (!o2i_ECPublicKey(&(ret->pkey.ec), pp, length)) {
ASN1error(ERR_R_ASN1_LIB);
goto err;
}
break;
#endif
default:
ASN1error(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
/* break; */
}
if (a != NULL)
(*a) = ret;
return (ret);
err:
if (a == NULL || *a != ret)
EVP_PKEY_free(ret);
return (NULL);
}

200
crypto/asn1/evp_asn1.c Normal file
View File

@ -0,0 +1,200 @@
/* $OpenBSD: evp_asn1.c,v 1.19 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1_mac.h>
#include <openssl/err.h>
int
ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
{
ASN1_STRING *os;
if ((os = ASN1_OCTET_STRING_new()) == NULL)
return (0);
if (!ASN1_STRING_set(os, data, len)) {
ASN1_OCTET_STRING_free(os);
return (0);
}
ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
return (1);
}
/* int max_len: for returned value */
int
ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len)
{
int ret, num;
unsigned char *p;
if ((a->type != V_ASN1_OCTET_STRING) ||
(a->value.octet_string == NULL)) {
ASN1error(ASN1_R_DATA_IS_WRONG);
return (-1);
}
p = ASN1_STRING_data(a->value.octet_string);
ret = ASN1_STRING_length(a->value.octet_string);
if (ret < max_len)
num = ret;
else
num = max_len;
memcpy(data, p, num);
return (ret);
}
int
ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
int len)
{
int n, size;
ASN1_OCTET_STRING os, *osp;
ASN1_INTEGER in;
unsigned char *p;
unsigned char buf[32]; /* when they have 256bit longs,
* I'll be in trouble */
in.data = buf;
in.length = 32;
os.data = data;
os.type = V_ASN1_OCTET_STRING;
os.length = len;
ASN1_INTEGER_set(&in, num);
n = i2d_ASN1_INTEGER(&in, NULL);
n += i2d_ASN1_bytes((ASN1_STRING *)&os, NULL, V_ASN1_OCTET_STRING,
V_ASN1_UNIVERSAL);
size = ASN1_object_size(1, n, V_ASN1_SEQUENCE);
if ((osp = ASN1_STRING_new()) == NULL)
return (0);
/* Grow the 'string' */
if (!ASN1_STRING_set(osp, NULL, size)) {
ASN1_STRING_free(osp);
return (0);
}
ASN1_STRING_length_set(osp, size);
p = ASN1_STRING_data(osp);
ASN1_put_object(&p, 1,n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
i2d_ASN1_INTEGER(&in, &p);
i2d_ASN1_bytes((ASN1_STRING *)&os, &p, V_ASN1_OCTET_STRING,
V_ASN1_UNIVERSAL);
ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp);
return (1);
}
/* we return the actual length..., num may be missing, in which
* case, set it to zero */
/* int max_len: for returned value */
int
ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
int max_len)
{
int ret = -1, n;
ASN1_INTEGER *ai = NULL;
ASN1_OCTET_STRING *os = NULL;
const unsigned char *p;
long length;
ASN1_const_CTX c;
if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
goto err;
}
p = ASN1_STRING_data(a->value.sequence);
length = ASN1_STRING_length(a->value.sequence);
c.pp = &p;
c.p = p;
c.max = p + length;
c.error = ASN1_R_DATA_IS_WRONG;
M_ASN1_D2I_start_sequence();
c.q = c.p;
if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
goto err;
c.slen -= (c.p - c.q);
c.q = c.p;
if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
goto err;
c.slen -= (c.p - c.q);
if (!M_ASN1_D2I_end_sequence())
goto err;
if (num != NULL)
*num = ASN1_INTEGER_get(ai);
ret = ASN1_STRING_length(os);
if (max_len > ret)
n = ret;
else
n = max_len;
if (data != NULL)
memcpy(data, ASN1_STRING_data(os), n);
if (0) {
err:
ASN1error(ASN1_R_DATA_IS_WRONG);
}
ASN1_OCTET_STRING_free(os);
ASN1_INTEGER_free(ai);
return (ret);
}

198
crypto/asn1/f_enum.c Normal file
View File

@ -0,0 +1,198 @@
/* $OpenBSD: f_enum.c,v 1.15 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
/* Based on a_int.c: equivalent ENUMERATED functions */
int
i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (a == NULL)
return (0);
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n = 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int
a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
{
int ret = 0;
int i, j,k, m,n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int first = 1;
size_t num = 0, slen = 0;
bs->type = V_ASN1_ENUMERATED;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i-1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i-1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j = 0; j < i; j++) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
i -= again;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
sp = realloc(s, num + i);
if (sp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
return (1);
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return (ret);
}

201
crypto/asn1/f_int.c Normal file
View File

@ -0,0 +1,201 @@
/* $OpenBSD: f_int.c,v 1.18 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
int
i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (a == NULL)
return (0);
if (a->type & V_ASN1_NEG) {
if (BIO_write(bp, "-", 1) != 1)
goto err;
n = 1;
}
if (a->length == 0) {
if (BIO_write(bp, "00", 2) != 2)
goto err;
n += 2;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int
a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
{
int ret = 0;
int i, j,k, m,n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int num = 0, slen = 0, first = 1;
bs->type = V_ASN1_INTEGER;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1)
goto err_sl;
i = bufsize;
if (buf[i - 1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i - 1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j = 0; j < i; j++) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
if (first) {
first = 0;
if ((bufp[0] == '0') && (buf[1] == '0')) {
bufp += 2;
i -= 2;
}
}
k = 0;
i -= again;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
sp = OPENSSL_realloc_clean(s, slen, num + i);
if (sp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
return (1);
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return (ret);
}

194
crypto/asn1/f_string.c Normal file
View File

@ -0,0 +1,194 @@
/* $OpenBSD: f_string.c,v 1.17 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
int
i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (a == NULL)
return (0);
if (a->length == 0) {
if (BIO_write(bp, "0", 1) != 1)
goto err;
n = 1;
} else {
for (i = 0; i < a->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
if (BIO_write(bp, buf, 2) != 2)
goto err;
n += 2;
}
}
return (n);
err:
return (-1);
}
int
a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
{
int ret = 0;
int i, j, k, m, n, again, bufsize;
unsigned char *s = NULL, *sp;
unsigned char *bufp;
int first = 1;
size_t num = 0, slen = 0;
bufsize = BIO_gets(bp, buf, size);
for (;;) {
if (bufsize < 1) {
if (first)
break;
else
goto err_sl;
}
first = 0;
i = bufsize;
if (buf[i-1] == '\n')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
if (buf[i-1] == '\r')
buf[--i] = '\0';
if (i == 0)
goto err_sl;
again = (buf[i - 1] == '\\');
for (j = i - 1; j > 0; j--) {
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
i = j;
break;
}
}
buf[i] = '\0';
/* We have now cleared all the crap off the end of the
* line */
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
k = 0;
i -= again;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
sp = realloc(s, num + i);
if (sp == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
s = sp;
slen = num + i;
}
for (j = 0; j < i; j++, k += 2) {
for (n = 0; n < 2; n++) {
m = bufp[k + n];
if ((m >= '0') && (m <= '9'))
m -= '0';
else if ((m >= 'a') && (m <= 'f'))
m = m - 'a' + 10;
else if ((m >= 'A') && (m <= 'F'))
m = m - 'A' + 10;
else {
ASN1error(ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num + j] <<= 4;
s[num + j] |= m;
}
}
num += i;
if (again)
bufsize = BIO_gets(bp, buf, size);
else
break;
}
bs->length = num;
bs->data = s;
return (1);
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return (ret);
}

81
crypto/asn1/i2d_pr.c Normal file
View File

@ -0,0 +1,81 @@
/* $OpenBSD: i2d_pr.c,v 1.11 2017/01/29 17:49:22 beck 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 <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
int
i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
{
if (a->ameth && a->ameth->old_priv_encode) {
return a->ameth->old_priv_encode(a, pp);
}
if (a->ameth && a->ameth->priv_encode) {
PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
PKCS8_PRIV_KEY_INFO_free(p8);
return ret;
}
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return (-1);
}

98
crypto/asn1/i2d_pu.c Normal file
View File

@ -0,0 +1,98 @@
/* $OpenBSD: i2d_pu.c,v 1.11 2017/01/29 17:49:22 beck 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 <openssl/opensslconf.h>
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
int
i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
{
switch (a->type) {
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
return (i2d_RSAPublicKey(a->pkey.rsa, pp));
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
return (i2d_DSAPublicKey(a->pkey.dsa, pp));
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
return (i2o_ECPublicKey(a->pkey.ec, pp));
#endif
default:
ASN1error(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return (-1);
}
}

432
crypto/asn1/n_pkey.c Normal file
View File

@ -0,0 +1,432 @@
/* $OpenBSD: n_pkey.c,v 1.31 2017/01/29 17:49:22 beck 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 <string.h>
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_RSA
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_RC4
typedef struct netscape_pkey_st {
long version;
X509_ALGOR *algor;
ASN1_OCTET_STRING *private_key;
} NETSCAPE_PKEY;
typedef struct netscape_encrypted_pkey_st {
ASN1_OCTET_STRING *os;
/* This is the same structure as DigestInfo so use it:
* although this isn't really anything to do with
* digests.
*/
X509_SIG *enckey;
} NETSCAPE_ENCRYPTED_PKEY;
static const ASN1_AUX NETSCAPE_ENCRYPTED_PKEY_aux = {
.flags = ASN1_AFLG_BROKEN,
};
static const ASN1_TEMPLATE NETSCAPE_ENCRYPTED_PKEY_seq_tt[] = {
{
.offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, os),
.field_name = "os",
.item = &ASN1_OCTET_STRING_it,
},
{
.offset = offsetof(NETSCAPE_ENCRYPTED_PKEY, enckey),
.field_name = "enckey",
.item = &X509_SIG_it,
},
};
const ASN1_ITEM NETSCAPE_ENCRYPTED_PKEY_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = NETSCAPE_ENCRYPTED_PKEY_seq_tt,
.tcount = sizeof(NETSCAPE_ENCRYPTED_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = &NETSCAPE_ENCRYPTED_PKEY_aux,
.size = sizeof(NETSCAPE_ENCRYPTED_PKEY),
.sname = "NETSCAPE_ENCRYPTED_PKEY",
};
NETSCAPE_ENCRYPTED_PKEY *NETSCAPE_ENCRYPTED_PKEY_new(void);
void NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a);
NETSCAPE_ENCRYPTED_PKEY *d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len);
int i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out);
NETSCAPE_ENCRYPTED_PKEY *
d2i_NETSCAPE_ENCRYPTED_PKEY(NETSCAPE_ENCRYPTED_PKEY **a, const unsigned char **in, long len)
{
return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&NETSCAPE_ENCRYPTED_PKEY_it);
}
int
i2d_NETSCAPE_ENCRYPTED_PKEY(const NETSCAPE_ENCRYPTED_PKEY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_ENCRYPTED_PKEY_it);
}
NETSCAPE_ENCRYPTED_PKEY *
NETSCAPE_ENCRYPTED_PKEY_new(void)
{
return (NETSCAPE_ENCRYPTED_PKEY *)ASN1_item_new(&NETSCAPE_ENCRYPTED_PKEY_it);
}
void
NETSCAPE_ENCRYPTED_PKEY_free(NETSCAPE_ENCRYPTED_PKEY *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_ENCRYPTED_PKEY_it);
}
static const ASN1_TEMPLATE NETSCAPE_PKEY_seq_tt[] = {
{
.offset = offsetof(NETSCAPE_PKEY, version),
.field_name = "version",
.item = &LONG_it,
},
{
.offset = offsetof(NETSCAPE_PKEY, algor),
.field_name = "algor",
.item = &X509_ALGOR_it,
},
{
.offset = offsetof(NETSCAPE_PKEY, private_key),
.field_name = "private_key",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM NETSCAPE_PKEY_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = NETSCAPE_PKEY_seq_tt,
.tcount = sizeof(NETSCAPE_PKEY_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(NETSCAPE_PKEY),
.sname = "NETSCAPE_PKEY",
};
NETSCAPE_PKEY *NETSCAPE_PKEY_new(void);
void NETSCAPE_PKEY_free(NETSCAPE_PKEY *a);
NETSCAPE_PKEY *d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len);
int i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out);
NETSCAPE_PKEY *
d2i_NETSCAPE_PKEY(NETSCAPE_PKEY **a, const unsigned char **in, long len)
{
return (NETSCAPE_PKEY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&NETSCAPE_PKEY_it);
}
int
i2d_NETSCAPE_PKEY(const NETSCAPE_PKEY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_PKEY_it);
}
NETSCAPE_PKEY *
NETSCAPE_PKEY_new(void)
{
return (NETSCAPE_PKEY *)ASN1_item_new(&NETSCAPE_PKEY_it);
}
void
NETSCAPE_PKEY_free(NETSCAPE_PKEY *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_PKEY_it);
}
static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey);
int
i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
int (*cb)(char *buf, int len, const char *prompt, int verify))
{
return i2d_RSA_NET(a, pp, cb, 0);
}
int
i2d_RSA_NET(const RSA *a, unsigned char **pp,
int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
{
int i, j, ret = 0;
int rsalen, pkeylen, olen;
NETSCAPE_PKEY *pkey = NULL;
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
unsigned char buf[256], *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
if (a == NULL)
return (0);
if ((pkey = NETSCAPE_PKEY_new()) == NULL)
goto err;
if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
goto err;
pkey->version = 0;
pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
goto err;
pkey->algor->parameter->type = V_ASN1_NULL;
rsalen = i2d_RSAPrivateKey(a, NULL);
/* Fake some octet strings just for the initial length
* calculation.
*/
pkey->private_key->length = rsalen;
pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);
enckey->enckey->digest->length = pkeylen;
enckey->os->length = 11; /* "private-key" */
enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
goto err;
enckey->enckey->algor->parameter->type = V_ASN1_NULL;
if (pp == NULL) {
olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
NETSCAPE_PKEY_free(pkey);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return olen;
}
/* Since its RC4 encrypted length is actual length */
if ((zz = malloc(rsalen)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
pkey->private_key->data = zz;
/* Write out private key encoding */
i2d_RSAPrivateKey(a, &zz);
if ((zz = malloc(pkeylen)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
enckey->enckey->digest->data = zz;
i2d_NETSCAPE_PKEY(pkey, &zz);
/* Wipe the private key encoding */
explicit_bzero(pkey->private_key->data, rsalen);
if (cb == NULL)
cb = EVP_read_pw_string;
i = cb((char *)buf, sizeof(buf), "Enter Private Key password:", 1);
if (i != 0) {
ASN1error(ASN1_R_BAD_PASSWORD_READ);
goto err;
}
i = strlen((char *)buf);
/* If the key is used for SGC the algorithm is modified a little. */
if (sgckey) {
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
goto err;
explicit_bzero(buf, sizeof(buf));
/* Encrypt private key in place */
zz = enckey->enckey->digest->data;
if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
goto err;
if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
goto err;
if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
goto err;
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
err:
EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
NETSCAPE_PKEY_free(pkey);
return (ret);
}
RSA *
d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
int (*cb)(char *buf, int len, const char *prompt, int verify))
{
return d2i_RSA_NET(a, pp, length, cb, 0);
}
RSA *
d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
{
RSA *ret = NULL;
const unsigned char *p;
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
p = *pp;
enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
if (!enckey) {
ASN1error(ASN1_R_DECODING_ERROR);
return NULL;
}
/* XXX 11 == strlen("private-key") */
if (enckey->os->length != 11 ||
memcmp("private-key", enckey->os->data, 11) != 0) {
ASN1error(ASN1_R_PRIVATE_KEY_HEADER_MISSING);
goto err;
}
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
ASN1error(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
goto err;
}
if (cb == NULL)
cb = EVP_read_pw_string;
if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb,
sgckey)) == NULL)
goto err;
*pp = p;
err:
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
return ret;
}
static RSA *
d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
int (*cb)(char *buf, int len, const char *prompt, int verify), int sgckey)
{
NETSCAPE_PKEY *pkey = NULL;
RSA *ret = NULL;
int i, j;
unsigned char buf[256];
const unsigned char *zz;
unsigned char key[EVP_MAX_KEY_LENGTH];
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
i=cb((char *)buf, sizeof(buf), "Enter Private Key password:",0);
if (i != 0) {
ASN1error(ASN1_R_BAD_PASSWORD_READ);
goto err;
}
i = strlen((char *)buf);
if (sgckey){
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
goto err;
memcpy(buf + 16, "SGCKEYSALT", 10);
i = 26;
}
if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i,1, key, NULL))
goto err;
explicit_bzero(buf, sizeof(buf));
if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
goto err;
if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
goto err;
if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
goto err;
os->length = i + j;
zz = os->data;
if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
ASN1error(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
goto err;
}
zz = pkey->private_key->data;
if ((ret = d2i_RSAPrivateKey(a, &zz,
pkey->private_key->length)) == NULL) {
ASN1error(ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
goto err;
}
err:
EVP_CIPHER_CTX_cleanup(&ctx);
NETSCAPE_PKEY_free(pkey);
return (ret);
}
#endif /* OPENSSL_NO_RC4 */
#endif

129
crypto/asn1/nsseq.c Normal file
View File

@ -0,0 +1,129 @@
/* $OpenBSD: nsseq.c,v 1.10 2015/02/11 04:00:39 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* 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
* 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 <openssl/asn1t.h>
#include <openssl/x509.h>
#include <openssl/objects.h>
static int
nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
{
if (operation == ASN1_OP_NEW_POST) {
NETSCAPE_CERT_SEQUENCE *nsseq;
nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
}
return 1;
}
/* Netscape certificate sequence structure */
static const ASN1_AUX NETSCAPE_CERT_SEQUENCE_aux = {
.asn1_cb = nsseq_cb,
};
static const ASN1_TEMPLATE NETSCAPE_CERT_SEQUENCE_seq_tt[] = {
{
.offset = offsetof(NETSCAPE_CERT_SEQUENCE, type),
.field_name = "type",
.item = &ASN1_OBJECT_it,
},
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
.offset = offsetof(NETSCAPE_CERT_SEQUENCE, certs),
.field_name = "certs",
.item = &X509_it,
},
};
const ASN1_ITEM NETSCAPE_CERT_SEQUENCE_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = NETSCAPE_CERT_SEQUENCE_seq_tt,
.tcount = sizeof(NETSCAPE_CERT_SEQUENCE_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = &NETSCAPE_CERT_SEQUENCE_aux,
.size = sizeof(NETSCAPE_CERT_SEQUENCE),
.sname = "NETSCAPE_CERT_SEQUENCE",
};
NETSCAPE_CERT_SEQUENCE *
d2i_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE **a, const unsigned char **in, long len)
{
return (NETSCAPE_CERT_SEQUENCE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&NETSCAPE_CERT_SEQUENCE_it);
}
int
i2d_NETSCAPE_CERT_SEQUENCE(NETSCAPE_CERT_SEQUENCE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_CERT_SEQUENCE_it);
}
NETSCAPE_CERT_SEQUENCE *
NETSCAPE_CERT_SEQUENCE_new(void)
{
return (NETSCAPE_CERT_SEQUENCE *)ASN1_item_new(&NETSCAPE_CERT_SEQUENCE_it);
}
void
NETSCAPE_CERT_SEQUENCE_free(NETSCAPE_CERT_SEQUENCE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_CERT_SEQUENCE_it);
}

186
crypto/asn1/p5_pbe.c Normal file
View File

@ -0,0 +1,186 @@
/* $OpenBSD: p5_pbe.c,v 1.22 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509.h>
/* PKCS#5 password based encryption structure */
static const ASN1_TEMPLATE PBEPARAM_seq_tt[] = {
{
.offset = offsetof(PBEPARAM, salt),
.field_name = "salt",
.item = &ASN1_OCTET_STRING_it,
},
{
.offset = offsetof(PBEPARAM, iter),
.field_name = "iter",
.item = &ASN1_INTEGER_it,
},
};
const ASN1_ITEM PBEPARAM_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PBEPARAM_seq_tt,
.tcount = sizeof(PBEPARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(PBEPARAM),
.sname = "PBEPARAM",
};
PBEPARAM *
d2i_PBEPARAM(PBEPARAM **a, const unsigned char **in, long len)
{
return (PBEPARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PBEPARAM_it);
}
int
i2d_PBEPARAM(PBEPARAM *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBEPARAM_it);
}
PBEPARAM *
PBEPARAM_new(void)
{
return (PBEPARAM *)ASN1_item_new(&PBEPARAM_it);
}
void
PBEPARAM_free(PBEPARAM *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PBEPARAM_it);
}
/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
int
PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
const unsigned char *salt, int saltlen)
{
PBEPARAM *pbe = NULL;
ASN1_STRING *pbe_str = NULL;
unsigned char *sstr;
pbe = PBEPARAM_new();
if (!pbe) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if (!ASN1_INTEGER_set(pbe->iter, iter)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
sstr = ASN1_STRING_data(pbe->salt);
if (salt)
memcpy(sstr, salt, saltlen);
else
arc4random_buf(sstr, saltlen);
if (!ASN1_item_pack(pbe, &PBEPARAM_it, &pbe_str)) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
PBEPARAM_free(pbe);
pbe = NULL;
if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
return 1;
err:
if (pbe != NULL)
PBEPARAM_free(pbe);
ASN1_STRING_free(pbe_str);
return 0;
}
/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
X509_ALGOR *
PKCS5_pbe_set(int alg, int iter, const unsigned char *salt, int saltlen)
{
X509_ALGOR *ret;
ret = X509_ALGOR_new();
if (!ret) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
return ret;
X509_ALGOR_free(ret);
return NULL;
}

372
crypto/asn1/p5_pbev2.c Normal file
View File

@ -0,0 +1,372 @@
/* $OpenBSD: p5_pbev2.c,v 1.25 2017/01/29 17:49:22 beck 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 <stdlib.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509.h>
/* PKCS#5 v2.0 password based encryption structures */
static const ASN1_TEMPLATE PBE2PARAM_seq_tt[] = {
{
.offset = offsetof(PBE2PARAM, keyfunc),
.field_name = "keyfunc",
.item = &X509_ALGOR_it,
},
{
.offset = offsetof(PBE2PARAM, encryption),
.field_name = "encryption",
.item = &X509_ALGOR_it,
},
};
const ASN1_ITEM PBE2PARAM_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PBE2PARAM_seq_tt,
.tcount = sizeof(PBE2PARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(PBE2PARAM),
.sname = "PBE2PARAM",
};
PBE2PARAM *
d2i_PBE2PARAM(PBE2PARAM **a, const unsigned char **in, long len)
{
return (PBE2PARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PBE2PARAM_it);
}
int
i2d_PBE2PARAM(PBE2PARAM *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBE2PARAM_it);
}
PBE2PARAM *
PBE2PARAM_new(void)
{
return (PBE2PARAM *)ASN1_item_new(&PBE2PARAM_it);
}
void
PBE2PARAM_free(PBE2PARAM *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PBE2PARAM_it);
}
static const ASN1_TEMPLATE PBKDF2PARAM_seq_tt[] = {
{
.offset = offsetof(PBKDF2PARAM, salt),
.field_name = "salt",
.item = &ASN1_ANY_it,
},
{
.offset = offsetof(PBKDF2PARAM, iter),
.field_name = "iter",
.item = &ASN1_INTEGER_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(PBKDF2PARAM, keylength),
.field_name = "keylength",
.item = &ASN1_INTEGER_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(PBKDF2PARAM, prf),
.field_name = "prf",
.item = &X509_ALGOR_it,
},
};
const ASN1_ITEM PBKDF2PARAM_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PBKDF2PARAM_seq_tt,
.tcount = sizeof(PBKDF2PARAM_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(PBKDF2PARAM),
.sname = "PBKDF2PARAM",
};
PBKDF2PARAM *
d2i_PBKDF2PARAM(PBKDF2PARAM **a, const unsigned char **in, long len)
{
return (PBKDF2PARAM *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PBKDF2PARAM_it);
}
int
i2d_PBKDF2PARAM(PBKDF2PARAM *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PBKDF2PARAM_it);
}
PBKDF2PARAM *
PBKDF2PARAM_new(void)
{
return (PBKDF2PARAM *)ASN1_item_new(&PBKDF2PARAM_it);
}
void
PBKDF2PARAM_free(PBKDF2PARAM *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PBKDF2PARAM_it);
}
/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
* yes I know this is horrible!
*
* Extended version to allow application supplied PRF NID and IV.
*/
X509_ALGOR *
PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
int saltlen, unsigned char *aiv, int prf_nid)
{
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
int alg_nid, keylen;
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
PBE2PARAM *pbe2 = NULL;
ASN1_OBJECT *obj;
alg_nid = EVP_CIPHER_type(cipher);
if (alg_nid == NID_undef) {
ASN1error(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
obj = OBJ_nid2obj(alg_nid);
if (!(pbe2 = PBE2PARAM_new()))
goto merr;
/* Setup the AlgorithmIdentifier for the encryption scheme */
scheme = pbe2->encryption;
scheme->algorithm = obj;
if (!(scheme->parameter = ASN1_TYPE_new()))
goto merr;
/* Create random IV */
if (EVP_CIPHER_iv_length(cipher)) {
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
else
arc4random_buf(iv, EVP_CIPHER_iv_length(cipher));
}
EVP_CIPHER_CTX_init(&ctx);
/* Dummy cipherinit to just setup the IV, and PRF */
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
goto err;
if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
ASN1error(ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
EVP_CIPHER_CTX_cleanup(&ctx);
goto err;
}
/* If prf NID unspecified see if cipher has a preference.
* An error is OK here: just means use default PRF.
*/
if ((prf_nid == -1) &&
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
ERR_clear_error();
prf_nid = NID_hmacWithSHA1;
}
EVP_CIPHER_CTX_cleanup(&ctx);
/* If its RC2 then we'd better setup the key length */
if (alg_nid == NID_rc2_cbc)
keylen = EVP_CIPHER_key_length(cipher);
else
keylen = -1;
/* Setup keyfunc */
X509_ALGOR_free(pbe2->keyfunc);
pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
if (!pbe2->keyfunc)
goto merr;
/* Now set up top level AlgorithmIdentifier */
if (!(ret = X509_ALGOR_new()))
goto merr;
if (!(ret->parameter = ASN1_TYPE_new()))
goto merr;
ret->algorithm = OBJ_nid2obj(NID_pbes2);
/* Encode PBE2PARAM into parameter */
if (!ASN1_item_pack(pbe2, &PBE2PARAM_it,
&ret->parameter->value.sequence)) goto merr;
ret->parameter->type = V_ASN1_SEQUENCE;
PBE2PARAM_free(pbe2);
pbe2 = NULL;
return ret;
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
X509_ALGOR_free(kalg);
X509_ALGOR_free(ret);
return NULL;
}
X509_ALGOR *
PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
int saltlen)
{
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
}
X509_ALGOR *
PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid,
int keylen)
{
X509_ALGOR *keyfunc = NULL;
PBKDF2PARAM *kdf = NULL;
ASN1_OCTET_STRING *osalt = NULL;
if (!(kdf = PBKDF2PARAM_new()))
goto merr;
if (!(osalt = ASN1_OCTET_STRING_new()))
goto merr;
kdf->salt->value.octet_string = osalt;
kdf->salt->type = V_ASN1_OCTET_STRING;
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!(osalt->data = malloc (saltlen)))
goto merr;
osalt->length = saltlen;
if (salt)
memcpy (osalt->data, salt, saltlen);
else
arc4random_buf(osalt->data, saltlen);
if (iter <= 0)
iter = PKCS5_DEFAULT_ITER;
if (!ASN1_INTEGER_set(kdf->iter, iter))
goto merr;
/* If have a key len set it up */
if (keylen > 0) {
if (!(kdf->keylength = ASN1_INTEGER_new()))
goto merr;
if (!ASN1_INTEGER_set(kdf->keylength, keylen))
goto merr;
}
/* prf can stay NULL if we are using hmacWithSHA1 */
if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
kdf->prf = X509_ALGOR_new();
if (!kdf->prf)
goto merr;
X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
V_ASN1_NULL, NULL);
}
/* Finally setup the keyfunc structure */
keyfunc = X509_ALGOR_new();
if (!keyfunc)
goto merr;
keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
/* Encode PBKDF2PARAM into parameter of pbe2 */
if (!(keyfunc->parameter = ASN1_TYPE_new()))
goto merr;
if (!ASN1_item_pack(kdf, &PBKDF2PARAM_it,
&keyfunc->parameter->value.sequence))
goto merr;
keyfunc->parameter->type = V_ASN1_SEQUENCE;
PBKDF2PARAM_free(kdf);
return keyfunc;
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);
return NULL;
}

201
crypto/asn1/p8_pkey.c Normal file
View File

@ -0,0 +1,201 @@
/* $OpenBSD: p8_pkey.c,v 1.17 2015/09/10 15:56:25 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* 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
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/x509.h>
/* Minor tweak to operation: zero private key data */
static int
pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
{
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
if (operation == ASN1_OP_FREE_PRE) {
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
if (key->pkey != NULL &&
key->pkey->type == V_ASN1_OCTET_STRING &&
key->pkey->value.octet_string != NULL)
explicit_bzero(key->pkey->value.octet_string->data,
key->pkey->value.octet_string->length);
}
return 1;
}
static const ASN1_AUX PKCS8_PRIV_KEY_INFO_aux = {
.asn1_cb = pkey_cb,
};
static const ASN1_TEMPLATE PKCS8_PRIV_KEY_INFO_seq_tt[] = {
{
.offset = offsetof(PKCS8_PRIV_KEY_INFO, version),
.field_name = "version",
.item = &ASN1_INTEGER_it,
},
{
.offset = offsetof(PKCS8_PRIV_KEY_INFO, pkeyalg),
.field_name = "pkeyalg",
.item = &X509_ALGOR_it,
},
{
.offset = offsetof(PKCS8_PRIV_KEY_INFO, pkey),
.field_name = "pkey",
.item = &ASN1_ANY_it,
},
{
.flags = ASN1_TFLG_IMPLICIT | ASN1_TFLG_SET_OF | ASN1_TFLG_OPTIONAL,
.offset = offsetof(PKCS8_PRIV_KEY_INFO, attributes),
.field_name = "attributes",
.item = &X509_ATTRIBUTE_it,
},
};
const ASN1_ITEM PKCS8_PRIV_KEY_INFO_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = PKCS8_PRIV_KEY_INFO_seq_tt,
.tcount = sizeof(PKCS8_PRIV_KEY_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = &PKCS8_PRIV_KEY_INFO_aux,
.size = sizeof(PKCS8_PRIV_KEY_INFO),
.sname = "PKCS8_PRIV_KEY_INFO",
};
PKCS8_PRIV_KEY_INFO *
d2i_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO **a, const unsigned char **in, long len)
{
return (PKCS8_PRIV_KEY_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&PKCS8_PRIV_KEY_INFO_it);
}
int
i2d_PKCS8_PRIV_KEY_INFO(PKCS8_PRIV_KEY_INFO *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &PKCS8_PRIV_KEY_INFO_it);
}
PKCS8_PRIV_KEY_INFO *
PKCS8_PRIV_KEY_INFO_new(void)
{
return (PKCS8_PRIV_KEY_INFO *)ASN1_item_new(&PKCS8_PRIV_KEY_INFO_it);
}
void
PKCS8_PRIV_KEY_INFO_free(PKCS8_PRIV_KEY_INFO *a)
{
ASN1_item_free((ASN1_VALUE *)a, &PKCS8_PRIV_KEY_INFO_it);
}
int
PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version,
int ptype, void *pval, unsigned char *penc, int penclen)
{
unsigned char **ppenc = NULL;
if (version >= 0) {
if (!ASN1_INTEGER_set(priv->version, version))
return 0;
}
if (penc) {
int pmtype;
ASN1_OCTET_STRING *oct;
oct = ASN1_OCTET_STRING_new();
if (!oct)
return 0;
oct->data = penc;
ppenc = &oct->data;
oct->length = penclen;
if (priv->broken == PKCS8_NO_OCTET)
pmtype = V_ASN1_SEQUENCE;
else
pmtype = V_ASN1_OCTET_STRING;
ASN1_TYPE_set(priv->pkey, pmtype, oct);
}
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
/* If call fails do not swallow 'enc' */
if (ppenc)
*ppenc = NULL;
return 0;
}
return 1;
}
int
PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen,
X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8)
{
if (ppkalg)
*ppkalg = p8->pkeyalg->algorithm;
if (p8->pkey->type == V_ASN1_OCTET_STRING) {
p8->broken = PKCS8_OK;
if (pk) {
*pk = p8->pkey->value.octet_string->data;
*ppklen = p8->pkey->value.octet_string->length;
}
} else if (p8->pkey->type == V_ASN1_SEQUENCE) {
p8->broken = PKCS8_NO_OCTET;
if (pk) {
*pk = p8->pkey->value.sequence->data;
*ppklen = p8->pkey->value.sequence->length;
}
} else
return 0;
if (pa)
*pa = p8->pkeyalg;
return 1;
}

112
crypto/asn1/t_bitst.c Normal file
View File

@ -0,0 +1,112 @@
/* $OpenBSD: t_bitst.c,v 1.7 2014/07/11 08:44:47 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <string.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
int
ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
BIT_STRING_BITNAME *tbl, int indent)
{
BIT_STRING_BITNAME *bnam;
char first = 1;
BIO_printf(out, "%*s", indent, "");
for (bnam = tbl; bnam->lname; bnam++) {
if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
if (!first)
BIO_puts(out, ", ");
BIO_puts(out, bnam->lname);
first = 0;
}
}
BIO_puts(out, "\n");
return 1;
}
int
ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
BIT_STRING_BITNAME *tbl)
{
int bitnum;
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
if (bitnum < 0)
return 0;
if (bs) {
if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
return 0;
}
return 1;
}
int
ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
{
BIT_STRING_BITNAME *bnam;
for (bnam = tbl; bnam->lname; bnam++) {
if (!strcmp(bnam->sname, name) ||
!strcmp(bnam->lname, name))
return bnam->bitnum;
}
return -1;
}

140
crypto/asn1/t_crl.c Normal file
View File

@ -0,0 +1,140 @@
/* $OpenBSD: t_crl.c,v 1.17 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
int
X509_CRL_print_fp(FILE *fp, X509_CRL *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
X509error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = X509_CRL_print(b, x);
BIO_free(b);
return (ret);
}
int
X509_CRL_print(BIO *out, X509_CRL *x)
{
STACK_OF(X509_REVOKED) *rev;
X509_REVOKED *r;
long l;
int i;
char *p;
BIO_printf(out, "Certificate Revocation List (CRL):\n");
l = X509_CRL_get_version(x);
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
i = OBJ_obj2nid(x->sig_alg->algorithm);
if (X509_signature_print(out, x->sig_alg, NULL) == 0)
goto err;
p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
if (p == NULL)
goto err;
BIO_printf(out, "%8sIssuer: %s\n", "", p);
free(p);
BIO_printf(out, "%8sLast Update: ", "");
ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
BIO_printf(out, "\n%8sNext Update: ", "");
if (X509_CRL_get_nextUpdate(x))
ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
else
BIO_printf(out, "NONE");
BIO_printf(out, "\n");
X509V3_extensions_print(out, "CRL extensions",
x->crl->extensions, 0, 8);
rev = X509_CRL_get_REVOKED(x);
if (sk_X509_REVOKED_num(rev) > 0)
BIO_printf(out, "Revoked Certificates:\n");
else
BIO_printf(out, "No Revoked Certificates.\n");
for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
r = sk_X509_REVOKED_value(rev, i);
BIO_printf(out, " Serial Number: ");
i2a_ASN1_INTEGER(out, r->serialNumber);
BIO_printf(out, "\n Revocation Date: ");
ASN1_TIME_print(out, r->revocationDate);
BIO_printf(out, "\n");
X509V3_extensions_print(out, "CRL entry extensions",
r->extensions, 0, 8);
}
if (X509_signature_print(out, x->sig_alg, x->signature) == 0)
goto err;
return 1;
err:
return 0;
}

114
crypto/asn1/t_pkey.c Normal file
View File

@ -0,0 +1,114 @@
/* $OpenBSD: t_pkey.c,v 1.16 2014/07/11 08:44:47 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.]
*/
#include <stdio.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/objects.h>
int
ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)
{
int n, i;
const char *neg;
if (num == NULL)
return (1);
neg = (BN_is_negative(num)) ? "-" : "";
if (!BIO_indent(bp, off, 128))
return 0;
if (BN_is_zero(num)) {
if (BIO_printf(bp, "%s 0\n", number) <= 0)
return 0;
return 1;
}
if (BN_num_bytes(num) <= BN_BYTES) {
if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
(unsigned long)num->d[0], neg,
(unsigned long)num->d[0]) <= 0)
return (0);
} else {
buf[0] = 0;
if (BIO_printf(bp, "%s%s", number,
(neg[0] == '-') ? " (Negative)" : "") <= 0)
return (0);
n = BN_bn2bin(num, &buf[1]);
if (buf[1] & 0x80)
n++;
else
buf++;
for (i = 0; i < n; i++) {
if ((i % 15) == 0) {
if (BIO_puts(bp, "\n") <= 0 ||
!BIO_indent(bp, off + 4, 128))
return 0;
}
if (BIO_printf(bp, "%02x%s", buf[i],
((i + 1) == n) ? "" : ":") <= 0)
return (0);
}
if (BIO_write(bp, "\n", 1) <= 0)
return (0);
}
return (1);
}

267
crypto/asn1/t_req.c Normal file
View File

@ -0,0 +1,267 @@
/* $OpenBSD: t_req.c,v 1.19 2017/01/29 17:49:22 beck 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 <openssl/opensslconf.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
int
X509_REQ_print_fp(FILE *fp, X509_REQ *x)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
X509error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = X509_REQ_print(b, x);
BIO_free(b);
return (ret);
}
int
X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
unsigned long cflag)
{
unsigned long l;
int i;
const char *neg;
X509_REQ_INFO *ri;
EVP_PKEY *pkey;
STACK_OF(X509_ATTRIBUTE) *sk;
STACK_OF(X509_EXTENSION) *exts;
char mlch = ' ';
int nmindent = 0;
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
nmindent = 12;
}
if (nmflags == X509_FLAG_COMPAT)
nmindent = 16;
ri = x->req_info;
if (!(cflag & X509_FLAG_NO_HEADER)) {
if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
goto err;
if (BIO_write(bp, " Data:\n", 10) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_VERSION)) {
neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
l = 0;
for (i = 0; i < ri->version->length; i++) {
l <<= 8;
l += ri->version->data[i];
}
if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg,
l, neg, l) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_SUBJECT)) {
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_PUBKEY)) {
if (BIO_write(bp, " Subject Public Key Info:\n",
33) <= 0)
goto err;
if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
goto err;
if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
pkey = X509_REQ_get_pubkey(x);
if (pkey == NULL) {
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bp);
} else {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
}
}
if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
/* may not be */
if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
goto err;
sk = x->req_info->attributes;
if (sk_X509_ATTRIBUTE_num(sk) == 0) {
if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
goto err;
} else {
for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
ASN1_TYPE *at;
X509_ATTRIBUTE *a;
ASN1_BIT_STRING *bs = NULL;
ASN1_TYPE *t;
int j, type = 0, count = 1, ii = 0;
a = sk_X509_ATTRIBUTE_value(sk, i);
if (X509_REQ_extension_nid(
OBJ_obj2nid(a->object)))
continue;
if (BIO_printf(bp, "%12s", "") <= 0)
goto err;
if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) {
if (a->single) {
t = a->value.single;
type = t->type;
bs = t->value.bit_string;
} else {
ii = 0;
count = sk_ASN1_TYPE_num(
a->value.set);
get_next:
at = sk_ASN1_TYPE_value(
a->value.set, ii);
type = at->type;
bs = at->value.asn1_string;
}
}
for (j = 25 - j; j > 0; j--)
if (BIO_write(bp, " ", 1) != 1)
goto err;
if (BIO_puts(bp, ":") <= 0)
goto err;
if ((type == V_ASN1_PRINTABLESTRING) ||
(type == V_ASN1_T61STRING) ||
(type == V_ASN1_IA5STRING)) {
if (BIO_write(bp, (char *)bs->data,
bs->length) != bs->length)
goto err;
BIO_puts(bp, "\n");
} else {
BIO_puts(bp,
"unable to print attribute\n");
}
if (++ii < count)
goto get_next;
}
}
}
if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
exts = X509_REQ_get_extensions(x);
if (exts) {
BIO_printf(bp, "%8sRequested Extensions:\n", "");
for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
ASN1_OBJECT *obj;
X509_EXTENSION *ex;
int j;
ex = sk_X509_EXTENSION_value(exts, i);
if (BIO_printf(bp, "%12s", "") <= 0)
goto err;
obj = X509_EXTENSION_get_object(ex);
i2a_ASN1_OBJECT(bp, obj);
j = X509_EXTENSION_get_critical(ex);
if (BIO_printf(bp, ": %s\n",
j ? "critical" : "") <= 0)
goto err;
if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
BIO_printf(bp, "%16s", "");
ASN1_STRING_print(bp, ex->value);
}
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
}
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
}
}
if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
if (!X509_signature_print(bp, x->sig_alg, x->signature))
goto err;
}
return (1);
err:
X509error(ERR_R_BUF_LIB);
return (0);
}
int
X509_REQ_print(BIO *bp, X509_REQ *x)
{
return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}

112
crypto/asn1/t_spki.c Normal file
View File

@ -0,0 +1,112 @@
/* $OpenBSD: t_spki.c,v 1.11 2014/07/11 08:44:47 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/opensslconf.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/x509.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
/* Print out an SPKI */
int
NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
{
EVP_PKEY *pkey;
ASN1_IA5STRING *chal;
int i, n;
char *s;
BIO_printf(out, "Netscape SPKI:\n");
i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
BIO_printf(out, " Public Key Algorithm: %s\n",
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
if (!pkey)
BIO_printf(out, " Unable to load public key\n");
else {
EVP_PKEY_print_public(out, pkey, 4, NULL);
EVP_PKEY_free(pkey);
}
chal = spki->spkac->challenge;
if (chal->length)
BIO_printf(out, " Challenge String: %s\n", chal->data);
i = OBJ_obj2nid(spki->sig_algor->algorithm);
BIO_printf(out, " Signature Algorithm: %s",
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
n = spki->signature->length;
s = (char *)spki->signature->data;
for (i = 0; i < n; i++) {
if ((i % 18) == 0)
BIO_write(out, "\n ", 7);
BIO_printf(out, "%02x%s", (unsigned char)s[i],
((i + 1) == n) ? "" : ":");
}
BIO_write(out, "\n", 1);
return 1;
}

537
crypto/asn1/t_x509.c Normal file
View File

@ -0,0 +1,537 @@
/* $OpenBSD: t_x509.c,v 1.28 2017/04/03 15:52:59 beck 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 <openssl/opensslconf.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_DSA
#include <openssl/dsa.h>
#endif
#ifndef OPENSSL_NO_EC
#include <openssl/ec.h>
#endif
#ifndef OPENSSL_NO_RSA
#include <openssl/rsa.h>
#endif
#include "asn1_locl.h"
int
X509_print_fp(FILE *fp, X509 *x)
{
return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}
int
X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
{
BIO *b;
int ret;
if ((b = BIO_new(BIO_s_file())) == NULL) {
X509error(ERR_R_BUF_LIB);
return (0);
}
BIO_set_fp(b, fp, BIO_NOCLOSE);
ret = X509_print_ex(b, x, nmflag, cflag);
BIO_free(b);
return (ret);
}
int
X509_print(BIO *bp, X509 *x)
{
return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
}
int
X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
{
long l;
int ret = 0, i;
char *m = NULL, mlch = ' ';
int nmindent = 0;
X509_CINF *ci;
ASN1_INTEGER *bs;
EVP_PKEY *pkey = NULL;
const char *neg;
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
mlch = '\n';
nmindent = 12;
}
if (nmflags == X509_FLAG_COMPAT)
nmindent = 16;
ci = x->cert_info;
if (!(cflag & X509_FLAG_NO_HEADER)) {
if (BIO_write(bp, "Certificate:\n", 13) <= 0)
goto err;
if (BIO_write(bp, " Data:\n", 10) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_VERSION)) {
l = X509_get_version(x);
if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n",
"", l + 1, l) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_SERIAL)) {
if (BIO_write(bp, " Serial Number:", 22) <= 0)
goto err;
bs = X509_get_serialNumber(x);
if (bs->length <= (int)sizeof(long)) {
l = ASN1_INTEGER_get(bs);
if (bs->type == V_ASN1_NEG_INTEGER) {
l = -l;
neg = "-";
} else
neg = "";
if (BIO_printf(bp, " %s%lu (%s0x%lx)\n",
neg, l, neg, l) <= 0)
goto err;
} else {
neg = (bs->type == V_ASN1_NEG_INTEGER) ?
" (Negative)" : "";
if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
goto err;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02x%c", bs->data[i],
((i + 1 == bs->length) ? '\n' : ':')) <= 0)
goto err;
}
}
}
if (!(cflag & X509_FLAG_NO_SIGNAME)) {
if (X509_signature_print(bp, x->sig_alg, NULL) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_ISSUER)) {
if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_issuer_name(x),
nmindent, nmflags) < 0)
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_VALIDITY)) {
if (BIO_write(bp, " Validity\n", 17) <= 0)
goto err;
if (BIO_write(bp, " Not Before: ", 24) <= 0)
goto err;
if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
goto err;
if (BIO_write(bp, "\n Not After : ", 25) <= 0)
goto err;
if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_SUBJECT)) {
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_subject_name(x),
nmindent, nmflags) < 0)
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_PUBKEY)) {
if (BIO_write(bp, " Subject Public Key Info:\n",
33) <= 0)
goto err;
if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
goto err;
if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
goto err;
if (BIO_puts(bp, "\n") <= 0)
goto err;
pkey = X509_get_pubkey(x);
if (pkey == NULL) {
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
ERR_print_errors(bp);
} else {
EVP_PKEY_print_public(bp, pkey, 16, NULL);
EVP_PKEY_free(pkey);
}
}
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
X509V3_extensions_print(bp, "X509v3 extensions",
ci->extensions, cflag, 8);
if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
goto err;
}
if (!(cflag & X509_FLAG_NO_AUX)) {
if (!X509_CERT_AUX_print(bp, x->aux, 0))
goto err;
}
ret = 1;
err:
free(m);
return (ret);
}
int X509_ocspid_print (BIO *bp, X509 *x)
{
unsigned char *der = NULL;
unsigned char *dertmp;
int derlen;
int i;
unsigned char SHA1md[SHA_DIGEST_LENGTH];
/* display the hash of the subject as it would appear
in OCSP requests */
if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
goto err;
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
if ((der = dertmp = malloc(derlen)) == NULL)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
goto err;
}
free (der);
der = NULL;
/* display the hash of the public key as it would appear
in OCSP requests */
if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
goto err;
if (!EVP_Digest(x->cert_info->key->public_key->data,
x->cert_info->key->public_key->length,
SHA1md, NULL, EVP_sha1(), NULL))
goto err;
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
goto err;
}
BIO_printf(bp, "\n");
return (1);
err:
free(der);
return (0);
}
int
X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
{
const unsigned char *s;
int i, n;
n = sig->length;
s = sig->data;
for (i = 0; i < n; i++) {
if ((i % 18) == 0) {
if (BIO_write(bp, "\n", 1) <= 0)
return 0;
if (BIO_indent(bp, indent, indent) <= 0)
return 0;
}
if (BIO_printf(bp, "%02x%s", s[i],
((i + 1) == n) ? "" : ":") <= 0)
return 0;
}
if (BIO_write(bp, "\n", 1) != 1)
return 0;
return 1;
}
int
X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
{
int sig_nid;
if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
return 0;
if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
return 0;
sig_nid = OBJ_obj2nid(sigalg->algorithm);
if (sig_nid != NID_undef) {
int pkey_nid, dig_nid;
const EVP_PKEY_ASN1_METHOD *ameth;
if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
if (ameth && ameth->sig_print)
return ameth->sig_print(bp, sigalg, sig, 9, 0);
}
}
if (sig)
return X509_signature_dump(bp, sig, 9);
else if (BIO_puts(bp, "\n") <= 0)
return 0;
return 1;
}
int
ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
{
int i, n;
char buf[80];
const char *p;
if (v == NULL)
return (0);
n = 0;
p = (const char *)v->data;
for (i = 0; i < v->length; i++) {
if ((p[i] > '~') || ((p[i] < ' ') &&
(p[i] != '\n') && (p[i] != '\r')))
buf[n] = '.';
else
buf[n] = p[i];
n++;
if (n >= 80) {
if (BIO_write(bp, buf, n) <= 0)
return (0);
n = 0;
}
}
if (n > 0)
if (BIO_write(bp, buf, n) <= 0)
return (0);
return (1);
}
int
ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
{
if (tm->type == V_ASN1_UTCTIME)
return ASN1_UTCTIME_print(bp, tm);
if (tm->type == V_ASN1_GENERALIZEDTIME)
return ASN1_GENERALIZEDTIME_print(bp, tm);
BIO_write(bp, "Bad time value", 14);
return (0);
}
static const char *mon[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
int
ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
{
char *v;
int gmt = 0;
int i;
int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
char *f = "";
int f_len = 0;
i = tm->length;
v = (char *)tm->data;
if (i < 12)
goto err;
if (v[i-1] == 'Z')
gmt = 1;
for (i = 0; i < 12; i++)
if ((v[i] > '9') || (v[i] < '0'))
goto err;
y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 +
(v[2] - '0') * 10 + (v[3] - '0');
M = (v[4] - '0') * 10 + (v[5] - '0');
if ((M > 12) || (M < 1))
goto err;
d = (v[6] - '0') * 10 + (v[7] - '0');
h = (v[8] - '0') * 10 + (v[9] - '0');
m = (v[10] - '0') * 10 + (v[11] - '0');
if (tm->length >= 14 &&
(v[12] >= '0') && (v[12] <= '9') &&
(v[13] >= '0') && (v[13] <= '9')) {
s = (v[12] - '0') * 10 + (v[13] - '0');
/* Check for fractions of seconds. */
if (tm->length >= 15 && v[14] == '.') {
int l = tm->length;
f = &v[14]; /* The decimal point. */
f_len = 1;
while (14 + f_len < l && f[f_len] >= '0' &&
f[f_len] <= '9')
++f_len;
}
}
if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
mon[M - 1], d, h, m, s, f_len, f, y, (gmt) ? " GMT" : "") <= 0)
return (0);
else
return (1);
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
int
ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
{
const char *v;
int gmt = 0;
int i;
int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
i = tm->length;
v = (const char *)tm->data;
if (i < 10)
goto err;
if (v[i-1] == 'Z')
gmt = 1;
for (i = 0; i < 10; i++)
if ((v[i] > '9') || (v[i] < '0'))
goto err;
y = (v[0] - '0') * 10 + (v[1] - '0');
if (y < 50)
y += 100;
M = (v[2] - '0') * 10 + (v[3] - '0');
if ((M > 12) || (M < 1))
goto err;
d = (v[4] - '0') * 10 + (v[5] - '0');
h = (v[6] - '0') * 10 + (v[7] - '0');
m = (v[8] - '0') * 10 + (v[9] - '0');
if (tm->length >=12 &&
(v[10] >= '0') && (v[10] <= '9') &&
(v[11] >= '0') && (v[11] <= '9'))
s = (v[10] - '0') * 10 + (v[11] - '0');
if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
mon[M - 1], d, h, m, s, y + 1900, (gmt) ? " GMT" : "") <= 0)
return (0);
else
return (1);
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
int
X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
{
char *s, *c, *b;
int ret = 0, l, i;
l = 80 - 2 - obase;
b = X509_NAME_oneline(name, NULL, 0);
if (b == NULL)
return 0;
if (*b == '\0') {
free(b);
return 1;
}
s = b + 1; /* skip the first slash */
c = s;
for (;;) {
if (((*s == '/') &&
((s[1] >= 'A') && (s[1] <= 'Z') &&
((s[2] == '=') || ((s[2] >= 'A') && (s[2] <= 'Z') &&
(s[3] == '='))))) || (*s == '\0')) {
i = s - c;
if (BIO_write(bp, c, i) != i)
goto err;
c = s + 1; /* skip following slash */
if (*s != '\0') {
if (BIO_write(bp, ", ", 2) != 2)
goto err;
}
l--;
}
if (*s == '\0')
break;
s++;
l--;
}
ret = 1;
if (0) {
err:
X509error(ERR_R_BUF_LIB);
}
free(b);
return (ret);
}

118
crypto/asn1/t_x509a.c Normal file
View File

@ -0,0 +1,118 @@
/* $OpenBSD: t_x509a.c,v 1.8 2014/07/11 08:44:47 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
/* X509_CERT_AUX and string set routines
*/
int
X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
{
char oidstr[80], first;
int i;
if (!aux)
return 1;
if (aux->trust) {
first = 1;
BIO_printf(out, "%*sTrusted Uses:\n%*s",
indent, "", indent + 2, "");
for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
if (!first)
BIO_puts(out, ", ");
else
first = 0;
OBJ_obj2txt(oidstr, sizeof oidstr,
sk_ASN1_OBJECT_value(aux->trust, i), 0);
BIO_puts(out, oidstr);
}
BIO_puts(out, "\n");
} else
BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
if (aux->reject) {
first = 1;
BIO_printf(out, "%*sRejected Uses:\n%*s",
indent, "", indent + 2, "");
for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
if (!first)
BIO_puts(out, ", ");
else
first = 0;
OBJ_obj2txt(oidstr, sizeof oidstr,
sk_ASN1_OBJECT_value(aux->reject, i), 0);
BIO_puts(out, oidstr);
}
BIO_puts(out, "\n");
} else
BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
if (aux->alias)
BIO_printf(out, "%*sAlias: %s\n", indent, "",
aux->alias->data);
if (aux->keyid) {
BIO_printf(out, "%*sKey Id: ", indent, "");
for (i = 0; i < aux->keyid->length; i++)
BIO_printf(out, "%s%02X", i ? ":" : "",
aux->keyid->data[i]);
BIO_write(out, "\n", 1);
}
return 1;
}

1148
crypto/asn1/tasn_dec.c Normal file

File diff suppressed because it is too large Load Diff

652
crypto/asn1/tasn_enc.c Normal file
View File

@ -0,0 +1,652 @@
/* $OpenBSD: tasn_enc.c,v 1.21 2016/12/30 16:04:34 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out,
int skcontlen, const ASN1_ITEM *item, int do_sort, int iclass);
static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt, int tag, int aclass);
static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out,
const ASN1_ITEM *it, int flags);
static int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
const ASN1_ITEM *it);
/* Top level i2d equivalents: the 'ndef' variant instructs the encoder
* to use indefinite length constructed encoding, where appropriate
*/
int
ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
{
return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF);
}
int
ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it)
{
return asn1_item_flags_i2d(val, out, it, 0);
}
/* Encode an ASN1 item, this is use by the
* standard 'i2d' function. 'out' points to
* a buffer to output the data to.
*
* The new i2d has one additional feature. If the output
* buffer is NULL (i.e. *out == NULL) then a buffer is
* allocated and populated with the encoding.
*/
static int
asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it,
int flags)
{
if (out && !*out) {
unsigned char *p, *buf;
int len;
len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
if (len <= 0)
return len;
buf = malloc(len);
if (!buf)
return -1;
p = buf;
ASN1_item_ex_i2d(&val, &p, it, -1, flags);
*out = buf;
return len;
}
return ASN1_item_ex_i2d(&val, out, it, -1, flags);
}
/* Encode an item, taking care of IMPLICIT tagging (if any).
* This function performs the normal item handling: it can be
* used in external types.
*/
int
ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
const ASN1_TEMPLATE *tt = NULL;
int i, seqcontlen, seqlen, ndef = 1;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb = NULL;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
return 0;
if (aux && aux->asn1_cb)
asn1_cb = aux->asn1_cb;
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
return asn1_template_ex_i2d(pval, out, it->templates,
tag, aclass);
return asn1_i2d_ex_primitive(pval, out, it, tag, aclass);
break;
case ASN1_ITYPE_MSTRING:
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount)) {
ASN1_VALUE **pchval;
const ASN1_TEMPLATE *chtt;
chtt = it->templates + i;
pchval = asn1_get_field_ptr(pval, chtt);
return asn1_template_ex_i2d(pchval, out, chtt,
-1, aclass);
}
/* Fixme: error condition if selector out of range */
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
break;
case ASN1_ITYPE_EXTERN:
/* If new style i2d it does all the work */
ef = it->funcs;
return ef->asn1_ex_i2d(pval, out, it, tag, aclass);
case ASN1_ITYPE_NDEF_SEQUENCE:
/* Use indefinite length constructed if requested */
if (aclass & ASN1_TFLG_NDEF)
ndef = 2;
/* fall through */
case ASN1_ITYPE_SEQUENCE:
i = asn1_enc_restore(&seqcontlen, out, pval, it);
/* An error occurred */
if (i < 0)
return 0;
/* We have a valid cached encoding... */
if (i > 0)
return seqcontlen;
/* Otherwise carry on */
seqcontlen = 0;
/* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */
if (tag == -1) {
tag = V_ASN1_SEQUENCE;
/* Retain any other flags in aclass */
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) |
V_ASN1_UNIVERSAL;
}
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
/* First work out sequence content length */
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
-1, aclass);
}
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
if (!out)
return seqlen;
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* FIXME: check for errors in enhanced version */
asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass);
}
if (ndef == 2)
ASN1_put_eoc(out);
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
return seqlen;
default:
return 0;
}
return 0;
}
int
ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt)
{
return asn1_template_ex_i2d(pval, out, tt, -1, 0);
}
static int
asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
const ASN1_TEMPLATE *tt, int tag, int iclass)
{
int i, ret, flags, ttag, tclass, ndef;
flags = tt->flags;
/* Work out tag and class to use: tagging may come
* either from the template or the arguments, not both
* because this would create ambiguity. Additionally
* the iclass argument may contain some additional flags
* which should be noted and passed down to other levels.
*/
if (flags & ASN1_TFLG_TAG_MASK) {
/* Error if argument and template tagging */
if (tag != -1)
/* FIXME: error code here */
return -1;
/* Get tagging from template */
ttag = tt->tag;
tclass = flags & ASN1_TFLG_TAG_CLASS;
} else if (tag != -1) {
/* No template tagging, get from arguments */
ttag = tag;
tclass = iclass & ASN1_TFLG_TAG_CLASS;
} else {
ttag = -1;
tclass = 0;
}
/*
* Remove any class mask from iflag.
*/
iclass &= ~ASN1_TFLG_TAG_CLASS;
/* At this point 'ttag' contains the outer tag to use,
* 'tclass' is the class and iclass is any flags passed
* to this function.
*/
/* if template and arguments require ndef, use it */
if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF))
ndef = 2;
else
ndef = 1;
if (flags & ASN1_TFLG_SK_MASK) {
/* SET OF, SEQUENCE OF */
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
int isset, sktag, skaclass;
int skcontlen, sklen;
ASN1_VALUE *skitem;
if (!*pval)
return 0;
if (flags & ASN1_TFLG_SET_OF) {
isset = 1;
/* 2 means we reorder */
if (flags & ASN1_TFLG_SEQUENCE_OF)
isset = 2;
} else
isset = 0;
/* Work out inner tag value: if EXPLICIT
* or no tagging use underlying type.
*/
if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) {
sktag = ttag;
skaclass = tclass;
} else {
skaclass = V_ASN1_UNIVERSAL;
if (isset)
sktag = V_ASN1_SET;
else
sktag = V_ASN1_SEQUENCE;
}
/* Determine total length of items */
skcontlen = 0;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
skitem = sk_ASN1_VALUE_value(sk, i);
skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
tt->item, -1, iclass);
}
sklen = ASN1_object_size(ndef, skcontlen, sktag);
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
ret = ASN1_object_size(ndef, sklen, ttag);
else
ret = sklen;
if (!out)
return ret;
/* Now encode this lot... */
/* EXPLICIT tag */
if (flags & ASN1_TFLG_EXPTAG)
ASN1_put_object(out, ndef, sklen, ttag, tclass);
/* SET or SEQUENCE and IMPLICIT tag */
ASN1_put_object(out, ndef, skcontlen, sktag, skaclass);
/* And the stuff itself */
asn1_set_seq_out(sk, out, skcontlen, tt->item,
isset, iclass);
if (ndef == 2) {
ASN1_put_eoc(out);
if (flags & ASN1_TFLG_EXPTAG)
ASN1_put_eoc(out);
}
return ret;
}
if (flags & ASN1_TFLG_EXPTAG) {
/* EXPLICIT tagging */
/* Find length of tagged item */
i = ASN1_item_ex_i2d(pval, NULL, tt->item,
-1, iclass);
if (!i)
return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
if (out) {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, tt->item,
-1, iclass);
if (ndef == 2)
ASN1_put_eoc(out);
}
return ret;
}
/* Either normal or IMPLICIT tagging: combine class and flags */
return ASN1_item_ex_i2d(pval, out, tt->item,
ttag, tclass | iclass);
}
/* Temporary structure used to hold DER encoding of items for SET OF */
typedef struct {
unsigned char *data;
int length;
ASN1_VALUE *field;
} DER_ENC;
static int
der_cmp(const void *a, const void *b)
{
const DER_ENC *d1 = a, *d2 = b;
int cmplen, i;
cmplen = (d1->length < d2->length) ? d1->length : d2->length;
i = memcmp(d1->data, d2->data, cmplen);
if (i)
return i;
return d1->length - d2->length;
}
/* Output the content octets of SET OF or SEQUENCE OF */
static int
asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, int skcontlen,
const ASN1_ITEM *item, int do_sort, int iclass)
{
int i;
ASN1_VALUE *skitem;
unsigned char *tmpdat = NULL, *p = NULL;
DER_ENC *derlst = NULL, *tder;
if (do_sort) {
/* Don't need to sort less than 2 items */
if (sk_ASN1_VALUE_num(sk) < 2)
do_sort = 0;
else {
derlst = reallocarray(NULL, sk_ASN1_VALUE_num(sk),
sizeof(*derlst));
tmpdat = malloc(skcontlen);
if (!derlst || !tmpdat) {
free(derlst);
free(tmpdat);
return 0;
}
}
}
/* If not sorting just output each item */
if (!do_sort) {
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
skitem = sk_ASN1_VALUE_value(sk, i);
ASN1_item_ex_i2d(&skitem, out, item, -1, iclass);
}
return 1;
}
p = tmpdat;
/* Doing sort: build up a list of each member's DER encoding */
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
skitem = sk_ASN1_VALUE_value(sk, i);
tder->data = p;
tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass);
tder->field = skitem;
}
/* Now sort them */
qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp);
/* Output sorted DER encoding */
p = *out;
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) {
memcpy(p, tder->data, tder->length);
p += tder->length;
}
*out = p;
/* If do_sort is 2 then reorder the STACK */
if (do_sort == 2) {
for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++)
(void)sk_ASN1_VALUE_set(sk, i, tder->field);
}
free(derlst);
free(tmpdat);
return 1;
}
static int
asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass)
{
int len;
int utype;
int usetag;
int ndef = 0;
utype = it->utype;
/* Get length of content octets and maybe find
* out the underlying type.
*/
len = asn1_ex_i2c(pval, NULL, &utype, it);
/* If SEQUENCE, SET or OTHER then header is
* included in pseudo content octets so don't
* include tag+length. We need to check here
* because the call to asn1_ex_i2c() could change
* utype.
*/
if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) ||
(utype == V_ASN1_OTHER))
usetag = 0;
else
usetag = 1;
/* -1 means omit type */
if (len == -1)
return 0;
/* -2 return is special meaning use ndef */
if (len == -2) {
ndef = 2;
len = 0;
}
/* If not implicitly tagged get tag from underlying type */
if (tag == -1)
tag = utype;
/* Output tag+length followed by content octets */
if (out) {
if (usetag)
ASN1_put_object(out, ndef, len, tag, aclass);
asn1_ex_i2c(pval, *out, &utype, it);
if (ndef)
ASN1_put_eoc(out);
else
*out += len;
}
if (usetag)
return ASN1_object_size(ndef, len, tag);
return len;
}
/* Produce content octets from a structure */
static int
asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
const ASN1_ITEM *it)
{
ASN1_BOOLEAN *tbool = NULL;
ASN1_STRING *strtmp;
ASN1_OBJECT *otmp;
int utype;
const unsigned char *cont;
unsigned char c;
int len;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_i2c)
return pf->prim_i2c(pval, cout, putype, it);
/* Should type be omitted? */
if ((it->itype != ASN1_ITYPE_PRIMITIVE) ||
(it->utype != V_ASN1_BOOLEAN)) {
if (!*pval)
return -1;
}
if (it->itype == ASN1_ITYPE_MSTRING) {
/* If MSTRING type set the underlying type */
strtmp = (ASN1_STRING *)*pval;
utype = strtmp->type;
*putype = utype;
} else if (it->utype == V_ASN1_ANY) {
/* If ANY set type and pointer to value */
ASN1_TYPE *typ;
typ = (ASN1_TYPE *)*pval;
utype = typ->type;
*putype = utype;
pval = &typ->value.asn1_value;
} else
utype = *putype;
switch (utype) {
case V_ASN1_OBJECT:
otmp = (ASN1_OBJECT *)*pval;
cont = otmp->data;
len = otmp->length;
break;
case V_ASN1_NULL:
cont = NULL;
len = 0;
break;
case V_ASN1_BOOLEAN:
tbool = (ASN1_BOOLEAN *)pval;
if (*tbool == -1)
return -1;
if (it->utype != V_ASN1_ANY) {
/* Default handling if value == size field then omit */
if (*tbool && (it->size > 0))
return -1;
if (!*tbool && !it->size)
return -1;
}
c = (unsigned char)*tbool;
cont = &c;
len = 1;
break;
case V_ASN1_BIT_STRING:
return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval,
cout ? &cout : NULL);
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
/* These are all have the same content format
* as ASN1_INTEGER
*/
return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval,
cout ? &cout : NULL);
break;
case V_ASN1_OCTET_STRING:
case V_ASN1_NUMERICSTRING:
case V_ASN1_PRINTABLESTRING:
case V_ASN1_T61STRING:
case V_ASN1_VIDEOTEXSTRING:
case V_ASN1_IA5STRING:
case V_ASN1_UTCTIME:
case V_ASN1_GENERALIZEDTIME:
case V_ASN1_GRAPHICSTRING:
case V_ASN1_VISIBLESTRING:
case V_ASN1_GENERALSTRING:
case V_ASN1_UNIVERSALSTRING:
case V_ASN1_BMPSTRING:
case V_ASN1_UTF8STRING:
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
default:
/* All based on ASN1_STRING and handled the same */
strtmp = (ASN1_STRING *)*pval;
/* Special handling for NDEF */
if ((it->size == ASN1_TFLG_NDEF) &&
(strtmp->flags & ASN1_STRING_FLAG_NDEF)) {
if (cout) {
strtmp->data = cout;
strtmp->length = 0;
}
/* Special return code */
return -2;
}
cont = strtmp->data;
len = strtmp->length;
break;
}
if (cout && len)
memcpy(cout, cont, len);
return len;
}

243
crypto/asn1/tasn_fre.c Normal file
View File

@ -0,0 +1,243 @@
/* $OpenBSD: tasn_fre.c,v 1.15 2016/12/30 16:04:34 jsing 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 <stddef.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
/* Free up an ASN1 structure */
void
ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
{
asn1_item_combine_free(&val, it, 0);
}
void
ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
asn1_item_combine_free(pval, it, 0);
}
static void
asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
{
const ASN1_TEMPLATE *tt = NULL, *seqtt;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb = NULL;
int i;
if (pval == NULL || *pval == NULL)
return;
if (aux != NULL && aux->asn1_cb != NULL)
asn1_cb = aux->asn1_cb;
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
ASN1_template_free(pval, it->templates);
else
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_MSTRING:
ASN1_primitive_free(pval, it);
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
i = asn1_get_choice_selector(pval, it);
if ((i >= 0) && (i < it->tcount)) {
ASN1_VALUE **pchval;
tt = it->templates + i;
pchval = asn1_get_field_ptr(pval, tt);
ASN1_template_free(pchval, tt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
free(*pval);
*pval = NULL;
}
break;
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_free)
ef->asn1_ex_free(pval, it);
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_do_lock(pval, -1, it) > 0)
return;
if (asn1_cb) {
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
if (i == 2)
return;
}
asn1_enc_free(pval, it);
/* If we free up as normal we will invalidate any
* ANY DEFINED BY field and we wont be able to
* determine the type of the field it defines. So
* free up in reverse order.
*/
tt = it->templates + it->tcount - 1;
for (i = 0; i < it->tcount; tt--, i++) {
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 0);
if (!seqtt)
continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
}
if (asn1_cb)
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
if (!combine) {
free(*pval);
*pval = NULL;
}
break;
}
}
void
ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
int i;
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
ASN1_VALUE *vtmp;
vtmp = sk_ASN1_VALUE_value(sk, i);
asn1_item_combine_free(&vtmp, tt->item,
0);
}
sk_ASN1_VALUE_free(sk);
*pval = NULL;
} else
asn1_item_combine_free(pval, tt->item,
tt->flags & ASN1_TFLG_COMBINE);
}
void
ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int utype;
if (it) {
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (pf && pf->prim_free) {
pf->prim_free(pval, it);
return;
}
}
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
if (!it) {
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
utype = typ->type;
pval = &typ->value.asn1_value;
if (!*pval)
return;
} else if (it->itype == ASN1_ITYPE_MSTRING) {
utype = -1;
if (!*pval)
return;
} else {
utype = it->utype;
if ((utype != V_ASN1_BOOLEAN) && !*pval)
return;
}
switch (utype) {
case V_ASN1_OBJECT:
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
break;
case V_ASN1_BOOLEAN:
if (it)
*(ASN1_BOOLEAN *)pval = it->size;
else
*(ASN1_BOOLEAN *)pval = -1;
return;
case V_ASN1_NULL:
break;
case V_ASN1_ANY:
ASN1_primitive_free(pval, NULL);
free(*pval);
break;
default:
ASN1_STRING_free((ASN1_STRING *)*pval);
break;
}
*pval = NULL;
}

374
crypto/asn1/tasn_new.c Normal file
View File

@ -0,0 +1,374 @@
/* $OpenBSD: tasn_new.c,v 1.17 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/asn1.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#include <openssl/asn1t.h>
#include <string.h>
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
ASN1_VALUE *
ASN1_item_new(const ASN1_ITEM *it)
{
ASN1_VALUE *ret = NULL;
if (ASN1_item_ex_new(&ret, it) > 0)
return ret;
return NULL;
}
/* Allocate an ASN1 structure */
int
ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
return asn1_item_ex_combine_new(pval, it, 0);
}
static int
asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
{
const ASN1_TEMPLATE *tt = NULL;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb = NULL;
ASN1_VALUE **pseqval;
int i;
if (aux != NULL && aux->asn1_cb != NULL)
asn1_cb = aux->asn1_cb;
if (!combine)
*pval = NULL;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
#endif
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_new) {
if (!ef->asn1_ex_new(pval, it))
goto memerr;
}
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {
if (!ASN1_template_new(pval, it->templates))
goto memerr;
} else if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_MSTRING:
if (!ASN1_primitive_new(pval, it))
goto memerr;
break;
case ASN1_ITYPE_CHOICE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
if (!combine) {
*pval = calloc(1, it->size);
if (!*pval)
goto memerr;
}
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
case ASN1_ITYPE_SEQUENCE:
if (asn1_cb) {
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
if (!combine) {
*pval = calloc(1, it->size);
if (!*pval)
goto memerr;
asn1_do_lock(pval, 0, it);
asn1_enc_init(pval, it);
}
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
goto memerr;
}
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
goto auxerr;
break;
}
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
auxerr:
ASN1error(ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
}
static void
asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
const ASN1_EXTERN_FUNCS *ef;
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
ef = it->funcs;
if (ef && ef->asn1_ex_clear)
ef->asn1_ex_clear(pval, it);
else
*pval = NULL;
break;
case ASN1_ITYPE_PRIMITIVE:
if (it->templates)
asn1_template_clear(pval, it->templates);
else
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_MSTRING:
asn1_primitive_clear(pval, it);
break;
case ASN1_ITYPE_CHOICE:
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
*pval = NULL;
break;
}
}
int
ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
const ASN1_ITEM *it = tt->item;
int ret;
if (tt->flags & ASN1_TFLG_OPTIONAL) {
asn1_template_clear(pval, tt);
return 1;
}
/* If ANY DEFINED BY nothing to do */
if (tt->flags & ASN1_TFLG_ADB_MASK) {
*pval = NULL;
return 1;
}
#ifdef CRYPTO_MDEBUG
if (tt->field_name)
CRYPTO_push_info(tt->field_name);
#endif
/* If SET OF or SEQUENCE OF, its a STACK */
if (tt->flags & ASN1_TFLG_SK_MASK) {
STACK_OF(ASN1_VALUE) *skval;
skval = sk_ASN1_VALUE_new_null();
if (!skval) {
ASN1error(ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
*pval = (ASN1_VALUE *)skval;
ret = 1;
goto done;
}
/* Otherwise pass it back to the item routine */
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
done:
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return ret;
}
static void
asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
/* If ADB or STACK just NULL the field */
if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
*pval = NULL;
else
asn1_item_clear(pval, tt->item);
}
/* NB: could probably combine most of the real XXX_new() behaviour and junk
* all the old functions.
*/
int
ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
ASN1_TYPE *typ;
ASN1_STRING *str;
int utype;
if (it && it->funcs) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_new)
return pf->prim_new(pval, it);
}
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = V_ASN1_UNDEF;
else
utype = it->utype;
switch (utype) {
case V_ASN1_OBJECT:
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
return 1;
case V_ASN1_BOOLEAN:
*(ASN1_BOOLEAN *)pval = it->size;
return 1;
case V_ASN1_NULL:
*pval = (ASN1_VALUE *)1;
return 1;
case V_ASN1_ANY:
typ = malloc(sizeof(ASN1_TYPE));
if (typ != NULL) {
typ->value.ptr = NULL;
typ->type = V_ASN1_UNDEF;
}
*pval = (ASN1_VALUE *)typ;
break;
default:
str = ASN1_STRING_type_new(utype);
if (it != NULL && it->itype == ASN1_ITYPE_MSTRING &&
str != NULL)
str->flags |= ASN1_STRING_FLAG_MSTRING;
*pval = (ASN1_VALUE *)str;
break;
}
if (*pval)
return 1;
return 0;
}
static void
asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int utype;
if (it && it->funcs) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
if (pf->prim_clear)
pf->prim_clear(pval, it);
else
*pval = NULL;
return;
}
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
utype = V_ASN1_UNDEF;
else
utype = it->utype;
if (utype == V_ASN1_BOOLEAN)
*(ASN1_BOOLEAN *)pval = it->size;
else
*pval = NULL;
}

596
crypto/asn1/tasn_prn.c Normal file
View File

@ -0,0 +1,596 @@
/* $OpenBSD: tasn_prn.c,v 1.16 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/x509v3.h>
#include "asn1_locl.h"
/* Print routines.
*/
/* ASN1_PCTX routines */
ASN1_PCTX default_pctx = {
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
0, /* cert_flags */
0, /* oid_flags */
0 /* str_flags */
};
ASN1_PCTX *
ASN1_PCTX_new(void)
{
ASN1_PCTX *ret;
ret = malloc(sizeof(ASN1_PCTX));
if (ret == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
ret->nm_flags = 0;
ret->cert_flags = 0;
ret->oid_flags = 0;
ret->str_flags = 0;
return ret;
}
void
ASN1_PCTX_free(ASN1_PCTX *p)
{
free(p);
}
unsigned long
ASN1_PCTX_get_flags(ASN1_PCTX *p)
{
return p->flags;
}
void
ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
{
p->flags = flags;
}
unsigned long
ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
{
return p->nm_flags;
}
void
ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
{
p->nm_flags = flags;
}
unsigned long
ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
{
return p->cert_flags;
}
void
ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
{
p->cert_flags = flags;
}
unsigned long
ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
{
return p->oid_flags;
}
void
ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
{
p->oid_flags = flags;
}
unsigned long
ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
{
return p->str_flags;
}
void
ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
{
p->str_flags = flags;
}
/* Main print routines */
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_ITEM *it, const char *fname, const char *sname, int nohdr,
const ASN1_PCTX *pctx);
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
const ASN1_ITEM *it, int indent, const char *fname, const char *sname,
const ASN1_PCTX *pctx);
static int asn1_print_fsname(BIO *out, int indent, const char *fname,
const char *sname, const ASN1_PCTX *pctx);
int
ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, const ASN1_ITEM *it,
const ASN1_PCTX *pctx)
{
const char *sname;
if (pctx == NULL)
pctx = &default_pctx;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;
else
sname = it->sname;
return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname,
0, pctx);
}
static int
asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, const ASN1_ITEM *it,
const char *fname, const char *sname, int nohdr, const ASN1_PCTX *pctx)
{
const ASN1_TEMPLATE *tt;
const ASN1_EXTERN_FUNCS *ef;
ASN1_VALUE **tmpfld;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
ASN1_PRINT_ARG parg;
int i;
if (aux && aux->asn1_cb) {
parg.out = out;
parg.indent = indent;
parg.pctx = pctx;
asn1_cb = aux->asn1_cb;
} else
asn1_cb = NULL;
if (*fld == NULL) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
if (!nohdr &&
!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (BIO_puts(out, "<ABSENT>\n") <= 0)
return 0;
}
return 1;
}
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {
if (!asn1_template_print_ctx(out, fld, indent,
it->templates, pctx))
return 0;
}
/* fall thru */
case ASN1_ITYPE_MSTRING:
if (!asn1_primitive_print(out, fld, it,
indent, fname, sname, pctx))
return 0;
break;
case ASN1_ITYPE_EXTERN:
if (!nohdr &&
!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
/* Use new style print routine if possible */
ef = it->funcs;
if (ef && ef->asn1_ex_print) {
i = ef->asn1_ex_print(out, fld, indent, "", pctx);
if (!i)
return 0;
if ((i == 2) && (BIO_puts(out, "\n") <= 0))
return 0;
return 1;
} else if (sname &&
BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
return 0;
break;
case ASN1_ITYPE_CHOICE:
/* CHOICE type, get selector */
i = asn1_get_choice_selector(fld, it);
/* This should never happen... */
if ((i < 0) || (i >= it->tcount)) {
if (BIO_printf(out,
"ERROR: selector [%d] invalid\n", i) <= 0)
return 0;
return 1;
}
tt = it->templates + i;
tmpfld = asn1_get_field_ptr(fld, tt);
if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
return 0;
break;
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
if (!nohdr &&
!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (fname || sname) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_puts(out, " {\n") <= 0)
return 0;
} else {
if (BIO_puts(out, "\n") <= 0)
return 0;
}
}
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
}
/* Print each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(fld, tt, 1);
if (seqtt == NULL)
return 0;
tmpfld = asn1_get_field_ptr(fld, seqtt);
if (!asn1_template_print_ctx(out, tmpfld, indent + 2,
seqtt, pctx))
return 0;
}
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_printf(out, "%*s}\n", indent, "") < 0)
return 0;
}
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
}
break;
default:
BIO_printf(out, "Unprocessed type %d\n", it->itype);
return 0;
}
return 1;
}
int
asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
{
int i, flags;
const char *sname, *fname;
flags = tt->flags;
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
sname = tt->item->sname;
else
sname = NULL;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
else
fname = tt->field_name;
if (flags & ASN1_TFLG_SK_MASK) {
char *tname;
ASN1_VALUE *skitem;
STACK_OF(ASN1_VALUE) *stack;
/* SET OF, SEQUENCE OF */
if (fname) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
if (flags & ASN1_TFLG_SET_OF)
tname = "SET";
else
tname = "SEQUENCE";
if (BIO_printf(out, "%*s%s OF %s {\n",
indent, "", tname, tt->field_name) <= 0)
return 0;
} else if (BIO_printf(out, "%*s%s:\n", indent, "",
fname) <= 0)
return 0;
}
stack = (STACK_OF(ASN1_VALUE) *)*fld;
for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
if ((i > 0) && (BIO_puts(out, "\n") <= 0))
return 0;
skitem = sk_ASN1_VALUE_value(stack, i);
if (!asn1_item_print_ctx(out, &skitem, indent + 2,
tt->item, NULL, NULL, 1, pctx))
return 0;
}
if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
return 0;
}
return 1;
}
return asn1_item_print_ctx(out, fld, indent, tt->item,
fname, sname, 0, pctx);
}
static int
asn1_print_fsname(BIO *out, int indent, const char *fname, const char *sname,
const ASN1_PCTX *pctx)
{
static char spaces[] = " ";
const int nspaces = sizeof(spaces) - 1;
while (indent > nspaces) {
if (BIO_write(out, spaces, nspaces) != nspaces)
return 0;
indent -= nspaces;
}
if (BIO_write(out, spaces, indent) != indent)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
if (!sname && !fname)
return 1;
if (fname) {
if (BIO_puts(out, fname) <= 0)
return 0;
}
if (sname) {
if (fname) {
if (BIO_printf(out, " (%s)", sname) <= 0)
return 0;
} else {
if (BIO_puts(out, sname) <= 0)
return 0;
}
}
if (BIO_write(out, ": ", 2) != 2)
return 0;
return 1;
}
static int
asn1_print_boolean_ctx(BIO *out, int boolval, const ASN1_PCTX *pctx)
{
const char *str;
switch (boolval) {
case -1:
str = "BOOL ABSENT";
break;
case 0:
str = "FALSE";
break;
default:
str = "TRUE";
break;
}
if (BIO_puts(out, str) <= 0)
return 0;
return 1;
}
static int
asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, const ASN1_PCTX *pctx)
{
char *s;
int ret = 1;
s = i2s_ASN1_INTEGER(NULL, str);
if (BIO_puts(out, s) <= 0)
ret = 0;
free(s);
return ret;
}
static int
asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, const ASN1_PCTX *pctx)
{
char objbuf[80];
const char *ln;
ln = OBJ_nid2ln(OBJ_obj2nid(oid));
if (!ln)
ln = "";
OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
return 0;
return 1;
}
static int
asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
const ASN1_PCTX *pctx)
{
if (str->type == V_ASN1_BIT_STRING) {
if (BIO_printf(out, " (%ld unused bits)\n",
str->flags & 0x7) <= 0)
return 0;
} else if (BIO_puts(out, "\n") <= 0)
return 0;
if ((str->length > 0) &&
BIO_dump_indent(out, (char *)str->data, str->length,
indent + 2) <= 0)
return 0;
return 1;
}
static int
asn1_primitive_print(BIO *out, ASN1_VALUE **fld, const ASN1_ITEM *it,
int indent, const char *fname, const char *sname, const ASN1_PCTX *pctx)
{
long utype;
ASN1_STRING *str;
int ret = 1, needlf = 1;
const char *pname;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (pf && pf->prim_print)
return pf->prim_print(out, fld, it, indent, pctx);
str = (ASN1_STRING *)*fld;
if (it->itype == ASN1_ITYPE_MSTRING)
utype = str->type & ~V_ASN1_NEG;
else
utype = it->utype;
if (utype == V_ASN1_ANY) {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
fld = &atype->value.asn1_value;
str = (ASN1_STRING *)*fld;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
pname = NULL;
else
pname = ASN1_tag2str(utype);
} else {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
pname = ASN1_tag2str(utype);
else
pname = NULL;
}
if (utype == V_ASN1_NULL) {
if (BIO_puts(out, "NULL\n") <= 0)
return 0;
return 1;
}
if (pname) {
if (BIO_puts(out, pname) <= 0)
return 0;
if (BIO_puts(out, ":") <= 0)
return 0;
}
switch (utype) {
case V_ASN1_BOOLEAN:
{
int boolval = *(int *)fld;
if (boolval == -1)
boolval = it->size;
ret = asn1_print_boolean_ctx(out, boolval, pctx);
}
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
ret = asn1_print_integer_ctx(out, str, pctx);
break;
case V_ASN1_UTCTIME:
ret = ASN1_UTCTIME_print(out, str);
break;
case V_ASN1_GENERALIZEDTIME:
ret = ASN1_GENERALIZEDTIME_print(out, str);
break;
case V_ASN1_OBJECT:
ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
break;
case V_ASN1_OCTET_STRING:
case V_ASN1_BIT_STRING:
ret = asn1_print_obstring_ctx(out, str, indent, pctx);
needlf = 0;
break;
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_OTHER:
if (BIO_puts(out, "\n") <= 0)
return 0;
if (ASN1_parse_dump(out, str->data, str->length,
indent, 0) <= 0)
ret = 0;
needlf = 0;
break;
default:
ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
}
if (!ret)
return 0;
if (needlf && BIO_puts(out, "\n") <= 0)
return 0;
return 1;
}

799
crypto/asn1/tasn_typ.c Normal file
View File

@ -0,0 +1,799 @@
/* $OpenBSD: tasn_typ.c,v 1.13 2015/07/24 15:09:52 jsing 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 <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
/* Declarations for string types */
const ASN1_ITEM ASN1_INTEGER_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.sname = "ASN1_INTEGER",
};
ASN1_INTEGER *
d2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **in, long len)
{
return (ASN1_INTEGER *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_INTEGER_it);
}
int
i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
}
ASN1_INTEGER *
ASN1_INTEGER_new(void)
{
return (ASN1_INTEGER *)ASN1_item_new(&ASN1_INTEGER_it);
}
void
ASN1_INTEGER_free(ASN1_INTEGER *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_INTEGER_it);
}
const ASN1_ITEM ASN1_ENUMERATED_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ENUMERATED,
.sname = "ASN1_ENUMERATED",
};
ASN1_ENUMERATED *
d2i_ASN1_ENUMERATED(ASN1_ENUMERATED **a, const unsigned char **in, long len)
{
return (ASN1_ENUMERATED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ENUMERATED_it);
}
int
i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it);
}
ASN1_ENUMERATED *
ASN1_ENUMERATED_new(void)
{
return (ASN1_ENUMERATED *)ASN1_item_new(&ASN1_ENUMERATED_it);
}
void
ASN1_ENUMERATED_free(ASN1_ENUMERATED *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ENUMERATED_it);
}
const ASN1_ITEM ASN1_BIT_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BIT_STRING,
.sname = "ASN1_BIT_STRING",
};
ASN1_BIT_STRING *
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
{
return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_BIT_STRING_it);
}
int
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
}
ASN1_BIT_STRING *
ASN1_BIT_STRING_new(void)
{
return (ASN1_BIT_STRING *)ASN1_item_new(&ASN1_BIT_STRING_it);
}
void
ASN1_BIT_STRING_free(ASN1_BIT_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_BIT_STRING_it);
}
const ASN1_ITEM ASN1_OCTET_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OCTET_STRING,
.sname = "ASN1_OCTET_STRING",
};
ASN1_OCTET_STRING *
d2i_ASN1_OCTET_STRING(ASN1_OCTET_STRING **a, const unsigned char **in, long len)
{
return (ASN1_OCTET_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_OCTET_STRING_it);
}
int
i2d_ASN1_OCTET_STRING(ASN1_OCTET_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_OCTET_STRING_it);
}
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_new(void)
{
return (ASN1_OCTET_STRING *)ASN1_item_new(&ASN1_OCTET_STRING_it);
}
void
ASN1_OCTET_STRING_free(ASN1_OCTET_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_OCTET_STRING_it);
}
const ASN1_ITEM ASN1_NULL_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_NULL,
.sname = "ASN1_NULL",
};
ASN1_NULL *
d2i_ASN1_NULL(ASN1_NULL **a, const unsigned char **in, long len)
{
return (ASN1_NULL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_NULL_it);
}
int
i2d_ASN1_NULL(ASN1_NULL *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_NULL_it);
}
ASN1_NULL *
ASN1_NULL_new(void)
{
return (ASN1_NULL *)ASN1_item_new(&ASN1_NULL_it);
}
void
ASN1_NULL_free(ASN1_NULL *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_NULL_it);
}
const ASN1_ITEM ASN1_OBJECT_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OBJECT,
.sname = "ASN1_OBJECT",
};
const ASN1_ITEM ASN1_UTF8STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_UTF8STRING,
.sname = "ASN1_UTF8STRING",
};
ASN1_UTF8STRING *
d2i_ASN1_UTF8STRING(ASN1_UTF8STRING **a, const unsigned char **in, long len)
{
return (ASN1_UTF8STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_UTF8STRING_it);
}
int
i2d_ASN1_UTF8STRING(ASN1_UTF8STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UTF8STRING_it);
}
ASN1_UTF8STRING *
ASN1_UTF8STRING_new(void)
{
return (ASN1_UTF8STRING *)ASN1_item_new(&ASN1_UTF8STRING_it);
}
void
ASN1_UTF8STRING_free(ASN1_UTF8STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_UTF8STRING_it);
}
const ASN1_ITEM ASN1_PRINTABLESTRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_PRINTABLESTRING,
.sname = "ASN1_PRINTABLESTRING",
};
ASN1_PRINTABLESTRING *
d2i_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING **a, const unsigned char **in,
long len)
{
return (ASN1_PRINTABLESTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_PRINTABLESTRING_it);
}
int
i2d_ASN1_PRINTABLESTRING(ASN1_PRINTABLESTRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_PRINTABLESTRING_it);
}
ASN1_PRINTABLESTRING *
ASN1_PRINTABLESTRING_new(void)
{
return (ASN1_PRINTABLESTRING *)ASN1_item_new(&ASN1_PRINTABLESTRING_it);
}
void
ASN1_PRINTABLESTRING_free(ASN1_PRINTABLESTRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_PRINTABLESTRING_it);
}
const ASN1_ITEM ASN1_T61STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_T61STRING,
.sname = "ASN1_T61STRING",
};
ASN1_T61STRING *
d2i_ASN1_T61STRING(ASN1_T61STRING **a, const unsigned char **in, long len)
{
return (ASN1_T61STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_T61STRING_it);
}
int
i2d_ASN1_T61STRING(ASN1_T61STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_T61STRING_it);
}
ASN1_T61STRING *
ASN1_T61STRING_new(void)
{
return (ASN1_T61STRING *)ASN1_item_new(&ASN1_T61STRING_it);
}
void
ASN1_T61STRING_free(ASN1_T61STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_T61STRING_it);
}
const ASN1_ITEM ASN1_IA5STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_IA5STRING,
.sname = "ASN1_IA5STRING",
};
ASN1_IA5STRING *
d2i_ASN1_IA5STRING(ASN1_IA5STRING **a, const unsigned char **in, long len)
{
return (ASN1_IA5STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_IA5STRING_it);
}
int
i2d_ASN1_IA5STRING(ASN1_IA5STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_IA5STRING_it);
}
ASN1_IA5STRING *
ASN1_IA5STRING_new(void)
{
return (ASN1_IA5STRING *)ASN1_item_new(&ASN1_IA5STRING_it);
}
void
ASN1_IA5STRING_free(ASN1_IA5STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_IA5STRING_it);
}
const ASN1_ITEM ASN1_GENERALSTRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_GENERALSTRING,
.sname = "ASN1_GENERALSTRING",
};
ASN1_GENERALSTRING *
d2i_ASN1_GENERALSTRING(ASN1_GENERALSTRING **a, const unsigned char **in,
long len)
{
return (ASN1_GENERALSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_GENERALSTRING_it);
}
int
i2d_ASN1_GENERALSTRING(ASN1_GENERALSTRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_GENERALSTRING_it);
}
ASN1_GENERALSTRING *
ASN1_GENERALSTRING_new(void)
{
return (ASN1_GENERALSTRING *)ASN1_item_new(&ASN1_GENERALSTRING_it);
}
void
ASN1_GENERALSTRING_free(ASN1_GENERALSTRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_GENERALSTRING_it);
}
const ASN1_ITEM ASN1_UTCTIME_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_UTCTIME,
.sname = "ASN1_UTCTIME",
};
ASN1_UTCTIME *
d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, const unsigned char **in, long len)
{
return (ASN1_UTCTIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_UTCTIME_it);
}
int
i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UTCTIME_it);
}
ASN1_UTCTIME *
ASN1_UTCTIME_new(void)
{
return (ASN1_UTCTIME *)ASN1_item_new(&ASN1_UTCTIME_it);
}
void
ASN1_UTCTIME_free(ASN1_UTCTIME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_UTCTIME_it);
}
const ASN1_ITEM ASN1_GENERALIZEDTIME_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_GENERALIZEDTIME,
.sname = "ASN1_GENERALIZEDTIME",
};
ASN1_GENERALIZEDTIME *
d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, const unsigned char **in,
long len)
{
return (ASN1_GENERALIZEDTIME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_GENERALIZEDTIME_it);
}
int
i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_GENERALIZEDTIME_it);
}
ASN1_GENERALIZEDTIME *
ASN1_GENERALIZEDTIME_new(void)
{
return (ASN1_GENERALIZEDTIME *)ASN1_item_new(&ASN1_GENERALIZEDTIME_it);
}
void
ASN1_GENERALIZEDTIME_free(ASN1_GENERALIZEDTIME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_GENERALIZEDTIME_it);
}
const ASN1_ITEM ASN1_VISIBLESTRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_VISIBLESTRING,
.sname = "ASN1_VISIBLESTRING",
};
ASN1_VISIBLESTRING *
d2i_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING **a, const unsigned char **in,
long len)
{
return (ASN1_VISIBLESTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_VISIBLESTRING_it);
}
int
i2d_ASN1_VISIBLESTRING(ASN1_VISIBLESTRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_VISIBLESTRING_it);
}
ASN1_VISIBLESTRING *
ASN1_VISIBLESTRING_new(void)
{
return (ASN1_VISIBLESTRING *)ASN1_item_new(&ASN1_VISIBLESTRING_it);
}
void
ASN1_VISIBLESTRING_free(ASN1_VISIBLESTRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_VISIBLESTRING_it);
}
const ASN1_ITEM ASN1_UNIVERSALSTRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_UNIVERSALSTRING,
.sname = "ASN1_UNIVERSALSTRING",
};
ASN1_UNIVERSALSTRING *
d2i_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING **a, const unsigned char **in,
long len)
{
return (ASN1_UNIVERSALSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_UNIVERSALSTRING_it);
}
int
i2d_ASN1_UNIVERSALSTRING(ASN1_UNIVERSALSTRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_UNIVERSALSTRING_it);
}
ASN1_UNIVERSALSTRING *
ASN1_UNIVERSALSTRING_new(void)
{
return (ASN1_UNIVERSALSTRING *)ASN1_item_new(&ASN1_UNIVERSALSTRING_it);
}
void
ASN1_UNIVERSALSTRING_free(ASN1_UNIVERSALSTRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_UNIVERSALSTRING_it);
}
const ASN1_ITEM ASN1_BMPSTRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BMPSTRING,
.sname = "ASN1_BMPSTRING",
};
ASN1_BMPSTRING *
d2i_ASN1_BMPSTRING(ASN1_BMPSTRING **a, const unsigned char **in, long len)
{
return (ASN1_BMPSTRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_BMPSTRING_it);
}
int
i2d_ASN1_BMPSTRING(ASN1_BMPSTRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BMPSTRING_it);
}
ASN1_BMPSTRING *
ASN1_BMPSTRING_new(void)
{
return (ASN1_BMPSTRING *)ASN1_item_new(&ASN1_BMPSTRING_it);
}
void
ASN1_BMPSTRING_free(ASN1_BMPSTRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_BMPSTRING_it);
}
const ASN1_ITEM ASN1_ANY_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ANY,
.sname = "ASN1_ANY",
};
/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */
const ASN1_ITEM ASN1_SEQUENCE_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_SEQUENCE,
.sname = "ASN1_SEQUENCE",
};
ASN1_TYPE *
d2i_ASN1_TYPE(ASN1_TYPE **a, const unsigned char **in, long len)
{
return (ASN1_TYPE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_ANY_it);
}
int
i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ANY_it);
}
ASN1_TYPE *
ASN1_TYPE_new(void)
{
return (ASN1_TYPE *)ASN1_item_new(&ASN1_ANY_it);
}
void
ASN1_TYPE_free(ASN1_TYPE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_ANY_it);
}
/* Multistring types */
const ASN1_ITEM ASN1_PRINTABLE_it = {
.itype = ASN1_ITYPE_MSTRING,
.utype = B_ASN1_PRINTABLE,
.templates = NULL,
.tcount = 0,
.funcs = NULL,
.size = sizeof(ASN1_STRING),
.sname = "ASN1_PRINTABLE",
};
ASN1_STRING *
d2i_ASN1_PRINTABLE(ASN1_STRING **a, const unsigned char **in, long len)
{
return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_PRINTABLE_it);
}
int
i2d_ASN1_PRINTABLE(ASN1_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_PRINTABLE_it);
}
ASN1_STRING *
ASN1_PRINTABLE_new(void)
{
return (ASN1_STRING *)ASN1_item_new(&ASN1_PRINTABLE_it);
}
void
ASN1_PRINTABLE_free(ASN1_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &ASN1_PRINTABLE_it);
}
const ASN1_ITEM DISPLAYTEXT_it = {
.itype = ASN1_ITYPE_MSTRING,
.utype = B_ASN1_DISPLAYTEXT,
.templates = NULL,
.tcount = 0,
.funcs = NULL,
.size = sizeof(ASN1_STRING),
.sname = "DISPLAYTEXT",
};
ASN1_STRING *
d2i_DISPLAYTEXT(ASN1_STRING **a, const unsigned char **in, long len)
{
return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&DISPLAYTEXT_it);
}
int
i2d_DISPLAYTEXT(ASN1_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DISPLAYTEXT_it);
}
ASN1_STRING *
DISPLAYTEXT_new(void)
{
return (ASN1_STRING *)ASN1_item_new(&DISPLAYTEXT_it);
}
void
DISPLAYTEXT_free(ASN1_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &DISPLAYTEXT_it);
}
const ASN1_ITEM DIRECTORYSTRING_it = {
.itype = ASN1_ITYPE_MSTRING,
.utype = B_ASN1_DIRECTORYSTRING,
.templates = NULL,
.tcount = 0,
.funcs = NULL,
.size = sizeof(ASN1_STRING),
.sname = "DIRECTORYSTRING",
};
ASN1_STRING *
d2i_DIRECTORYSTRING(ASN1_STRING **a, const unsigned char **in, long len)
{
return (ASN1_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&DIRECTORYSTRING_it);
}
int
i2d_DIRECTORYSTRING(ASN1_STRING *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &DIRECTORYSTRING_it);
}
ASN1_STRING *
DIRECTORYSTRING_new(void)
{
return (ASN1_STRING *)ASN1_item_new(&DIRECTORYSTRING_it);
}
void
DIRECTORYSTRING_free(ASN1_STRING *a)
{
ASN1_item_free((ASN1_VALUE *)a, &DIRECTORYSTRING_it);
}
/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */
const ASN1_ITEM ASN1_BOOLEAN_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BOOLEAN,
.size = -1,
.sname = "ASN1_BOOLEAN",
};
const ASN1_ITEM ASN1_TBOOLEAN_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BOOLEAN,
.size = 1,
.sname = "ASN1_TBOOLEAN",
};
const ASN1_ITEM ASN1_FBOOLEAN_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BOOLEAN,
.size = 0,
.sname = "ASN1_FBOOLEAN",
};
/* Special, OCTET STRING with indefinite length constructed support */
const ASN1_ITEM ASN1_OCTET_STRING_NDEF_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OCTET_STRING,
.size = ASN1_TFLG_NDEF,
.sname = "ASN1_OCTET_STRING_NDEF",
};
static const ASN1_TEMPLATE ASN1_SEQUENCE_ANY_item_tt = {
.flags = ASN1_TFLG_SEQUENCE_OF,
.tag = 0,
.offset = 0,
.field_name = "ASN1_SEQUENCE_ANY",
.item = &ASN1_ANY_it,
};
const ASN1_ITEM ASN1_SEQUENCE_ANY_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &ASN1_SEQUENCE_ANY_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "ASN1_SEQUENCE_ANY",
};
static const ASN1_TEMPLATE ASN1_SET_ANY_item_tt = {
.flags = ASN1_TFLG_SET_OF,
.tag = 0,
.offset = 0,
.field_name = "ASN1_SET_ANY",
.item = &ASN1_ANY_it,
};
const ASN1_ITEM ASN1_SET_ANY_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &ASN1_SET_ANY_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "ASN1_SET_ANY",
};
ASN1_SEQUENCE_ANY *
d2i_ASN1_SEQUENCE_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len)
{
return (ASN1_SEQUENCE_ANY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_SEQUENCE_ANY_it);
}
int
i2d_ASN1_SEQUENCE_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_SEQUENCE_ANY_it);
}
ASN1_SEQUENCE_ANY *
d2i_ASN1_SET_ANY(ASN1_SEQUENCE_ANY **a, const unsigned char **in, long len)
{
return (ASN1_SEQUENCE_ANY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_SET_ANY_it);
}
int
i2d_ASN1_SET_ANY(const ASN1_SEQUENCE_ANY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_SET_ANY_it);
}

280
crypto/asn1/tasn_utl.c Normal file
View File

@ -0,0 +1,280 @@
/* $OpenBSD: tasn_utl.c,v 1.12 2017/01/29 17:49:22 beck Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/err.h>
/* Utility functions for manipulating fields and offsets */
/* Add 'offset' to 'addr' */
#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
/* Given an ASN1_ITEM CHOICE type return
* the selector value
*/
int
asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
int *sel = offset2ptr(*pval, it->utype);
return *sel;
}
/* Given an ASN1_ITEM CHOICE type set
* the selector value, return old value.
*/
int
asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
{
int *sel, ret;
sel = offset2ptr(*pval, it->utype);
ret = *sel;
*sel = value;
return ret;
}
/* Do reference counting. The value 'op' decides what to do.
* if it is +1 then the count is incremented. If op is 0 count is
* set to 1. If op is -1 count is decremented and the return value
* is the current refrence count or 0 if no reference count exists.
*/
int
asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
{
const ASN1_AUX *aux;
int *lck, ret;
if ((it->itype != ASN1_ITYPE_SEQUENCE) &&
(it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
return 0;
aux = it->funcs;
if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
return 0;
lck = offset2ptr(*pval, aux->ref_offset);
if (op == 0) {
*lck = 1;
return 1;
}
ret = CRYPTO_add(lck, op, aux->ref_lock);
return ret;
}
static ASN1_ENCODING *
asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
const ASN1_AUX *aux;
if (!pval || !*pval)
return NULL;
aux = it->funcs;
if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
return NULL;
return offset2ptr(*pval, aux->enc_offset);
}
void
asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc) {
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
}
}
void
asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (enc) {
free(enc->enc);
enc->enc = NULL;
enc->len = 0;
enc->modified = 1;
}
}
int
asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
const ASN1_ITEM *it)
{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc)
return 1;
free(enc->enc);
enc->enc = malloc(inlen);
if (!enc->enc)
return 0;
memcpy(enc->enc, in, inlen);
enc->len = inlen;
enc->modified = 0;
return 1;
}
int
asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
const ASN1_ITEM *it)
{
ASN1_ENCODING *enc;
enc = asn1_get_enc_ptr(pval, it);
if (!enc || enc->modified)
return 0;
if (out) {
memcpy(*out, enc->enc, enc->len);
*out += enc->len;
}
if (len)
*len = enc->len;
return 1;
}
/* Given an ASN1_TEMPLATE get a pointer to a field */
ASN1_VALUE **
asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
{
ASN1_VALUE **pvaltmp;
if (tt->flags & ASN1_TFLG_COMBINE)
return pval;
pvaltmp = offset2ptr(*pval, tt->offset);
/* NOTE for BOOLEAN types the field is just a plain
* int so we can't return int **, so settle for
* (int *).
*/
return pvaltmp;
}
/* Handle ANY DEFINED BY template, find the selector, look up
* the relevant ASN1_TEMPLATE in the table and return it.
*/
const ASN1_TEMPLATE *
asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr)
{
const ASN1_ADB *adb;
const ASN1_ADB_TABLE *atbl;
long selector;
ASN1_VALUE **sfld;
int i;
if (!(tt->flags & ASN1_TFLG_ADB_MASK))
return tt;
/* Else ANY DEFINED BY ... get the table */
adb = (const ASN1_ADB *)tt->item;
/* Get the selector field */
sfld = offset2ptr(*pval, adb->offset);
/* Check if NULL */
if (!sfld) {
if (!adb->null_tt)
goto err;
return adb->null_tt;
}
/* Convert type to a long:
* NB: don't check for NID_undef here because it
* might be a legitimate value in the table
*/
if (tt->flags & ASN1_TFLG_ADB_OID)
selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
else
selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
/* Try to find matching entry in table
* Maybe should check application types first to
* allow application override? Might also be useful
* to have a flag which indicates table is sorted and
* we can do a binary search. For now stick to a
* linear search.
*/
for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
if (atbl->value == selector)
return &atbl->tt;
/* FIXME: need to search application table too */
/* No match, return default type */
if (!adb->default_tt)
goto err;
return adb->default_tt;
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr)
ASN1error(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
}

222
crypto/asn1/x_algor.c Normal file
View File

@ -0,0 +1,222 @@
/* $OpenBSD: x_algor.c,v 1.21 2015/07/24 15:09:52 jsing 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 <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
static const ASN1_TEMPLATE X509_ALGOR_seq_tt[] = {
{
.offset = offsetof(X509_ALGOR, algorithm),
.field_name = "algorithm",
.item = &ASN1_OBJECT_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_ALGOR, parameter),
.field_name = "parameter",
.item = &ASN1_ANY_it,
},
};
const ASN1_ITEM X509_ALGOR_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_ALGOR_seq_tt,
.tcount = sizeof(X509_ALGOR_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(X509_ALGOR),
.sname = "X509_ALGOR",
};
static const ASN1_TEMPLATE X509_ALGORS_item_tt = {
.flags = ASN1_TFLG_SEQUENCE_OF,
.tag = 0,
.offset = 0,
.field_name = "algorithms",
.item = &X509_ALGOR_it,
};
const ASN1_ITEM X509_ALGORS_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &X509_ALGORS_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "X509_ALGORS",
};
X509_ALGOR *
d2i_X509_ALGOR(X509_ALGOR **a, const unsigned char **in, long len)
{
return (X509_ALGOR *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_ALGOR_it);
}
int
i2d_X509_ALGOR(X509_ALGOR *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ALGOR_it);
}
X509_ALGOR *
X509_ALGOR_new(void)
{
return (X509_ALGOR *)ASN1_item_new(&X509_ALGOR_it);
}
void
X509_ALGOR_free(X509_ALGOR *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_ALGOR_it);
}
X509_ALGORS *
d2i_X509_ALGORS(X509_ALGORS **a, const unsigned char **in, long len)
{
return (X509_ALGORS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_ALGORS_it);
}
int
i2d_X509_ALGORS(X509_ALGORS *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ALGORS_it);
}
X509_ALGOR *
X509_ALGOR_dup(X509_ALGOR *x)
{
return ASN1_item_dup(&X509_ALGOR_it, x);
}
int
X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
{
if (!alg)
return 0;
if (ptype != V_ASN1_UNDEF) {
if (alg->parameter == NULL)
alg->parameter = ASN1_TYPE_new();
if (alg->parameter == NULL)
return 0;
}
if (alg) {
if (alg->algorithm)
ASN1_OBJECT_free(alg->algorithm);
alg->algorithm = aobj;
}
if (ptype == 0)
return 1;
if (ptype == V_ASN1_UNDEF) {
if (alg->parameter) {
ASN1_TYPE_free(alg->parameter);
alg->parameter = NULL;
}
} else
ASN1_TYPE_set(alg->parameter, ptype, pval);
return 1;
}
void
X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
X509_ALGOR *algor)
{
if (paobj)
*paobj = algor->algorithm;
if (pptype) {
if (algor->parameter == NULL) {
*pptype = V_ASN1_UNDEF;
return;
} else
*pptype = algor->parameter->type;
if (ppval)
*ppval = algor->parameter->value.ptr;
}
}
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
void
X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
{
int param_type;
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
param_type = V_ASN1_UNDEF;
else
param_type = V_ASN1_NULL;
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}
/* Returns 0 if they are equal, != 0 otherwise. */
int
X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
{
int rv = OBJ_cmp(a->algorithm, b->algorithm);
if (!rv) {
if (!a->parameter && !b->parameter)
rv = 0;
else
rv = ASN1_TYPE_cmp(a->parameter, b->parameter);
}
return(rv);
}

198
crypto/asn1/x_attrib.c Normal file
View File

@ -0,0 +1,198 @@
/* $OpenBSD: x_attrib.c,v 1.13 2015/02/14 14:56:45 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.]
*/
#include <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
/* X509_ATTRIBUTE: this has the following form:
*
* typedef struct x509_attributes_st
* {
* ASN1_OBJECT *object;
* int single;
* union {
* char *ptr;
* STACK_OF(ASN1_TYPE) *set;
* ASN1_TYPE *single;
* } value;
* } X509_ATTRIBUTE;
*
* this needs some extra thought because the CHOICE type is
* merged with the main structure and because the value can
* be anything at all we *must* try the SET OF first because
* the ASN1_ANY type will swallow anything including the whole
* SET OF structure.
*/
static const ASN1_TEMPLATE X509_ATTRIBUTE_SET_ch_tt[] = {
{
.flags = ASN1_TFLG_SET_OF,
.tag = 0,
.offset = offsetof(X509_ATTRIBUTE, value.set),
.field_name = "value.set",
.item = &ASN1_ANY_it,
},
{
.flags = 0,
.tag = 0,
.offset = offsetof(X509_ATTRIBUTE, value.single),
.field_name = "value.single",
.item = &ASN1_ANY_it,
},
};
const ASN1_ITEM X509_ATTRIBUTE_SET_it = {
.itype = ASN1_ITYPE_CHOICE,
.utype = offsetof(X509_ATTRIBUTE, single),
.templates = X509_ATTRIBUTE_SET_ch_tt,
.tcount = sizeof(X509_ATTRIBUTE_SET_ch_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(X509_ATTRIBUTE),
.sname = "X509_ATTRIBUTE",
};
static const ASN1_TEMPLATE X509_ATTRIBUTE_seq_tt[] = {
{
.flags = 0,
.tag = 0,
.offset = offsetof(X509_ATTRIBUTE, object),
.field_name = "object",
.item = &ASN1_OBJECT_it,
},
/* CHOICE type merged with parent */
{
.flags = 0 | ASN1_TFLG_COMBINE,
.tag = 0,
.offset = 0,
.field_name = NULL,
.item = &X509_ATTRIBUTE_SET_it,
},
};
const ASN1_ITEM X509_ATTRIBUTE_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_ATTRIBUTE_seq_tt,
.tcount = sizeof(X509_ATTRIBUTE_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(X509_ATTRIBUTE),
.sname = "X509_ATTRIBUTE",
};
X509_ATTRIBUTE *
d2i_X509_ATTRIBUTE(X509_ATTRIBUTE **a, const unsigned char **in, long len)
{
return (X509_ATTRIBUTE *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_ATTRIBUTE_it);
}
int
i2d_X509_ATTRIBUTE(X509_ATTRIBUTE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_ATTRIBUTE_it);
}
X509_ATTRIBUTE *
X509_ATTRIBUTE_new(void)
{
return (X509_ATTRIBUTE *)ASN1_item_new(&X509_ATTRIBUTE_it);
}
void
X509_ATTRIBUTE_free(X509_ATTRIBUTE *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_ATTRIBUTE_it);
}
X509_ATTRIBUTE *
X509_ATTRIBUTE_dup(X509_ATTRIBUTE *x)
{
return ASN1_item_dup(&X509_ATTRIBUTE_it, x);
}
X509_ATTRIBUTE *
X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
{
X509_ATTRIBUTE *ret = NULL;
ASN1_TYPE *val = NULL;
if ((ret = X509_ATTRIBUTE_new()) == NULL)
return (NULL);
ret->object = OBJ_nid2obj(nid);
ret->single = 0;
if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
goto err;
if ((val = ASN1_TYPE_new()) == NULL)
goto err;
if (!sk_ASN1_TYPE_push(ret->value.set, val))
goto err;
ASN1_TYPE_set(val, atrtype, value);
return (ret);
err:
if (ret != NULL)
X509_ATTRIBUTE_free(ret);
if (val != NULL)
ASN1_TYPE_free(val);
return (NULL);
}

167
crypto/asn1/x_bignum.c Normal file
View File

@ -0,0 +1,167 @@
/* $OpenBSD: x_bignum.c,v 1.8 2015/07/25 17:07:17 jsing 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 <stdio.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
/*
* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
* BIGNUM directly. Currently it ignores the sign which isn't a problem since
* all BIGNUMs used are non negative and anything that looks negative is
* normally due to an encoding error.
*/
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL,
0,
bn_new,
bn_free,
0,
bn_c2i,
bn_i2c
};
const ASN1_ITEM BIGNUM_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.templates = NULL,
.tcount = 0,
.funcs = &bignum_pf,
.size = 0,
.sname = "BIGNUM",
};
const ASN1_ITEM CBIGNUM_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.templates = NULL,
.tcount = 0,
.funcs = &bignum_pf,
.size = 0,
.sname = "BIGNUM",
};
static int
bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*pval = (ASN1_VALUE *)BN_new();
if (*pval)
return 1;
else
return 0;
}
static void
bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if (*pval == NULL)
return;
BN_clear_free((BIGNUM *)*pval);
*pval = NULL;
}
static int
bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
{
BIGNUM *bn;
int pad, len;
if (*pval == NULL)
return -1;
bn = (BIGNUM *)*pval;
/* If MSB set in an octet we need a padding byte */
if (BN_num_bits(bn) & 0x7)
pad = 0;
else
pad = 1;
if (cont) {
if (pad)
*cont++ = 0;
len = BN_bn2bin(bn, cont);
} else
len = BN_num_bytes(bn);
return pad + len;
}
static int
bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
char *free_cont, const ASN1_ITEM *it)
{
BIGNUM *bn;
if (*pval == NULL) {
if (bn_new(pval, it) == 0)
return 0;
}
bn = (BIGNUM *)*pval;
if (!BN_bin2bn(cont, len, bn)) {
bn_free(pval, it);
return 0;
}
return 1;
}

687
crypto/asn1/x_crl.c Normal file
View File

@ -0,0 +1,687 @@
/* $OpenBSD: x_crl.c,v 1.27 2017/01/29 17:49:22 beck 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 <openssl/opensslconf.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "asn1_locl.h"
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b);
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
static const ASN1_TEMPLATE X509_REVOKED_seq_tt[] = {
{
.offset = offsetof(X509_REVOKED, serialNumber),
.field_name = "serialNumber",
.item = &ASN1_INTEGER_it,
},
{
.offset = offsetof(X509_REVOKED, revocationDate),
.field_name = "revocationDate",
.item = &ASN1_TIME_it,
},
{
.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_REVOKED, extensions),
.field_name = "extensions",
.item = &X509_EXTENSION_it,
},
};
const ASN1_ITEM X509_REVOKED_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_REVOKED_seq_tt,
.tcount = sizeof(X509_REVOKED_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(X509_REVOKED),
.sname = "X509_REVOKED",
};
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
static int def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *serial, X509_NAME *issuer);
static X509_CRL_METHOD int_crl_meth = {
.crl_lookup = def_crl_lookup,
.crl_verify = def_crl_verify
};
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
/* The X509_CRL_INFO structure needs a bit of customisation.
* Since we cache the original encoding the signature wont be affected by
* reordering of the revoked field.
*/
static int
crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
{
X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
if (!a || !a->revoked)
return 1;
switch (operation) {
/* Just set cmp function here. We don't sort because that
* would affect the output of X509_CRL_print().
*/
case ASN1_OP_D2I_POST:
(void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
break;
}
return 1;
}
static const ASN1_AUX X509_CRL_INFO_aux = {
.flags = ASN1_AFLG_ENCODING,
.asn1_cb = crl_inf_cb,
.enc_offset = offsetof(X509_CRL_INFO, enc),
};
static const ASN1_TEMPLATE X509_CRL_INFO_seq_tt[] = {
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_CRL_INFO, version),
.field_name = "version",
.item = &ASN1_INTEGER_it,
},
{
.offset = offsetof(X509_CRL_INFO, sig_alg),
.field_name = "sig_alg",
.item = &X509_ALGOR_it,
},
{
.offset = offsetof(X509_CRL_INFO, issuer),
.field_name = "issuer",
.item = &X509_NAME_it,
},
{
.offset = offsetof(X509_CRL_INFO, lastUpdate),
.field_name = "lastUpdate",
.item = &ASN1_TIME_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_CRL_INFO, nextUpdate),
.field_name = "nextUpdate",
.item = &ASN1_TIME_it,
},
{
.flags = ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_CRL_INFO, revoked),
.field_name = "revoked",
.item = &X509_REVOKED_it,
},
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_CRL_INFO, extensions),
.field_name = "extensions",
.item = &X509_EXTENSION_it,
},
};
const ASN1_ITEM X509_CRL_INFO_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_CRL_INFO_seq_tt,
.tcount = sizeof(X509_CRL_INFO_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = &X509_CRL_INFO_aux,
.size = sizeof(X509_CRL_INFO),
.sname = "X509_CRL_INFO",
};
/* Set CRL entry issuer according to CRL certificate issuer extension.
* Check for unhandled critical CRL entry extensions.
*/
static int
crl_set_issuers(X509_CRL *crl)
{
int i, j;
GENERAL_NAMES *gens, *gtmp;
STACK_OF(X509_REVOKED) *revoked;
revoked = X509_CRL_get_REVOKED(crl);
gens = NULL;
for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
STACK_OF(X509_EXTENSION) *exts;
ASN1_ENUMERATED *reason;
X509_EXTENSION *ext;
gtmp = X509_REVOKED_get_ext_d2i(rev, NID_certificate_issuer,
&j, NULL);
if (!gtmp && (j != -1)) {
crl->flags |= EXFLAG_INVALID;
return 1;
}
if (gtmp) {
gens = gtmp;
if (!crl->issuers) {
crl->issuers = sk_GENERAL_NAMES_new_null();
if (!crl->issuers)
return 0;
}
if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
return 0;
}
rev->issuer = gens;
reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
&j, NULL);
if (!reason && (j != -1)) {
crl->flags |= EXFLAG_INVALID;
return 1;
}
if (reason) {
rev->reason = ASN1_ENUMERATED_get(reason);
ASN1_ENUMERATED_free(reason);
} else
rev->reason = CRL_REASON_NONE;
/* Check for critical CRL entry extensions */
exts = rev->extensions;
for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
ext = sk_X509_EXTENSION_value(exts, j);
if (ext->critical > 0) {
if (OBJ_obj2nid(ext->object) ==
NID_certificate_issuer)
continue;
crl->flags |= EXFLAG_CRITICAL;
break;
}
}
}
return 1;
}
/* The X509_CRL structure needs a bit of customisation. Cache some extensions
* and hash of the whole CRL.
*/
static int
crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
{
X509_CRL *crl = (X509_CRL *)*pval;
STACK_OF(X509_EXTENSION) *exts;
X509_EXTENSION *ext;
int idx;
int rc = 1;
switch (operation) {
case ASN1_OP_NEW_POST:
crl->idp = NULL;
crl->akid = NULL;
crl->flags = 0;
crl->idp_flags = 0;
crl->idp_reasons = CRLDP_ALL_REASONS;
crl->meth = default_crl_method;
crl->meth_data = NULL;
crl->issuers = NULL;
crl->crl_number = NULL;
crl->base_crl_number = NULL;
break;
case ASN1_OP_D2I_POST:
#ifndef OPENSSL_NO_SHA
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
#endif
crl->idp = X509_CRL_get_ext_d2i(crl,
NID_issuing_distribution_point, NULL, NULL);
if (crl->idp)
setup_idp(crl, crl->idp);
crl->akid = X509_CRL_get_ext_d2i(crl,
NID_authority_key_identifier, NULL, NULL);
crl->crl_number = X509_CRL_get_ext_d2i(crl,
NID_crl_number, NULL, NULL);
crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
NID_delta_crl, NULL, NULL);
/* Delta CRLs must have CRL number */
if (crl->base_crl_number && !crl->crl_number)
crl->flags |= EXFLAG_INVALID;
/* See if we have any unhandled critical CRL extensions and
* indicate this in a flag. We only currently handle IDP,
* AKID and deltas, so anything else critical sets the flag.
*
* This code accesses the X509_CRL structure directly:
* applications shouldn't do this.
*/
exts = crl->crl->extensions;
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
int nid;
ext = sk_X509_EXTENSION_value(exts, idx);
nid = OBJ_obj2nid(ext->object);
if (nid == NID_freshest_crl)
crl->flags |= EXFLAG_FRESHEST;
if (ext->critical > 0) {
/* We handle IDP, AKID and deltas */
if (nid == NID_issuing_distribution_point ||
nid == NID_authority_key_identifier ||
nid == NID_delta_crl)
break;
crl->flags |= EXFLAG_CRITICAL;
break;
}
}
if (!crl_set_issuers(crl))
return 0;
if (crl->meth->crl_init) {
if (crl->meth->crl_init(crl) == 0)
return 0;
}
break;
case ASN1_OP_FREE_POST:
if (crl->meth->crl_free) {
if (!crl->meth->crl_free(crl))
rc = 0;
}
if (crl->akid)
AUTHORITY_KEYID_free(crl->akid);
if (crl->idp)
ISSUING_DIST_POINT_free(crl->idp);
ASN1_INTEGER_free(crl->crl_number);
ASN1_INTEGER_free(crl->base_crl_number);
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
break;
}
return rc;
}
/* Convert IDP into a more convenient form */
static void
setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
{
int idp_only = 0;
/* Set various flags according to IDP */
crl->idp_flags |= IDP_PRESENT;
if (idp->onlyuser > 0) {
idp_only++;
crl->idp_flags |= IDP_ONLYUSER;
}
if (idp->onlyCA > 0) {
idp_only++;
crl->idp_flags |= IDP_ONLYCA;
}
if (idp->onlyattr > 0) {
idp_only++;
crl->idp_flags |= IDP_ONLYATTR;
}
if (idp_only > 1)
crl->idp_flags |= IDP_INVALID;
if (idp->indirectCRL > 0)
crl->idp_flags |= IDP_INDIRECT;
if (idp->onlysomereasons) {
crl->idp_flags |= IDP_REASONS;
if (idp->onlysomereasons->length > 0)
crl->idp_reasons = idp->onlysomereasons->data[0];
if (idp->onlysomereasons->length > 1)
crl->idp_reasons |=
(idp->onlysomereasons->data[1] << 8);
crl->idp_reasons &= CRLDP_ALL_REASONS;
}
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
}
static const ASN1_AUX X509_CRL_aux = {
.app_data = NULL,
.flags = ASN1_AFLG_REFCOUNT,
.ref_offset = offsetof(X509_CRL, references),
.ref_lock = CRYPTO_LOCK_X509_CRL,
.asn1_cb = crl_cb,
};
static const ASN1_TEMPLATE X509_CRL_seq_tt[] = {
{
.offset = offsetof(X509_CRL, crl),
.field_name = "crl",
.item = &X509_CRL_INFO_it,
},
{
.offset = offsetof(X509_CRL, sig_alg),
.field_name = "sig_alg",
.item = &X509_ALGOR_it,
},
{
.offset = offsetof(X509_CRL, signature),
.field_name = "signature",
.item = &ASN1_BIT_STRING_it,
},
};
const ASN1_ITEM X509_CRL_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_CRL_seq_tt,
.tcount = sizeof(X509_CRL_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = &X509_CRL_aux,
.size = sizeof(X509_CRL),
.sname = "X509_CRL",
};
X509_REVOKED *
d2i_X509_REVOKED(X509_REVOKED **a, const unsigned char **in, long len)
{
return (X509_REVOKED *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_REVOKED_it);
}
int
i2d_X509_REVOKED(X509_REVOKED *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_REVOKED_it);
}
X509_REVOKED *
X509_REVOKED_new(void)
{
return (X509_REVOKED *)ASN1_item_new(&X509_REVOKED_it);
}
void
X509_REVOKED_free(X509_REVOKED *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_REVOKED_it);
}
X509_CRL_INFO *
d2i_X509_CRL_INFO(X509_CRL_INFO **a, const unsigned char **in, long len)
{
return (X509_CRL_INFO *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_CRL_INFO_it);
}
int
i2d_X509_CRL_INFO(X509_CRL_INFO *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CRL_INFO_it);
}
X509_CRL_INFO *
X509_CRL_INFO_new(void)
{
return (X509_CRL_INFO *)ASN1_item_new(&X509_CRL_INFO_it);
}
void
X509_CRL_INFO_free(X509_CRL_INFO *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_CRL_INFO_it);
}
X509_CRL *
d2i_X509_CRL(X509_CRL **a, const unsigned char **in, long len)
{
return (X509_CRL *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_CRL_it);
}
int
i2d_X509_CRL(X509_CRL *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CRL_it);
}
X509_CRL *
X509_CRL_new(void)
{
return (X509_CRL *)ASN1_item_new(&X509_CRL_it);
}
void
X509_CRL_free(X509_CRL *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_CRL_it);
}
X509_CRL *
X509_CRL_dup(X509_CRL *x)
{
return ASN1_item_dup(&X509_CRL_it, x);
}
static int
X509_REVOKED_cmp(const X509_REVOKED * const *a, const X509_REVOKED * const *b)
{
return(ASN1_STRING_cmp(
(ASN1_STRING *)(*a)->serialNumber,
(ASN1_STRING *)(*b)->serialNumber));
}
int
X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
{
X509_CRL_INFO *inf;
inf = crl->crl;
if (!inf->revoked)
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
inf->enc.modified = 1;
return 1;
}
int
X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
{
if (crl->meth->crl_verify)
return crl->meth->crl_verify(crl, r);
return 0;
}
int
X509_CRL_get0_by_serial(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *serial)
{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret, serial, NULL);
return 0;
}
int
X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
{
if (crl->meth->crl_lookup)
return crl->meth->crl_lookup(crl, ret,
X509_get_serialNumber(x), X509_get_issuer_name(x));
return 0;
}
static int
def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
{
return(ASN1_item_verify(&X509_CRL_INFO_it,
crl->sig_alg, crl->signature, crl->crl, r));
}
static int
crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, X509_REVOKED *rev)
{
int i;
if (!rev->issuer) {
if (!nm)
return 1;
if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
return 1;
return 0;
}
if (!nm)
nm = X509_CRL_get_issuer(crl);
for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
if (gen->type != GEN_DIRNAME)
continue;
if (!X509_NAME_cmp(nm, gen->d.directoryName))
return 1;
}
return 0;
}
static int
def_crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial,
X509_NAME *issuer)
{
X509_REVOKED rtmp, *rev;
int idx;
rtmp.serialNumber = serial;
/* Sort revoked into serial number order if not already sorted.
* Do this under a lock to avoid race condition.
*/
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
sk_X509_REVOKED_sort(crl->crl->revoked);
CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
}
idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
if (idx < 0)
return 0;
/* Need to look for matching name */
for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
return 0;
if (crl_revoked_issuer_match(crl, issuer, rev)) {
if (ret)
*ret = rev;
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
return 2;
return 1;
}
}
return 0;
}
void
X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
{
if (meth == NULL)
default_crl_method = &int_crl_meth;
else
default_crl_method = meth;
}
X509_CRL_METHOD *
X509_CRL_METHOD_new(int (*crl_init)(X509_CRL *crl),
int (*crl_free)(X509_CRL *crl),
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
ASN1_INTEGER *ser, X509_NAME *issuer),
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
{
X509_CRL_METHOD *m;
m = malloc(sizeof(X509_CRL_METHOD));
if (!m)
return NULL;
m->crl_init = crl_init;
m->crl_free = crl_free;
m->crl_lookup = crl_lookup;
m->crl_verify = crl_verify;
m->flags = X509_CRL_METHOD_DYNAMIC;
return m;
}
void
X509_CRL_METHOD_free(X509_CRL_METHOD *m)
{
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
return;
free(m);
}
void
X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
{
crl->meth_data = dat;
}
void *
X509_CRL_get_meth_data(X509_CRL *crl)
{
return crl->meth_data;
}

153
crypto/asn1/x_exten.c Normal file
View File

@ -0,0 +1,153 @@
/* $OpenBSD: x_exten.c,v 1.16 2015/07/24 15:09:52 jsing 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 <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
static const ASN1_TEMPLATE X509_EXTENSION_seq_tt[] = {
{
.offset = offsetof(X509_EXTENSION, object),
.field_name = "object",
.item = &ASN1_OBJECT_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(X509_EXTENSION, critical),
.field_name = "critical",
.item = &ASN1_BOOLEAN_it,
},
{
.offset = offsetof(X509_EXTENSION, value),
.field_name = "value",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM X509_EXTENSION_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_EXTENSION_seq_tt,
.tcount = sizeof(X509_EXTENSION_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(X509_EXTENSION),
.sname = "X509_EXTENSION",
};
static const ASN1_TEMPLATE X509_EXTENSIONS_item_tt = {
.flags = ASN1_TFLG_SEQUENCE_OF,
.tag = 0,
.offset = 0,
.field_name = "Extension",
.item = &X509_EXTENSION_it,
};
const ASN1_ITEM X509_EXTENSIONS_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &X509_EXTENSIONS_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "X509_EXTENSIONS",
};
X509_EXTENSION *
d2i_X509_EXTENSION(X509_EXTENSION **a, const unsigned char **in, long len)
{
return (X509_EXTENSION *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_EXTENSION_it);
}
int
i2d_X509_EXTENSION(X509_EXTENSION *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_EXTENSION_it);
}
X509_EXTENSION *
X509_EXTENSION_new(void)
{
return (X509_EXTENSION *)ASN1_item_new(&X509_EXTENSION_it);
}
void
X509_EXTENSION_free(X509_EXTENSION *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_EXTENSION_it);
}
X509_EXTENSIONS *
d2i_X509_EXTENSIONS(X509_EXTENSIONS **a, const unsigned char **in, long len)
{
return (X509_EXTENSIONS *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_EXTENSIONS_it);
}
int
i2d_X509_EXTENSIONS(X509_EXTENSIONS *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_EXTENSIONS_it);
}
X509_EXTENSION *
X509_EXTENSION_dup(X509_EXTENSION *x)
{
return ASN1_item_dup(&X509_EXTENSION_it, x);
}

107
crypto/asn1/x_info.c Normal file
View File

@ -0,0 +1,107 @@
/* $OpenBSD: x_info.c,v 1.17 2017/01/29 17:49:22 beck 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 <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
X509_INFO *
X509_INFO_new(void)
{
X509_INFO *ret = NULL;
ret = malloc(sizeof(X509_INFO));
if (ret == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->enc_cipher.cipher = NULL;
ret->enc_len = 0;
ret->enc_data = NULL;
ret->references = 1;
ret->x509 = NULL;
ret->crl = NULL;
ret->x_pkey = NULL;
return (ret);
}
void
X509_INFO_free(X509_INFO *x)
{
int i;
if (x == NULL)
return;
i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO);
if (i > 0)
return;
X509_free(x->x509);
if (x->crl != NULL)
X509_CRL_free(x->crl);
if (x->x_pkey != NULL)
X509_PKEY_free(x->x_pkey);
free(x->enc_data);
free(x);
}

210
crypto/asn1/x_long.c Normal file
View File

@ -0,0 +1,210 @@
/* $OpenBSD: x_long.c,v 1.11 2017/01/29 17:49:22 beck 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 <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/err.h>
/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
* and a long directly.
*/
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
static ASN1_PRIMITIVE_FUNCS long_pf = {
NULL, 0,
long_new,
long_free,
long_free, /* Clear should set to initial value */
long_c2i,
long_i2c,
long_print
};
const ASN1_ITEM LONG_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.templates = NULL,
.tcount = 0,
.funcs = &long_pf,
.size = ASN1_LONG_UNDEF,
.sname = "LONG",
};
const ASN1_ITEM ZLONG_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.templates = NULL,
.tcount = 0,
.funcs = &long_pf,
.size = 0,
.sname = "ZLONG",
};
static int
long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
return 1;
}
static void
long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
*(long *)pval = it->size;
}
static int
long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it)
{
long ltmp;
unsigned long utmp;
int clen, pad, i;
/* this exists to bypass broken gcc optimization */
char *cp = (char *)pval;
/* use memcpy, because we may not be long aligned */
memcpy(&ltmp, cp, sizeof(long));
if (ltmp == it->size)
return -1;
/* Convert the long to positive: we subtract one if negative so
* we can cleanly handle the padding if only the MSB of the leading
* octet is set.
*/
if (ltmp < 0)
utmp = -ltmp - 1;
else
utmp = ltmp;
clen = BN_num_bits_word(utmp);
/* If MSB of leading octet set we need to pad */
if (!(clen & 0x7))
pad = 1;
else
pad = 0;
/* Convert number of bits to number of octets */
clen = (clen + 7) >> 3;
if (cont) {
if (pad)
*cont++ = (ltmp < 0) ? 0xff : 0;
for (i = clen - 1; i >= 0; i--) {
cont[i] = (unsigned char)(utmp & 0xff);
if (ltmp < 0)
cont[i] ^= 0xff;
utmp >>= 8;
}
}
return clen + pad;
}
static int
long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
char *free_cont, const ASN1_ITEM *it)
{
int neg, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
if (len > (int)sizeof(long)) {
ASN1error(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
if (len && (cont[0] & 0x80))
neg = 1;
else
neg = 0;
utmp = 0;
for (i = 0; i < len; i++) {
utmp <<= 8;
if (neg)
utmp |= cont[i] ^ 0xff;
else
utmp |= cont[i];
}
ltmp = (long)utmp;
if (neg) {
ltmp++;
ltmp = -ltmp;
}
if (ltmp == it->size) {
ASN1error(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
return 1;
}
static int
long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent,
const ASN1_PCTX *pctx)
{
return BIO_printf(out, "%ld\n", *(long *)pval);
}

642
crypto/asn1/x_name.c Normal file
View File

@ -0,0 +1,642 @@
/* $OpenBSD: x_name.c,v 1.33 2017/01/29 17:49:22 beck 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in,
long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
ASN1_TLC *ctx);
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
const ASN1_ITEM *it, int tag, int aclass);
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
static int x509_name_encode(X509_NAME *a);
static int x509_name_canon(X509_NAME *a);
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
unsigned char **in);
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent,
const char *fname, const ASN1_PCTX *pctx);
static const ASN1_TEMPLATE X509_NAME_ENTRY_seq_tt[] = {
{
.offset = offsetof(X509_NAME_ENTRY, object),
.field_name = "object",
.item = &ASN1_OBJECT_it,
},
{
.offset = offsetof(X509_NAME_ENTRY, value),
.field_name = "value",
.item = &ASN1_PRINTABLE_it,
},
};
const ASN1_ITEM X509_NAME_ENTRY_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_NAME_ENTRY_seq_tt,
.tcount = sizeof(X509_NAME_ENTRY_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(X509_NAME_ENTRY),
.sname = "X509_NAME_ENTRY",
};
X509_NAME_ENTRY *
d2i_X509_NAME_ENTRY(X509_NAME_ENTRY **a, const unsigned char **in, long len)
{
return (X509_NAME_ENTRY *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_NAME_ENTRY_it);
}
int
i2d_X509_NAME_ENTRY(X509_NAME_ENTRY *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_ENTRY_it);
}
X509_NAME_ENTRY *
X509_NAME_ENTRY_new(void)
{
return (X509_NAME_ENTRY *)ASN1_item_new(&X509_NAME_ENTRY_it);
}
void
X509_NAME_ENTRY_free(X509_NAME_ENTRY *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_ENTRY_it);
}
X509_NAME_ENTRY *
X509_NAME_ENTRY_dup(X509_NAME_ENTRY *x)
{
return ASN1_item_dup(&X509_NAME_ENTRY_it, x);
}
/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
* so declare two template wrappers for this
*/
static const ASN1_TEMPLATE X509_NAME_ENTRIES_item_tt = {
.flags = ASN1_TFLG_SET_OF,
.tag = 0,
.offset = 0,
.field_name = "RDNS",
.item = &X509_NAME_ENTRY_it,
};
const ASN1_ITEM X509_NAME_ENTRIES_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &X509_NAME_ENTRIES_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "X509_NAME_ENTRIES",
};
static const ASN1_TEMPLATE X509_NAME_INTERNAL_item_tt = {
.flags = ASN1_TFLG_SEQUENCE_OF,
.tag = 0,
.offset = 0,
.field_name = "Name",
.item = &X509_NAME_ENTRIES_it,
};
const ASN1_ITEM X509_NAME_INTERNAL_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = -1,
.templates = &X509_NAME_INTERNAL_item_tt,
.tcount = 0,
.funcs = NULL,
.size = 0,
.sname = "X509_NAME_INTERNAL",
};
/* Normally that's where it would end: we'd have two nested STACK structures
* representing the ASN1. Unfortunately X509_NAME uses a completely different
* form and caches encodings so we have to process the internal form and convert
* to the external form.
*/
const ASN1_EXTERN_FUNCS x509_name_ff = {
NULL,
x509_name_ex_new,
x509_name_ex_free,
0, /* Default clear behaviour is OK */
x509_name_ex_d2i,
x509_name_ex_i2d,
x509_name_ex_print
};
const ASN1_ITEM X509_NAME_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = V_ASN1_SEQUENCE,
.templates = NULL,
.tcount = 0,
.funcs = &x509_name_ff,
.size = 0,
.sname = "X509_NAME",
};
X509_NAME *
d2i_X509_NAME(X509_NAME **a, const unsigned char **in, long len)
{
return (X509_NAME *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_NAME_it);
}
int
i2d_X509_NAME(X509_NAME *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_NAME_it);
}
X509_NAME *
X509_NAME_new(void)
{
return (X509_NAME *)ASN1_item_new(&X509_NAME_it);
}
void
X509_NAME_free(X509_NAME *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_NAME_it);
}
X509_NAME *
X509_NAME_dup(X509_NAME *x)
{
return ASN1_item_dup(&X509_NAME_it, x);
}
static int
x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
{
X509_NAME *ret = NULL;
ret = malloc(sizeof(X509_NAME));
if (!ret)
goto memerr;
if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
goto memerr;
if ((ret->bytes = BUF_MEM_new()) == NULL)
goto memerr;
ret->canon_enc = NULL;
ret->canon_enclen = 0;
ret->modified = 1;
*val = (ASN1_VALUE *)ret;
return 1;
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
if (ret) {
if (ret->entries)
sk_X509_NAME_ENTRY_free(ret->entries);
free(ret);
}
return 0;
}
static void
x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
X509_NAME *a;
if (!pval || !*pval)
return;
a = (X509_NAME *)*pval;
BUF_MEM_free(a->bytes);
sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
free(a->canon_enc);
free(a);
*pval = NULL;
}
static int
x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
const unsigned char *p = *in, *q;
union {
STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a;
} intname = {NULL};
union {
X509_NAME *x;
ASN1_VALUE *a;
} nm = {NULL};
int i, j, ret;
STACK_OF(X509_NAME_ENTRY) *entries;
X509_NAME_ENTRY *entry;
q = p;
/* Get internal representation of Name */
ret = ASN1_item_ex_d2i(&intname.a, &p, len,
&X509_NAME_INTERNAL_it, tag, aclass, opt, ctx);
if (ret <= 0)
return ret;
if (*val)
x509_name_ex_free(val, NULL);
if (!x509_name_ex_new(&nm.a, NULL))
goto err;
/* We've decoded it: now cache encoding */
if (!BUF_MEM_grow(nm.x->bytes, p - q))
goto err;
memcpy(nm.x->bytes->data, q, p - q);
/* Convert internal representation to X509_NAME structure */
for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
entry = sk_X509_NAME_ENTRY_value(entries, j);
entry->set = i;
if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
goto err;
}
sk_X509_NAME_ENTRY_free(entries);
}
sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
ret = x509_name_canon(nm.x);
if (!ret)
goto err;
nm.x->modified = 0;
*val = nm.a;
*in = p;
return ret;
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
ASN1error(ERR_R_NESTED_ASN1_ERROR);
return 0;
}
static int
x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
int ret;
X509_NAME *a = (X509_NAME *)*val;
if (a->modified) {
ret = x509_name_encode(a);
if (ret < 0)
return ret;
ret = x509_name_canon(a);
if (ret < 0)
return ret;
}
ret = a->bytes->length;
if (out != NULL) {
memcpy(*out, a->bytes->data, ret);
*out += ret;
}
return ret;
}
static void
local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
sk_X509_NAME_ENTRY_free(ne);
}
static void
local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}
static int
x509_name_encode(X509_NAME *a)
{
union {
STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
ASN1_VALUE *a;
} intname = {NULL};
int len;
unsigned char *p;
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
X509_NAME_ENTRY *entry;
int i, set = -1;
intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
if (!intname.s)
goto memerr;
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
if (entry->set != set) {
entries = sk_X509_NAME_ENTRY_new_null();
if (!entries)
goto memerr;
if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
entries))
goto memerr;
set = entry->set;
}
if (entries == NULL /* if entry->set is bogusly -1 */ ||
!sk_X509_NAME_ENTRY_push(entries, entry))
goto memerr;
}
len = ASN1_item_ex_i2d(&intname.a, NULL,
&X509_NAME_INTERNAL_it, -1, -1);
if (!BUF_MEM_grow(a->bytes, len))
goto memerr;
p = (unsigned char *)a->bytes->data;
ASN1_item_ex_i2d(&intname.a, &p, &X509_NAME_INTERNAL_it,
-1, -1);
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
a->modified = 0;
return len;
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
ASN1error(ERR_R_MALLOC_FAILURE);
return -1;
}
static int
x509_name_ex_print(BIO *out, ASN1_VALUE **pval, int indent, const char *fname,
const ASN1_PCTX *pctx)
{
if (X509_NAME_print_ex(out, (X509_NAME *)*pval, indent,
pctx->nm_flags) <= 0)
return 0;
return 2;
}
/* This function generates the canonical encoding of the Name structure.
* In it all strings are converted to UTF8, leading, trailing and
* multiple spaces collapsed, converted to lower case and the leading
* SEQUENCE header removed.
*
* In future we could also normalize the UTF8 too.
*
* By doing this comparison of Name structures can be rapidly
* performed by just using memcmp() of the canonical encoding.
* By omitting the leading SEQUENCE name constraints of type
* dirName can also be checked with a simple memcmp().
*/
static int
x509_name_canon(X509_NAME *a)
{
unsigned char *p;
STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
X509_NAME_ENTRY *entry, *tmpentry = NULL;
int i, len, set = -1, ret = 0;
if (a->canon_enc) {
free(a->canon_enc);
a->canon_enc = NULL;
}
/* Special case: empty X509_NAME => null encoding */
if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
a->canon_enclen = 0;
return 1;
}
intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
if (!intname)
goto err;
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
if (entry->set != set) {
entries = sk_X509_NAME_ENTRY_new_null();
if (!entries)
goto err;
if (sk_STACK_OF_X509_NAME_ENTRY_push(intname,
entries) == 0) {
sk_X509_NAME_ENTRY_free(entries);
goto err;
}
set = entry->set;
}
tmpentry = X509_NAME_ENTRY_new();
if (tmpentry == NULL)
goto err;
tmpentry->object = OBJ_dup(entry->object);
if (tmpentry->object == NULL)
goto err;
if (!asn1_string_canon(tmpentry->value, entry->value))
goto err;
if (entries == NULL /* if entry->set is bogusly -1 */ ||
!sk_X509_NAME_ENTRY_push(entries, tmpentry))
goto err;
tmpentry = NULL;
}
/* Finally generate encoding */
len = i2d_name_canon(intname, NULL);
if (len < 0)
goto err;
p = malloc(len);
if (p == NULL)
goto err;
a->canon_enc = p;
a->canon_enclen = len;
i2d_name_canon(intname, &p);
ret = 1;
err:
if (tmpentry)
X509_NAME_ENTRY_free(tmpentry);
if (intname)
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
local_sk_X509_NAME_ENTRY_pop_free);
return ret;
}
/* Bitmap of all the types of string that will be canonicalized. */
#define ASN1_MASK_CANON \
(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
| B_ASN1_VISIBLESTRING)
static int
asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
{
unsigned char *to, *from;
int len, i;
/* If type not in bitmask just copy string across */
if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
if (!ASN1_STRING_copy(out, in))
return 0;
return 1;
}
out->type = V_ASN1_UTF8STRING;
out->length = ASN1_STRING_to_UTF8(&out->data, in);
if (out->length == -1)
return 0;
to = out->data;
from = to;
len = out->length;
/* Convert string in place to canonical form.
* Ultimately we may need to handle a wider range of characters
* but for now ignore anything with MSB set and rely on the
* isspace() and tolower() functions.
*/
/* Ignore leading spaces */
while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
from++;
len--;
}
to = from + len - 1;
/* Ignore trailing spaces */
while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
to--;
len--;
}
to = out->data;
i = 0;
while (i < len) {
/* If MSB set just copy across */
if (*from & 0x80) {
*to++ = *from++;
i++;
}
/* Collapse multiple spaces */
else if (isspace(*from)) {
/* Copy one space across */
*to++ = ' ';
/* Ignore subsequent spaces. Note: don't need to
* check len here because we know the last
* character is a non-space so we can't overflow.
*/
do {
from++;
i++;
} while (!(*from & 0x80) && isspace(*from));
} else {
*to++ = tolower(*from);
from++;
i++;
}
}
out->length = to - out->data;
return 1;
}
static int
i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
{
int i, len, ltmp;
ASN1_VALUE *v;
STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
len = 0;
for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
v = sk_ASN1_VALUE_value(intname, i);
ltmp = ASN1_item_ex_i2d(&v, in,
&X509_NAME_ENTRIES_it, -1, -1);
if (ltmp < 0)
return ltmp;
len += ltmp;
}
return len;
}
int
X509_NAME_set(X509_NAME **xn, X509_NAME *name)
{
X509_NAME *in;
if (!xn || !name)
return (0);
if (*xn != name) {
in = X509_NAME_dup(name);
if (in != NULL) {
X509_NAME_free(*xn);
*xn = in;
}
}
return (*xn != NULL);
}

113
crypto/asn1/x_nx509.c Normal file
View File

@ -0,0 +1,113 @@
/* $OpenBSD: x_nx509.c,v 1.6 2015/02/11 04:00:39 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2005.
*/
/* ====================================================================
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#include <stddef.h>
#include <openssl/x509.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
/* Old netscape certificate wrapper format */
static const ASN1_TEMPLATE NETSCAPE_X509_seq_tt[] = {
{
.offset = offsetof(NETSCAPE_X509, header),
.field_name = "header",
.item = &ASN1_OCTET_STRING_it,
},
{
.flags = ASN1_TFLG_OPTIONAL,
.offset = offsetof(NETSCAPE_X509, cert),
.field_name = "cert",
.item = &X509_it,
},
};
const ASN1_ITEM NETSCAPE_X509_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = NETSCAPE_X509_seq_tt,
.tcount = sizeof(NETSCAPE_X509_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(NETSCAPE_X509),
.sname = "NETSCAPE_X509",
};
NETSCAPE_X509 *
d2i_NETSCAPE_X509(NETSCAPE_X509 **a, const unsigned char **in, long len)
{
return (NETSCAPE_X509 *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&NETSCAPE_X509_it);
}
int
i2d_NETSCAPE_X509(NETSCAPE_X509 *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &NETSCAPE_X509_it);
}
NETSCAPE_X509 *
NETSCAPE_X509_new(void)
{
return (NETSCAPE_X509 *)ASN1_item_new(&NETSCAPE_X509_it);
}
void
NETSCAPE_X509_free(NETSCAPE_X509 *a)
{
ASN1_item_free((ASN1_VALUE *)a, &NETSCAPE_X509_it);
}

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