early-access version 2698

This commit is contained in:
pineappleEA 2022-04-24 22:29:35 +02:00
parent c96f949832
commit caa0c2911b
486 changed files with 37806 additions and 14362 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access
=============
This is the source code for early-access 2696.
This is the source code for early-access 2698.
## Legal Notice

View file

@ -98,7 +98,7 @@ if(CMAKE_SYSTEM_NAME MATCHES "SunOS")
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")
set(PLATFORM_LIBS ${PLATFORM_LIBS} nsl socket)
set(PLATFORM_LIBS ${PLATFORM_LIBS} dl md nsl socket)
endif()
add_definitions(-DLIBRESSL_INTERNAL)
@ -113,19 +113,21 @@ if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
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=0x0600)
add_definitions(-DCPPFLAGS -DNO_SYSLOG -DNO_CRYPT)
set(PLATFORM_LIBS ${PLATFORM_LIBS} ws2_32)
add_definitions(-DWIN32_LEAN_AND_MEAN)
if(NOT CMAKE_SYSTEM_NAME MATCHES "WindowsStore")
add_definitions(-D_WIN32_WINNT=0x0600)
endif()
set(PLATFORM_LIBS ${PLATFORM_LIBS} ws2_32 bcrypt)
endif()
if(MSVC)
add_definitions(-Dinline=__inline)
message(STATUS "Using [${CMAKE_C_COMPILER_ID}] compiler")
if(CMAKE_C_COMPILER_ID MATCHES "MSVC")
if(CMAKE_C_COMPILER_ID MATCHES "MSVC" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
set(MSVC_DISABLED_WARNINGS_LIST
"C4018" # 'expression' : signed/unsigned mismatch
"C4057" # 'operator' : 'identifier1' indirection to
@ -284,11 +286,21 @@ if(HAVE_MEMMEM)
add_definitions(-DHAVE_MEMMEM)
endif()
check_include_files(endian.h HAVE_ENDIAN_H)
if(HAVE_ENDIAN_H)
add_definitions(-DHAVE_ENDIAN_H)
endif()
check_include_files(err.h HAVE_ERR_H)
if(HAVE_ERR_H)
add_definitions(-DHAVE_ERR_H)
endif()
check_include_files("sys/types.h;arpa/inet.h;netinet/ip.h" HAVE_NETINET_IP_H)
if(HAVE_NETINET_IP_H)
add_definitions(-DHAVE_NETINET_IP_H)
endif()
if(ENABLE_ASM)
if("${CMAKE_C_COMPILER_ABI}" STREQUAL "ELF")
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86_64|amd64)")
@ -298,6 +310,7 @@ if(ENABLE_ASM)
elseif(CMAKE_SYSTEM_NAME STREQUAL "SunOS" AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i386")
set(HOST_ASM_ELF_X86_64 true)
endif()
add_definitions(-DHAVE_GNU_STACK)
elseif(APPLE AND "${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
set(HOST_ASM_MACOSX_X86_64 true)
elseif(MSVC AND ("${CMAKE_GENERATOR}" MATCHES "Win64" OR "${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64"))
@ -331,14 +344,38 @@ if(SIZEOF_TIME_T STREQUAL "4")
endif()
add_definitions(-DSIZEOF_TIME_T=${SIZEOF_TIME_T})
set(OPENSSL_LIBS tls ssl crypto ${PLATFORM_LIBS})
set(OPENSSL_LIBS ssl crypto ${PLATFORM_LIBS})
set(LIBTLS_LIBS tls ${PLATFORM_LIBS})
# libraries for regression test
if(BUILD_SHARED_LIBS)
set(OPENSSL_TEST_LIBS ssl-static crypto-static ${PLATFORM_LIBS})
set(LIBTLS_TEST_LIBS tls-static ${PLATFORM_LIBS})
else()
set(OPENSSL_TEST_LIBS ssl crypto ${PLATFORM_LIBS})
set(LIBTLS_TEST_LIBS tls ${PLATFORM_LIBS})
endif()
add_subdirectory(crypto)
add_subdirectory(ssl)
add_subdirectory(tls)
add_subdirectory(include)
if(NOT MSVC)
if (BUILD_APPLE_XCFRAMEWORK)
# Create the super library from object libraries
add_library(LibreSSL_xcframework
$<TARGET_OBJECTS:crypto_obj> $<TARGET_OBJECTS:tls_obj> $<TARGET_OBJECTS:ssl_obj>)
set_target_properties(LibreSSL_xcframework PROPERTIES
OUTPUT_NAME ressl)
if(ENABLE_LIBRESSL_INSTALL)
install(TARGETS LibreSSL_xcframework
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(ENABLE_LIBRESSL_INSTALL)
endif(BUILD_APPLE_XCFRAMEWORK)
if(ENABLE_LIBRESSL_INSTALL)
if(NOT MSVC)
# Create pkgconfig files.
set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix \${prefix})
@ -356,5 +393,16 @@ if(NOT MSVC)
endforeach()
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig
DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()
endif(ENABLE_LIBRESSL_INSTALL)
if(NOT "${OPENSSLDIR}" STREQUAL "")
set(CONF_DIR "${OPENSSLDIR}")
else()
set(CONF_DIR "${CMAKE_INSTALL_PREFIX}/etc/ssl")
endif()
if(ENABLE_LIBRESSL_INSTALL)
install(FILES cert.pem openssl.cnf x509v3.cnf DESTINATION ${CONF_DIR})
install(DIRECTORY DESTINATION ${CONF_DIR}/certs)
endif(ENABLE_LIBRESSL_INSTALL)

View file

@ -28,6 +28,804 @@ history is also available from Git.
LibreSSL Portable Release Notes:
3.5.2 - Stable release
* Bug fixes
- Avoid single byte overread in asn1_parse2().
- Allow name constraints with a leading dot. From Alex Wilson.
- Relax a check in x509_constraints_dirname() to allow prefixes.
From Alex Wilson.
- Fix NULL dereferences in openssl(1) cms option parsing.
- Do not zero the computed cofactor on ec_guess_cofactor() success.
- Bound cofactor in EC_GROUP_set_generator() to reduce the number of
bogus groups that can be described with nonsensical parameters.
- Avoid various potential segfaults in EVP_PKEY_CTX_free() in low
memory conditions. Reported for HMAC by Masaru Masuda.
- Plug leak in ASN1_TIME_adj_internal().
- Avoid infinite loop for custom curves of order 1.
Issue reported by Hanno Boeck, comments by David Benjamin.
- Avoid an infinite loop on parsing DSA private keys by validating
that the provided parameters conform to FIPS 186-4.
Issue reported by Hanno Boeck, comments by David Benjamin.
* Compatibility improvements
- Allow non-standard name constraints of the form @domain.com.
* Internal improvements
- Limit OID text conversion to 64 bits per arc.
- Clean up and simplify memory BIO code.
- Reduce number of memmove() calls in memory BIOs.
- Factor out alert handling code in the legacy stack.
- Add sanity checks on p and q in old_dsa_priv_decode()
- Cache the SHA-512 hash instead of the SHA-1 for CRLs.
- Suppress various compiler warnings for old gcc versions.
- Remove free_cont from asn1_d2i_ex_primitive()/asn1_ex_c2i().
- Rework ownership handling in x509_constraints_validate().
- Rework ASN1_STRING_set().
- Remove const from tls1_transcript_hash_value().
- Clean up and simplify ssl3_renegotiate{,_check}().
- Rewrite legacy TLS and DTLS unexpected handshake message handling.
- Simplify SSL_do_handshake().
- Rewrite ASCII/text to ASN.1 object conversion.
- Provide t2i_ASN1_OBJECT_internal() and use it for OBJ_txt2obj().
- Split armv7 and aarch64 code into separate locations.
- Rewrote openssl(1) ts to use the new option handling and cleaned
up the C code.
- Provide asn1_get_primitive().
- Convert {c2i,d2i}_ASN1_OBJECT() to CBS.
- Remove the minimum record length checks from dtls1_read_bytes().
- Clean up {dtls1,ssl3}_read_bytes().
- Be more careful with embedded and terminating NULs in the new
name constraints code.
- Check EVP_Digest* return codes in openssl(1) ts
- Various minor code cleanup in openssl(1) pkcs12
- Use calloc() in pkey_hmac_init().
- Simplify priv_key handling in d2i_ECPrivateKey().
* Documentation improvements
- Update d2i_ASN1_OBJECT(3) documentation to reflect reality after
refactoring and bug fixes.
- Fixed numerous minor grammar, spelling, wording, and punctuation
issues.
3.5.1 - Security release
* A malicious certificate can cause an infinite loop.
Reported by and fix from Tavis Ormandy and David Benjamin, Google.
3.5.0 - Development release
* New Features
- The RFC 3779 API was ported from OpenSSL. Many bugs were fixed,
regression tests were added and the code was cleaned up.
- Certificate Transparency was ported from OpenSSL. Many internal
improvements were made, resulting in cleaner and safer code.
Regress coverage was added. libssl does not yet make use of it.
* Portable Improvements
- Fixed various POSIX compliance and other portability issues
found by the port to the Sortix operating system.
- Add libmd as platform specific libraries for Solaris.
Issue reported from (ihsan <at> opencsw org) on libressl ML.
- Set IA-64 compiler flag only if it is HP-UX with IA-64.
Suggested from Larkin Nickle (me <at> larbob org) by libressl ML.
- Enabled and scheduled Coverity scan.
Contributed by Ilya Shipitsin (chipitsine <at> gmail com> on github.
* Compatibility Changes
- Most structs that were previously defined in the following headers
are now opaque as they are in OpenSSL 1.1:
bio.h, bn.h, comp.h, dh.h, dsa.h, evp.h, hmac.h, ocsp.h, rsa.h,
x509.h, x509v3.h, x509_vfy.h
- Switch TLSv1.3 cipher names from AEAD- to OpenSSL's TLS_
OpenSSL added the TLSv1.3 ciphersuites with "RFC names" instead
of using something consistent with the previous naming. Various
test suites expect these names (instead of checking for the much
more sensible cipher numbers). The old names are still accepted
as aliases.
- Subject alternative names and name constraints are now validated
when they are added to certificates. Various interoperability
problems with stacks that validate certificates more strictly
than OpenSSL can be avoided this way.
- Attempt to opportunistically use the host name for SNI in s_client
* Bug fixes
- In some situations, the verifier would discard the error on an
unvalidated certificate chain. This would happen when the
verification callback was in use, instructing the verifier to
continue unconditionally. This could lead to incorrect decisions
being made in software.
- Avoid an infinite loop in SSL_shutdown()
- Fix another return 0 bug in SSL_shutdown()
- Handle zero byte reads/writes that trigger handshakes in the
TLSv1.3 stack
- A long standing memleak in libtls CRL handling was fixed
* Internal Improvements
- Cache the SHA-512 hash instead of the SHA-1 hash and cache
notBefore and notAfter times when X.509 certificates are parsed.
- The X.509 lookup code has been simplified and cleaned up.
- Fixed numerous issues flagged by coverity and the cryptofuzz
project
- Increased the number of Miller-Rabin checks in DH and DSA
key/parameter generation
- Started using the bytestring API in libcrypto for cleaner and
safer code
- Convert {i2d,d2i}_{,EC_,DSA_,RSA_}PUBKEY{,_bio,_fp}() to templated
ASN1
- Convert ASN1_OBJECT_new() to calloc()
- Convert ASN1_STRING_type_new() to calloc()
- Rewrite ASN1_STRING_cmp()
- Use calloc() for X509_CRL_METHOD_new() instead of malloc()
- Convert ASN1_PCTX_new() to calloc()
- Replace asn1_tlc_clear and asn1_tlc_clear_nc macros with a
function
- Consolidate {d2i,i2d}_{pr,pu}.c
- Remove handling of a NULL BUF_MEM from asn1_collect()
- Pull the recursion depth check up to the top of asn1_collect()
- Inline collect_data() in asn1_collect()
- Convert asn1_d2i_ex_primitive()/asn1_collect() from BUF_MEM to CBB
- Clean up d2i_ASN1_BOOLEAN() and i2d_ASN1_BOOLEAN()
- Consolidate ASN.1 universal tag type data
- Rewrite ASN.1 identifier/length parsing in CBS
- Make OBJ_obj2nid() work correctly with NID_undef
- tlsext_tick_lifetime_hint is now an uint32_t
- Untangle ssl3_get_message() return values
- Rename tls13_buffer to tls_buffer
- Fold DTLS_STATE_INTERNAL into DTLS1_STATE
- Provide a way to determine our maximum legacy version
- Mop up enc_read_ctx and read_hash
- Fold SSL_SESSION_INTERNAL into SSL_SESSION
- Use ssl_force_want_read in the DTLS code
- Add record processing limit to DTLS code
- Add explicit CBS_contains_zero_byte() check in CBS_strdup()
- Improve SNI hostname validation
- Ensure SSL_set_tlsext_host_name() is given a valid hostname
- Fix a strange check in the auto DH codepath
- Factor out/rewrite DHE key exchange
- Convert server serialisation of DHE parameters/public key to new
functions
- Check DH public key in ssl_kex_peer_public_dhe()
- Move the minimum DHE key size check into ssl_kex_peer_params_dhe()
- Clean up and refactor server side DHE key exchange
- Provide CBS_get_last_u8()
- Provide CBS_get_u64()
- Provide CBS_add_u64()
- Provide various CBS_peek_* functions
- Use CBS_get_last_u8() to find the content type in TLSv1.3 records
- unifdef TLS13_USE_LEGACY_CLIENT_AUTH
- Correct SSL_get_peer_cert_chain() when used with the TLSv1.3 stack
- Only allow zero length key shares when we know we're doing HRR
- Pull key share group/length CBB code up from
tls13_key_share_public()
- Refactor ssl3_get_server_kex_ecdhe() to separate parsing and
validation
- Return 0 on failure from send/get kex functions in the legacy
stack
- Rename tls13_key_share to tls_key_share
- Allocate and free the EVP_AEAD_CTX struct in
tls13_record_protection
- Convert legacy TLS client to tls_key_share
- Convert legacy TLS server to tls_key_share
- Stop attempting to duplicate the public and private key of dh_tmp
- Rename dh_tmp to dhe_params
- Rename CERT to SSL_CERT and CERT_PKEY to SSL_CERT_PKEY
- Clean up pkey handling in ssl3_get_server_key_exchange()
- Fix GOST skip certificate verify handling
- Simplify tlsext_keyshare_server_parse()
- Plumb decode errors through key share parsing code
- Simplify SSL_get_peer_certificate()
- Cleanup/simplify ssl_cert_type()
- The S3I macro was removed
- The openssl(1) cms and smime subcommands option handling was
converted and the C source was cleaned up.
* Documentation improvements
- 45 new manual pages, most of which were written from scratch.
Documentation coverage of ASN.1 and X.509 code has been
significantly improved.
* API additions and removals
- libssl
API additions
SSL_get0_verified_chain SSL_peek_ex SSL_read_ex SSL_write_ex
API stubs for compatibility
SSL_CTX_get_keylog_callback SSL_CTX_get_num_tickets
SSL_CTX_set_keylog_callback SSL_CTX_set_num_tickets
SSL_get_num_tickets SSL_set_num_tickets
- libcrypto
added API (some of these were previously available as macros):
ASIdOrRange_free ASIdOrRange_new ASIdentifierChoice_free
ASIdentifierChoice_new ASIdentifiers_free ASIdentifiers_new
ASN1_TIME_diff ASRange_free ASRange_new BIO_get_callback_ex
BIO_get_init BIO_set_callback_ex BIO_set_next
BIO_set_retry_reason BN_GENCB_set BN_GENCB_set_old
BN_abs_is_word BN_get_flags BN_is_negative
BN_is_odd BN_is_one BN_is_word BN_is_zero BN_set_flags
BN_to_montgomery BN_with_flags BN_zero_ex CTLOG_STORE_free
CTLOG_STORE_get0_log_by_id CTLOG_STORE_load_default_file
CTLOG_STORE_load_file CTLOG_STORE_new CTLOG_free
CTLOG_get0_log_id CTLOG_get0_name CTLOG_get0_public_key
CTLOG_new CTLOG_new_from_base64 CT_POLICY_EVAL_CTX_free
CT_POLICY_EVAL_CTX_get0_cert CT_POLICY_EVAL_CTX_get0_issuer
CT_POLICY_EVAL_CTX_get0_log_store CT_POLICY_EVAL_CTX_get_time
CT_POLICY_EVAL_CTX_new CT_POLICY_EVAL_CTX_set1_cert
CT_POLICY_EVAL_CTX_set1_issuer
CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE
CT_POLICY_EVAL_CTX_set_time DH_get0_g DH_get0_p DH_get0_priv_key
DH_get0_pub_key DH_get0_q DH_get_length DSA_bits DSA_get0_g
DSA_get0_p DSA_get0_priv_key DSA_get0_pub_key DSA_get0_q
ECDSA_SIG_get0_r ECDSA_SIG_get0_s EVP_AEAD_CTX_free
EVP_AEAD_CTX_new EVP_CIPHER_CTX_buf_noconst
EVP_CIPHER_CTX_get_cipher_data EVP_CIPHER_CTX_set_cipher_data
EVP_MD_CTX_md_data EVP_MD_CTX_pkey_ctx EVP_MD_CTX_set_pkey_ctx
EVP_MD_meth_dup EVP_MD_meth_free EVP_MD_meth_new
EVP_MD_meth_set_app_datasize EVP_MD_meth_set_cleanup
EVP_MD_meth_set_copy EVP_MD_meth_set_ctrl EVP_MD_meth_set_final
EVP_MD_meth_set_flags EVP_MD_meth_set_init
EVP_MD_meth_set_input_blocksize EVP_MD_meth_set_result_size
EVP_MD_meth_set_update EVP_PKEY_asn1_set_check
EVP_PKEY_asn1_set_param_check EVP_PKEY_asn1_set_public_check
EVP_PKEY_check EVP_PKEY_meth_set_check
EVP_PKEY_meth_set_param_check EVP_PKEY_meth_set_public_check
EVP_PKEY_param_check EVP_PKEY_public_check FIPS_mode
FIPS_mode_set IPAddressChoice_free IPAddressChoice_new
IPAddressFamily_free IPAddressFamily_new IPAddressOrRange_free
IPAddressOrRange_new IPAddressRange_free IPAddressRange_new
OBJ_get0_data OBJ_length OCSP_resp_get0_certs OCSP_resp_get0_id
OCSP_resp_get0_produced_at OCSP_resp_get0_respdata
OCSP_resp_get0_signature OCSP_resp_get0_signer
OCSP_resp_get0_tbs_sigalg PEM_write_bio_PrivateKey_traditional
RSA_get0_d RSA_get0_dmp1 RSA_get0_dmq1 RSA_get0_e RSA_get0_iqmp
RSA_get0_n RSA_get0_p RSA_get0_pss_params RSA_get0_q
SCT_LIST_free SCT_LIST_print SCT_LIST_validate SCT_free
SCT_get0_extensions SCT_get0_log_id SCT_get0_signature
SCT_get_log_entry_type SCT_get_signature_nid SCT_get_source
SCT_get_timestamp SCT_get_validation_status SCT_get_version
SCT_new SCT_new_from_base64 SCT_print SCT_set0_extensions
SCT_set0_log_id SCT_set0_signature SCT_set1_extensions
SCT_set1_log_id SCT_set1_signature SCT_set_log_entry_type
SCT_set_signature_nid SCT_set_source SCT_set_timestamp
SCT_set_version SCT_validate SCT_validation_status_string
X509_OBJECT_free X509_OBJECT_new X509_REQ_get0_pubkey
X509_SIG_get0 X509_SIG_getm X509_STORE_CTX_get_by_subject
X509_STORE_CTX_get_num_untrusted
X509_STORE_CTX_get_obj_by_subject X509_STORE_CTX_get_verify
X509_STORE_CTX_get_verify_cb X509_STORE_CTX_set0_verified_chain
X509_STORE_CTX_set_current_cert X509_STORE_CTX_set_error_depth
X509_STORE_CTX_set_verify X509_STORE_get_verify
X509_STORE_get_verify_cb X509_STORE_set_verify
X509_get_X509_PUBKEY X509_get_extended_key_usage
X509_get_extension_flags X509_get_key_usage
X509v3_addr_add_inherit X509v3_addr_add_prefix
X509v3_addr_add_range X509v3_addr_canonize X509v3_addr_get_afi
X509v3_addr_get_range X509v3_addr_inherits
X509v3_addr_is_canonical X509v3_addr_subset
X509v3_addr_validate_path X509v3_addr_validate_resource_set
X509v3_asid_add_id_or_range X509v3_asid_add_inherit
X509v3_asid_canonize X509v3_asid_inherits
X509v3_asid_is_canonical X509v3_asid_subset
X509v3_asid_validate_path X509v3_asid_validate_resource_set
d2i_ASIdOrRange d2i_ASIdentifierChoice d2i_ASIdentifiers
d2i_ASRange d2i_IPAddressChoice d2i_IPAddressFamily
d2i_IPAddressOrRange d2i_IPAddressRange d2i_SCT_LIST
i2d_ASIdOrRange i2d_ASIdentifierChoice i2d_ASIdentifiers
i2d_ASRange i2d_IPAddressChoice i2d_IPAddressFamily
i2d_IPAddressOrRange i2d_IPAddressRange i2d_SCT_LIST
i2d_re_X509_CRL_tbs i2d_re_X509_REQ_tbs i2d_re_X509_tbs i2o_SCT
i2o_SCT_LIST o2i_SCT o2i_SCT_LIST
removed API:
ASN1_check_infinite_end ASN1_const_check_infinite_end EVP_dss
EVP_dss1 EVP_ecdsa HMAC_CTX_cleanup HMAC_CTX_init
NETSCAPE_ENCRYPTED_PKEY_free NETSCAPE_ENCRYPTED_PKEY_new
NETSCAPE_PKEY_free NETSCAPE_PKEY_new NETSCAPE_X509_free
NETSCAPE_X509_new OBJ_bsearch_ex_ PEM_SealFinal PEM_SealInit
PEM_SealUpdate PEM_read_X509_CERT_PAIR
PEM_read_bio_X509_CERT_PAIR PEM_write_X509_CERT_PAIR
PEM_write_bio_X509_CERT_PAIR X509_CERT_PAIR_free
X509_CERT_PAIR_new X509_OBJECT_free_contents asn1_do_adb
asn1_do_lock asn1_enc_free asn1_enc_init asn1_enc_restore
asn1_enc_save asn1_ex_c2i asn1_get_choice_selector
asn1_get_field_ptr asn1_set_choice_selector check_defer
d2i_ASN1_BOOLEAN d2i_NETSCAPE_ENCRYPTED_PKEY d2i_NETSCAPE_PKEY
d2i_NETSCAPE_X509 d2i_Netscape_RSA d2i_RSA_NET
d2i_X509_CERT_PAIR i2d_ASN1_BOOLEAN i2d_NETSCAPE_ENCRYPTED_PKEY
i2d_NETSCAPE_PKEY i2d_NETSCAPE_X509 i2d_Netscape_RSA i2d_RSA_NET
i2d_X509_CERT_PAIR name_cmp obj_cleanup_defer
3.4.1 - Stable release
* New Features
- Added support for OpenSSL 1.1.1 TLSv1.3 APIs.
- Enabled the new X.509 validator to allow verification of
modern certificate chains.
* Portable Improvements
- Ported continuous integration and test infrastructure to Github
actions.
- Added Universal Windows Platform (UWP) build support.
- Fixed mingw-w64 builds on newer versions with missing SSP support.
- Added non-executable stack annotations for CMake builds.
* API and Documentation Enhancements
- Added the following APIs from OpenSSL
BN_bn2binpad BN_bn2lebinpad BN_lebin2bn EC_GROUP_get_curve
EC_GROUP_order_bits EC_GROUP_set_curve
EC_POINT_get_affine_coordinates
EC_POINT_set_affine_coordinates
EC_POINT_set_compressed_coordinates EVP_DigestSign
EVP_DigestVerify SSL_CIPHER_find SSL_CTX_get0_privatekey
SSL_CTX_get_max_early_data SSL_CTX_get_ssl_method
SSL_CTX_set_ciphersuites SSL_CTX_set_max_early_data
SSL_CTX_set_post_handshake_auth SSL_SESSION_get0_cipher
SSL_SESSION_get_max_early_data SSL_SESSION_is_resumable
SSL_SESSION_set_max_early_data SSL_get_early_data_status
SSL_get_max_early_data SSL_read_early_data SSL_set0_rbio
SSL_set_ciphersuites SSL_set_max_early_data
SSL_set_post_handshake_auth
SSL_set_psk_use_session_callback
SSL_verify_client_post_handshake SSL_write_early_data
- Added AES-GCM constants from RFC 7714 for SRTP.
* Compatibility Changes
- Implement flushing for TLSv1.3 handshakes behavior, needed for Apache.
- Call the info callback on connect/accept exit in TLSv1.3,
needed for p5-Net-SSLeay.
- Default to using named curve parameter encoding from
pre-OpenSSL 1.1.0, adding OPENSSL_EC_EXPLICIT_CURVE.
- Do not ignore SSL_TLSEXT_ERR_FATAL from the ALPN callback.
* Testing and Proactive Security
- Added additional state machine test coverage.
- Improved integration test support with ruby/openssl tests.
- Error codes and callback support in new X.509 validator made
compatible with p5-Net_SSLeay tests.
* Internal Improvements
- Numerous fixes and improvements to the new X.509 validator to
ensure compatible error codes and callback support compatible
with the legacy OpenSSL validator.
3.4.0 - Development release
* Add support for OpenSSL 1.1.1 TLSv1.3 APIs.
* Enable new x509 validator.
* More details to come, testing is appreciated.
3.3.5 - Security fix
* A stack overread could occur when checking X.509 name constraints.
From GoldBinocle on GitHub.
* Enable X509_V_FLAG_TRUSTED_FIRST by default in the legacy verifier.
This compensates for the expiry of the DST Root X3 certificate.
3.3.4 - Security fix
* In LibreSSL, printing a certificate can result in a crash in
X509_CERT_AUX_print().
From Ingo Schwarze
* Ensure GNU-stack is set on ELF platforms when building with CMake to
enable non-executable stack annotations for the GNU toolchain.
From Tobias Heider
3.3.3 - Stable release
* This is the first stable release from the 3.3.x series.
There are no changes from 3.3.2.
3.3.2 - Development release
* This release adds support for DTLSv1.2 and continues the rewrite
of the record layer for the legacy stack. Numerous bugs and
interoperability issues were fixed in the new verifier. A few bugs
and incompatibilities remain, so this release uses the old verifier
by default. The OpenSSL 1.1 TLSv1.3 API is not yet available.
* Switch finish{,_peer}_md_len from an int to a size_t.
* Make SSL_get{,_peer}_finished() work when used with TLSv1.3.
* Use EVP_MD_MAX_MD_SIZE instead of 2 * EVP_MD_MAX_MD_SIZE as size
for cert_verify_md[], finish_md[] and peer_finish_md[]. The factor 2
was a historical artefact.
* Correct the return value type from ERR_peek_error() to a long.
* Avoid use of uninitialized in ASN1_time_parse() which could happen
on parsing UTCTime if the caller did not initialise the passed
struct tm.
* Destroy the mutex in a tls_config object on tls_config_free().
* Free alert_data and phh_data in tls13_record_layer_free()
these could leak if SSL_shutdown() or tls_close() were called
after closing the underlying socket().
* Free struct members in tls13_record_layer_free() in their natural
order for reviewability.
* Gracefully handle root certificates being both trusted and
untrusted.
* Handle X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE in the new
verifier.
* Use the legacy verifier when building auto chains for TLS.
* Use consistent names in tls13_{client,server}_finished_{recv,send}().
* Add tls13_secret_{init,cleanup}() and use them throughout the
TLSv1.3 code base.
* Move the read MAC key into the TLSv1.2 record layer.
* Make tls12_record_layer_free() NULL safe.
* Search the intermediates only after searching the root certs in the
new verifier to avoid problems with the legacy callback.
* Bail out early after finding a single chain in the new verifier, if
we have been called via the legacy verifier API.
* Set (invalid and likely incomplete) chain on the xsc on chain build
failure prior to calling the callback. This is required by various
callers, including auto chain.
* Align SSL_get_shared_ciphers() with OpenSSL. This takes into account
that it never returned server ciphers, so now it will fail when
called from the client side.
* Add support for SSL_get_shared_ciphers() with TLSv1.3.
* Split the record protection from the TLSv1.2 record layer.
* Clean up sequence number handling in the new TLSv1.2 record layer.
* Clean up sequence number handling in DTLS.
* Clean up dtls1_reset_seq_numbers().
* Factor out code for explicit IV length, block size and MAC length
from tls12_record_layer_open_record_protected_cipher().
* Provide record layer overhead for DTLS.
* Provide functions to determine if TLSv1.2 record protection is
engaged.
* Add code to handle change of cipher state in the new TLSv1.2 record
layer.
* Mop up now unused dtls1_build_sequence_numbers() function.
* Allow setting a keypair on a tls context without specifying the
private key, and fake it internally in libtls. This removes the
need for privsep engines like relayd to use bogus keys.
* Skip the private key check for fake private keys.
* Move the private key setup from tls_configure_ssl_keypair() to a
helper function with proper error checking.
* Change the internal tls_configure_ssl_keypair() function to
return -1 instead of 1 on failure.
* Move sequence numbers into the new TLSv1.2 record layer.
* Move AEAD handling into the new TLSv1.2 record layer.
* Remove direct assignment of aead_ctx to avoid a leak.
* Add a number of RPKI OIDs from RFC 6482, 6484, 6493, 8182, 8360,
draft-ietf-sidrops-rpki-rta, and draft-ietf-opsawg-finding-geofeeds.
* Fail early in legacy exporter if the master secret is not available
to avoid a segfault if it is called when the handshake is not
completed.
* Factor out legacy stack version checks.
* Correct handshake MAC/PRF for various TLSv1.2 cipher suites which
were originally added with the default handshake MAC and PRF rather
than the SHA256 handshake MAC and PRF.
* Absorb ssl3_get_algorithm2() into ssl_get_handshake_evp_md().
* Use dtls1_record_retrieve_buffered_record() to load buffered
application data.
* Enforce read ahead with DTLS.
* Remove bogus DTLS checks that disabled ECC and OCSP.
* Sync cert.pem with Mozilla NSS root CAs except "GeoTrust Global CA".
* Only print the certificate file once on verification failure.
* Pull in fix for EVP_CipherUpdate() overflow from OpenSSL.
* Clean up and simplify dtls1_get_cipher().
* Group HelloVerifyRequest decoding and add missing check for trailing
data.
* Revise HelloVerifyRequest handling for DTLSv1.2.
* Handle DTLS1_2_VERSION in various places.
* Add DTLSv1.2 methods.
* Make SSL{_CTX,}_get_{min,max}_proto_version() return a version of
zero if the minimum or maximum has been set to zero to match
OpenSSL's behavior.
* Rename the "truncated" label into "decode_err" and the "f_err"
label into "fatal_err".
* Factor out and change some of the legacy client version code.
* Simplify version checks in the TLSv1.3 client. Ensure that the
server announced TLSv1.3 and nothing higher and check that the
legacy_version is set to TLSv1.2 as required by RFC 8446.
* Fix an off-by-one in x509_verify_set_xsc_chain() to make sure that
the new validator checks for EXFLAG_CRITICAL in
x509_vfy_check_chain_extension() for all untrusted certs in the
chain. Take into account that the root is not necessarily trusted.
* Avoid passing last and depth to x509_verify_cert_error() on ENOMEM.
* Rename depth to num_untrusted.
* Only use TLS versions internally rather than both TLS and DTLS
versions since the latter are the one's complement of the human
readable version numbers, which means that newer versions decrease
in value.
* Fix two bugs in the legacy verifier that resulted from refactoring
of X509_verify_cert() for the new verifier: a return value was
incorrectly treated as boolean, making it insufficient to decide
whether validation should carry on or not.
* Identify DTLS based on the version major value.
* Move handling of cipher/hash based cipher suites into the new record
layer.
* Add tls12_record_protection_unused() and call it from CCS functions.
* Move key/IV length checks closer to usage sites. Also add explicit
checks against EVP_CIPHER_{iv,key}_length().
* Replace two handrolled tls12_record_protection_engaged().
* Improve internal version handling: add handshake fields for our
minimum version, our maximum version and the TLS version negotiated
during the handshake. Convert most of the internal code to use these
version fields.
* Guard against future internal use of TLS1_get_{client,}_version()
macros.
* Remove the internal ssl_downgrade_max_version() function which is no
longer needed.
* Fix checks for memory caps of constraints names. There are internal
caps on the number of name constraints and other names, that the new
name constraints code allocates per cert chain. These limits were
checked too late, making them only partially effective.
* Use EXFLAG_INVALID to handle out of memory and parse errors in
x509v3_cache_extensions().
* Add support for DTLSv1.2 version handling.
* Enable DTLSv1.2 support.
* Add DTLSv1.2 support to openssl s_client/s_server.
* Remove no longer needed read ahead workarounds in the s_client and
s_server.
* Fix a copy-paste error - skid was confused with an akid when
checking for EXFLAG_INVALID. This broke OCSP validation with
certain mirrors.
* Make supported protocols and options for DHE params more prominent
in tls_config_set_protocols.3.
* Avoid a use-after-scope in tls13_cert_add().
* Split TLSv1.3 record protection from record layer.
* Move the TLSv1.3 handshake struct inside the shared handshake
struct.
* Fully initialize rrec in tls12_record_layer_open_record_protected()
to avoid confusing some static analyzers.
* Use tls_set_errorx() on OCSP_basic_verify() failure since the latter
does not set errno.
* Convert openssl(1) x509 to new option handling and do the usual
clean up that goes along with it.
* Add SSL_HANDSHAKE_TLS12 for TLSv1.2 specific handshake data.
* Rename new_cipher to cipher to align naming with keyblock or other
parts of the handshake data.
* Avoid mangled output in BIO_debug_callback().
* Fix client initiated renegotiation by replacing use of s->internal-type
with s->server.
* Move the TLSv1.2 record number increment into the new record layer.
* Move finished and peer finished into the handshake struct.
* Avoid transcript initialization when sending a TLS HelloRequest,
fixing server initiated renegotiation.
* Remove pointless assignment in SSL_get0_alpn_selected().
* Provide EVP_PKEY_new_CMAC_KEY(3).
* Add missing prototype for d2i_DSAPrivateKey_fp(3) to x509.h.
* Add DTLSv1.2 to openssl(1) s_server and s_client protocol message
logging.
* Avoid leaking param->name in x509_verify_param_zero().
* Avoid a leak in an error path in openssl(1) x509.
* Add some error checking to openssl(1) x509.
* When sending an alert in TLSv1.3, only set its error code when no
other error was set previously. Certain clients rely on specific
SSL_R_ error codes to identify that they are dealing with a self
signed cert.
* Switch to the legacy verifier for the stable release.
* Provide SSL_use_certificate_chain_file(3).
* Provide SSL_set_hostflags(3) and SSL_get0_peername(3).
* Provide various DTLSv1.2 specific functions and defines.
* Document meaning of '*' in the genrsa output.
* Updated documentation for SSL_get_shared_ciphers(3).
* Add documentation for SSL_get_finished(3).
* Document EVP_PKEY_new_CMAC_key(3)
* Document SSL_use_certificate_chain_file(3).
* Document SSL_set_hostflags(3) and SSL_get0_peername(3).
* Update SSL_get_version.3 manual for DTLSv.1.2 support.
* Added '--enable-libtls-only' build option, which builds and installs a
statically-linked libtls, skipping libcrypto and libssl. This is useful
for systems that ship with OpenSSL but wish to also package libtls.
3.3.1 - Security fix
* Malformed ASN.1 in a certificate revocation list or a timestamp
response token can lead to a NULL pointer dereference.
Bug fixes
* Move point-on-curve check to set_affine_coordinates to avoid
verifying ECDSA signatures with unchecked public keys.
* Fix SSL_is_server() to behave as documented by re-introducing the
client-specific methods.
* Avoid undefined behavior due to memcpy(NULL, NULL, 0).
* Mark a few more internal static tables const.
3.3.0 - Development release
* Make openssl(1) s_server ignore -4 and -6 for compatibility with
OpenSSL.
* Further cleanup of the DTLS record handling.
* Continue the replacement of the TLSv1.2 record layer by
reimplementing the read side of the TLSv1.2 record handling.
* Replace DTLSv1_enc_data() with TLSv1_1_enc_data().
* Merge d1_{clnt,srvr}.c into ssl_{clnt,srvr}.c.
* When switching from the TLSv1.3 stack to the legacy stack include
a TLS record header. This is necessary if there is more than one
handshake message in the TLS plaintext record.
* Set SO_REUSEADDR on the server socket in the openssl(1) ocsp
command.
* Fix resource handling on error in OCSP_request_add0_id().
* Add const to ssl_ciphers and tls1[23]_sigalgs* to push them into
.data.rel.ro and .rodata, respectively.
* Add a const qualifier to srtp_known_profiles.
* Simplify TLS method by removing the client and server specific
methods internally.
* Avoid casting away const in ssl_ctx_make_profiles().
* Make sure there is enough room for stashing the handshake message
when switching to the legacy TLS stack.
* Avoid explicitly conditioning an assert on DTLS1_VERSION to make
the assert work for newer DTLS versions.
* Merge SSL_ENC_METHOD into SSL_METHOD_INTERNAL.
* Send a host header with OCSP queries to make openssl(1) ocsp
work with some widely used OCSP responders.
* Fix a memory leak in the openssl(1) s_client.
* Add a flag to mark DTLS methods as DTLS to have an easy way to
recognize DTLS methods that avoids inspecting the version number.
* Implement SSL_is_dtls() and use it internally in place of the
SSL_IS_DTLS macro.
* Unbreak DTLS retransmissions for flights that include a CCS.
* Add ability to ocspcheck(8) to parse a port in the specified
OCSP URL.
* Refactor and clean up ocspcheck(8) and add regression tests.
* If x509_verify() fails, ensure that the error is set on both
the x509_verify_ctx() and its store context to make some failures
visible from SSL_get_verify_result().
* Use the X509_STORE_CTX get_issuer() callback from the new X.509
verifier to fix hashed certificate directories.
* Only check BIO_should_read() on read and BIO_should_write() on
write. Previously, BIO_should_write() was also checked after read
and BIO_should_read() after write which could cause stalls in
software that uses the same BIO for read and write.
* In openssl(1) verify, also check for error on the store context
since the return value of X509_verify_cert() is unreliable in
presence of a callback that returns 1 too often.
* Update getentropy on Windows to use Cryptography Next Generation
(CNG). wincrypt is deprecated and no longer works with newer Windows
environments, such as in Windows Store apps.
* Implement auto chain for the TLSv1.3 server since some software
relies on this.
* Handle additional certificate error cases in the new X.509 verifier.
Keep track of the errors encountered if a verify callback tells the
verifier to continue and report them back via the error on the store
context. This mimics the behavior of the old verifier that would
persist the first error encountered while building the chain.
* Report specific failures for "self signed certificates" in a way
compatible with the old verifier since software relies on the
error code.
* Implement key exporter for TLSv1.3.
* Plug a large memory leak in the new verifier caused by calling
X509_policy_check() repeatedly.
* Avoid leaking memory in x509_verify_chain_dup().
* Various documentation improvements, particularly around TLS methods.
3.2.3 - Security fix
* Malformed ASN.1 in a certificate revocation list or a timestamp
response token can lead to a NULL pointer dereference.
3.2.2 - Stable release
* This is the first stable release with the new TLSv1.3
@ -279,6 +1077,11 @@ LibreSSL Portable Release Notes:
* Use non-expired certificates first when building a certificate chain.
3.1.5 - Security fix
* Malformed ASN.1 in a certificate revocation list or a timestamp
response token can lead to a NULL pointer dereference.
3.1.4 - Interoperability and bug fixes for the TLSv1.3 client:
* Improve client certificate selection to allow EC certificates

View file

@ -1,4 +1,4 @@
Built from https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.2.2.tar.gz
Built from https://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-3.5.2.tar.gz
Modifications:
- Removed tests/mandocs/pkgconfig/scripts/apps/cmake_uninstall from both filesystem and CMakeLists.txt
@ -9,7 +9,12 @@ Modifications:
![LibreSSL image](https://www.libressl.org/images/libressl.jpg)
## Official portable version of [LibreSSL](https://www.libressl.org) ##
[![Build Status](https://travis-ci.org/libressl-portable/portable.svg?branch=master)](https://travis-ci.org/libressl-portable/portable) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libressl.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libressl)
[![Linux Build Status](https://github.com/libressl-portable/portable/actions/workflows/linux_test.yml/badge.svg)](https://github.com/libressl-portable/portable/actions/workflows/linux_test.yml)
[![macOS Build Status](https://github.com/libressl-portable/portable/actions/workflows/macos_test.yml/badge.svg)](https://github.com/libressl-portable/portable/actions/workflows/macos_test.yml)
[![Android_Build Status](https://github.com/libressl-portable/portable/actions/workflows/android_test.yml/badge.svg)](https://github.com/libressl-portable/portable/actions/workflows/android_test.yml)
[![Cross_Build Status](https://github.com/libressl-portable/portable/actions/workflows/cross_test.yml/badge.svg)](https://github.com/libressl-portable/portable/actions/workflows/cross_test.yml)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/libressl.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:libressl)
[![ASan Status](https://github.com/libressl-portable/portable/actions/workflows/linux_test_asan.yml/badge.svg)](https://github.com/libressl-portable/portable/actions/workflows/linux_test_asan.yml)
LibreSSL is a fork of [OpenSSL](https://www.openssl.org) 1.0.1g developed by the
[OpenBSD](https://www.openbsd.org) project. Our goal is to modernize the codebase,
@ -45,9 +50,9 @@ At the time of this writing, LibreSSL is known to build and work on:
* AIX (5.3 and later)
LibreSSL also supports the following Windows environments:
* Microsoft Windows (Vista or higher, x86 and x64)
* Microsoft Windows (Windows 7 / Windows Server 2008r2 or later, x86 and x64)
* Wine (32-bit and 64-bit)
* Builds with Mingw-w64, Cygwin, and Visual Studio
* Mingw-w64, Cygwin, and Visual Studio
Official release tarballs are available at your friendly neighborhood
OpenBSD mirror in directory

View file

@ -1,2 +1,2 @@
3.2.2
3.5.2

5950
externals/libressl/cert.pem vendored Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
add_definitions(-DLIBRESSL_CRYPTO_INTERNAL)
if(HOST_ASM_ELF_ARMV4)
set(
ASM_ARMV4_ELF_SRC
@ -231,6 +233,7 @@ set(
malloc-wrapper.c
mem_clr.c
mem_dbg.c
o_fips.c
o_init.c
o_str.c
o_time.c
@ -242,49 +245,38 @@ set(
aes/aes_ofb.c
aes/aes_wrap.c
asn1/a_bitstr.c
asn1/a_bool.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_pkey.c
asn1/a_print.c
asn1/a_sign.c
asn1/a_pubkey.c
asn1/a_strex.c
asn1/a_string.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_item.c
asn1/asn1_lib.c
asn1/asn1_old.c
asn1/asn1_old_lib.c
asn1/asn1_par.c
asn1/asn1_types.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
@ -306,7 +298,6 @@ set(
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
@ -370,6 +361,9 @@ set(
buffer/buf_err.c
buffer/buf_str.c
buffer/buffer.c
bytestring/bs_ber.c
bytestring/bs_cbb.c
bytestring/bs_cbs.c
camellia/cmll_cfb.c
camellia/cmll_ctr.c
camellia/cmll_ecb.c
@ -409,6 +403,16 @@ set(
conf/conf_mall.c
conf/conf_mod.c
conf/conf_sap.c
ct/ct_b64.c
ct/ct_err.c
ct/ct_log.c
ct/ct_oct.c
ct/ct_policy.c
ct/ct_prn.c
ct/ct_sct.c
ct/ct_sct_ctx.c
ct/ct_vfy.c
ct/ct_x509v3.c
curve25519/curve25519-generic.c
curve25519/curve25519.c
des/cbc_cksm.c
@ -550,9 +554,6 @@ set(
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
@ -636,7 +637,6 @@ set(
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
@ -726,9 +726,11 @@ set(
x509/pcy_map.c
x509/pcy_node.c
x509/pcy_tree.c
x509/x509_addr.c
x509/x509_akey.c
x509/x509_akeya.c
x509/x509_alt.c
x509/x509_asid.c
x509/x509_att.c
x509/x509_bcons.c
x509/x509_bitst.c
@ -875,6 +877,11 @@ if(NOT HAVE_STRSEP)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strsep)
endif()
if(NOT HAVE_STRTONUM)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/strtonum.c)
set(EXTRA_EXPORT ${EXTRA_EXPORT} strtonum)
endif()
if(NOT HAVE_SYSLOG_R)
set(CRYPTO_SRC ${CRYPTO_SRC} compat/syslog_r.c)
endif()
@ -968,22 +975,33 @@ if(EXTRA_EXPORT)
endforeach()
endif()
add_library(crypto ${CRYPTO_SRC})
target_include_directories(crypto
set(LIBTLS_EXTRA_EXPORT ${EXTRA_EXPORT} PARENT_SCOPE)
add_library(crypto_obj OBJECT ${CRYPTO_SRC})
target_include_directories(crypto_obj
PRIVATE
.
asn1
bio
bn
bytestring
dh
dsa
ec
ecdh
ecdsa
evp
hmac
modes
ocsp
rsa
x509
../include/compat
PUBLIC
../include)
add_library(crypto $<TARGET_OBJECTS:crypto_obj>)
export_symbol(crypto ${CMAKE_CURRENT_BINARY_DIR}/crypto_p.sym)
target_link_libraries(crypto ${PLATFORM_LIBS})
if (WIN32)
@ -1003,3 +1021,10 @@ if(ENABLE_LIBRESSL_INSTALL)
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
endif(ENABLE_LIBRESSL_INSTALL)
# build static library for regression test
if(BUILD_SHARED_LIBS)
add_library(crypto-static STATIC $<TARGET_OBJECTS:crypto_obj>)
target_link_libraries(crypto-static ${PLATFORM_LIBS})
endif()

View file

@ -1 +1 @@
46:1:0
49:0:0

View file

@ -1,7 +1,7 @@
; 1 "crypto/aes/aes-masm-x86_64.S.tmp"
; 1 "<built-in>" 1
; 1 "<built-in>" 3
; 340 "<built-in>" 3
; 343 "<built-in>" 3
; 1 "<command line>" 1
; 1 "<built-in>" 2
; 1 "crypto/aes/aes-masm-x86_64.S.tmp" 2

View file

@ -1,4 +1,4 @@
/* $OpenBSD: aes_ige.c,v 1.7 2015/02/10 09:46:30 miod Exp $ */
/* $OpenBSD: aes_ige.c,v 1.8 2022/01/22 00:43:41 inoguchi Exp $ */
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
@ -109,8 +109,8 @@ AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length,
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);
memmove(ivec, ivp->data, AES_BLOCK_SIZE);
memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
} else {
aes_block_t tmp, tmp2;
aes_block_t iv;
@ -161,8 +161,8 @@ AES_ige_encrypt(const unsigned char *in, unsigned char *out, size_t length,
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);
memmove(ivec, ivp->data, AES_BLOCK_SIZE);
memmove(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
} else {
aes_block_t tmp, tmp2;
aes_block_t iv;

View file

@ -1,7 +1,7 @@
; 1 "crypto/aes/aesni-masm-x86_64.S.tmp"
; 1 "<built-in>" 1
; 1 "<built-in>" 3
; 340 "<built-in>" 3
; 343 "<built-in>" 3
; 1 "<command line>" 1
; 1 "<built-in>" 2
; 1 "crypto/aes/aesni-masm-x86_64.S.tmp" 2

View file

@ -1,7 +1,7 @@
; 1 "crypto/aes/aesni-sha1-masm-x86_64.S.tmp"
; 1 "<built-in>" 1
; 1 "<built-in>" 3
; 340 "<built-in>" 3
; 343 "<built-in>" 3
; 1 "<command line>" 1
; 1 "<built-in>" 2
; 1 "crypto/aes/aesni-sha1-masm-x86_64.S.tmp" 2

View file

@ -1,7 +1,7 @@
; 1 "crypto/aes/bsaes-masm-x86_64.S.tmp"
; 1 "<built-in>" 1
; 1 "<built-in>" 3
; 340 "<built-in>" 3
; 343 "<built-in>" 3
; 1 "<command line>" 1
; 1 "<built-in>" 2
; 1 "crypto/aes/bsaes-masm-x86_64.S.tmp" 2

View file

@ -1,7 +1,7 @@
; 1 "crypto/aes/vpaes-masm-x86_64.S.tmp"
; 1 "<built-in>" 1
; 1 "<built-in>" 3
; 340 "<built-in>" 3
; 343 "<built-in>" 3
; 1 "<command line>" 1
; 1 "<built-in>" 2
; 1 "crypto/aes/vpaes-masm-x86_64.S.tmp" 2

View file

@ -1,4 +1,4 @@
/* $OpenBSD: arm_arch.h,v 1.10 2019/07/02 19:31:28 patrick Exp $ */
/* $OpenBSD: arm_arch.h,v 1.1 2022/03/23 15:13:31 tb Exp $ */
#ifndef __ARM_ARCH_H__
#define __ARM_ARCH_H__

View file

@ -1,4 +1,4 @@
/* $OpenBSD: armcap.c,v 1.8 2019/03/13 10:18:30 patrick Exp $ */
/* $OpenBSD: armcap.c,v 1.1 2022/03/23 15:13:31 tb Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_bitstr.c,v 1.30 2020/09/03 17:19:27 tb Exp $ */
/* $OpenBSD: a_bitstr.c,v 1.33 2021/12/25 08:52:44 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -60,7 +60,28 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/x509v3.h>
const ASN1_ITEM ASN1_BIT_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BIT_STRING,
.sname = "ASN1_BIT_STRING",
};
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);
}
int
ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
@ -68,6 +89,127 @@ ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
return ASN1_STRING_set(x, d, len);
}
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 */
if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
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(const 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(const ASN1_BIT_STRING *a, const 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;
}
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, const 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(const 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;
}
int
i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
{
@ -192,73 +334,14 @@ c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **pp, long len)
}
int
ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
i2d_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **out)
{
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 */
if ((c = recallocarray(a->data, a->length, w + 1, 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
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);
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_BIT_STRING_it);
}
int
ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
ASN1_BIT_STRING *
d2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, const unsigned char **in, long len)
{
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(const ASN1_BIT_STRING *a, const 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;
return (ASN1_BIT_STRING *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&ASN1_BIT_STRING_it);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_enum.c,v 1.20 2019/04/28 05:05:56 tb Exp $ */
/* $OpenBSD: a_enum.c,v 1.23 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -60,7 +60,9 @@
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
/*
@ -68,6 +70,24 @@
* for comments on encoding see a_int.c
*/
const ASN1_ITEM ASN1_ENUMERATED_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_ENUMERATED,
.sname = "ASN1_ENUMERATED",
};
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);
}
int
ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
{
@ -175,7 +195,7 @@ BN_to_ASN1_ENUMERATED(const BIGNUM *bn, ASN1_ENUMERATED *ai)
}
return (ret);
err:
err:
if (ret != ai)
ASN1_ENUMERATED_free(ret);
return (NULL);
@ -192,3 +212,143 @@ ASN1_ENUMERATED_to_BN(const ASN1_ENUMERATED *ai, BIGNUM *bn)
BN_set_negative(ret, 1);
return (ret);
}
/* Based on a_int.c: equivalent ENUMERATED functions */
int
i2a_ASN1_ENUMERATED(BIO *bp, const 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;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
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;
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);
}
int
i2d_ASN1_ENUMERATED(ASN1_ENUMERATED *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ENUMERATED_it);
}
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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_int.c,v 1.34 2019/04/28 05:03:56 tb Exp $ */
/* $OpenBSD: a_int.c,v 1.38 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -61,9 +61,29 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
const ASN1_ITEM ASN1_INTEGER_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_INTEGER,
.sname = "ASN1_INTEGER",
};
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);
}
static int
ASN1_INTEGER_valid(const ASN1_INTEGER *a)
{
@ -101,6 +121,276 @@ ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
return ret;
}
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);
}
/*
* XXX this particular API is a gibbering eidrich horror that makes it
* impossible to determine valid return cases from errors.. "a bit
* ugly" is preserved for posterity, unfortunately this is probably
* unfixable without changing public API
*/
long
ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
unsigned 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 (!ASN1_INTEGER_valid(a))
return -1; /* XXX best effort */
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 (r > LONG_MAX)
return -1;
if (neg)
return -(long)r;
return (long)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 (!ASN1_INTEGER_valid(ret))
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 (!ASN1_INTEGER_valid(ai))
return (NULL);
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);
}
int
i2a_ASN1_INTEGER(BIO *bp, const 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;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
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;
if (i % 2 != 0) {
ASN1error(ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i /= 2;
if (num + i > slen) {
if ((sp = recallocarray(s, slen, num + i, 1)) == 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);
}
/*
* This converts an ASN1 INTEGER into its content encoding.
@ -289,13 +579,25 @@ c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, long len)
*pp = pend;
return (ret);
err:
err:
ASN1error(i);
if (a == NULL || *a != ret)
ASN1_INTEGER_free(ret);
return (NULL);
}
int
i2d_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_INTEGER_it);
}
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);
}
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
* ASN1 integers: some broken software can encode a positive INTEGER
@ -364,151 +666,9 @@ d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, long length)
*pp = p;
return (ret);
err:
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);
}
/*
* XXX this particular API is a gibbering eidrich horror that makes it
* impossible to determine valid return cases from errors.. "a bit
* ugly" is preserved for posterity, unfortunately this is probably
* unfixable without changing public API
*/
long
ASN1_INTEGER_get(const ASN1_INTEGER *a)
{
int neg = 0, i;
unsigned 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 (!ASN1_INTEGER_valid(a))
return -1; /* XXX best effort */
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 (r > LONG_MAX)
return -1;
if (neg)
return -(long)r;
return (long)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 (!ASN1_INTEGER_valid(ret))
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 (!ASN1_INTEGER_valid(ai))
return (NULL);
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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_mbstr.c,v 1.23 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: a_mbstr.c,v 1.24 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -248,7 +248,7 @@ ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
traverse_string(in, len, inform, cpyfunc, &p);
return str_type;
err:
err:
if (free_out) {
ASN1_STRING_free(dest);
*out = NULL;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_object.c,v 1.31 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: a_object.c,v 1.46 2022/04/10 12:42:33 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -61,308 +61,31 @@
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/buffer.h>
#include <openssl/objects.h>
int
i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
{
unsigned char *p;
int objsize;
#include "asn1_locl.h"
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, const ASN1_OBJECT *a)
{
return OBJ_obj2txt(buf, buf_len, a, 0);
}
int
i2a_ASN1_OBJECT(BIO *bp, const 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);
}
const ASN1_ITEM ASN1_OBJECT_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OBJECT,
.sname = "ASN1_OBJECT",
};
ASN1_OBJECT *
ASN1_OBJECT_new(void)
{
ASN1_OBJECT *ret;
ASN1_OBJECT *a;
ret = malloc(sizeof(ASN1_OBJECT));
if (ret == NULL) {
if ((a = calloc(1, sizeof(ASN1_OBJECT))) == 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);
a->flags = ASN1_OBJECT_FLAG_DYNAMIC;
return a;
}
void
@ -399,3 +122,539 @@ ASN1_OBJECT_create(int nid, unsigned char *data, int len,
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
return (OBJ_dup(&o));
}
static int
oid_add_arc(CBB *cbb, uint64_t arc)
{
int started = 0;
uint8_t val;
int i;
for (i = (sizeof(arc) * 8) / 7; i >= 0; i--) {
val = (arc >> (i * 7)) & 0x7f;
if (!started && i != 0 && val == 0)
continue;
if (i > 0)
val |= 0x80;
if (!CBB_add_u8(cbb, val))
return 0;
started = 1;
}
return 1;
}
static int
oid_parse_arc(CBS *cbs, uint64_t *out_arc)
{
uint64_t arc = 0;
uint8_t val;
do {
if (!CBS_get_u8(cbs, &val))
return 0;
if (arc == 0 && val == 0x80)
return 0;
if (out_arc != NULL && arc > (UINT64_MAX >> 7))
return 0;
arc = (arc << 7) | (val & 0x7f);
} while (val & 0x80);
if (out_arc != NULL)
*out_arc = arc;
return 1;
}
static int
oid_add_arc_txt(CBB *cbb, uint64_t arc, int first)
{
const char *fmt = ".%llu";
char s[22]; /* Digits in decimal representation of 2^64-1, plus '.' and NUL. */
int n;
if (first)
fmt = "%llu";
n = snprintf(s, sizeof(s), fmt, (unsigned long long)arc);
if (n < 0 || (size_t)n >= sizeof(s))
return 0;
if (!CBB_add_bytes(cbb, s, n))
return 0;
return 1;
}
static int
oid_parse_arc_txt(CBS *cbs, uint64_t *out_arc, char *separator, int first)
{
uint64_t arc = 0;
int digits = 0;
uint8_t val;
if (!first) {
if (!CBS_get_u8(cbs, &val))
return 0;
if ((*separator == 0 && val != '.' && val != ' ') ||
(*separator != 0 && val != *separator)) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
return 0;
}
*separator = val;
}
while (CBS_len(cbs) > 0) {
if (!CBS_peek_u8(cbs, &val))
return 0;
if (val == '.' || val == ' ')
break;
if (!CBS_get_u8(cbs, &val))
return 0;
if (val < '0' || val > '9') {
/* For the first arc we treat this as the separator. */
if (first) {
ASN1error(ASN1_R_INVALID_SEPARATOR);
return 0;
}
ASN1error(ASN1_R_INVALID_DIGIT);
return 0;
}
val -= '0';
if (digits > 0 && arc == 0 && val == 0) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
digits++;
if (arc > UINT64_MAX / 10) {
ASN1error(ASN1_R_TOO_LONG);
return 0;
}
arc = arc * 10 + val;
}
if (digits < 1) {
ASN1error(ASN1_R_INVALID_NUMBER);
return 0;
}
*out_arc = arc;
return 1;
}
static int
a2c_ASN1_OBJECT_internal(CBB *cbb, CBS *cbs)
{
uint64_t arc, si1, si2;
char separator = 0;
if (!oid_parse_arc_txt(cbs, &si1, &separator, 1))
return 0;
if (CBS_len(cbs) == 0) {
ASN1error(ASN1_R_MISSING_SECOND_NUMBER);
return 0;
}
if (!oid_parse_arc_txt(cbs, &si2, &separator, 0))
return 0;
/*
* X.690 section 8.19 - the first two subidentifiers are encoded as
* (x * 40) + y, with x being limited to [0,1,2]. The second
* subidentifier cannot exceed 39 for x < 2.
*/
if (si1 > 2) {
ASN1error(ASN1_R_FIRST_NUM_TOO_LARGE);
return 0;
}
if ((si1 < 2 && si2 >= 40) || si2 > UINT64_MAX - si1 * 40) {
ASN1error(ASN1_R_SECOND_NUMBER_TOO_LARGE);
return 0;
}
arc = si1 * 40 + si2;
if (!oid_add_arc(cbb, arc))
return 0;
while (CBS_len(cbs) > 0) {
if (!oid_parse_arc_txt(cbs, &arc, &separator, 0))
return 0;
if (!oid_add_arc(cbb, arc))
return 0;
}
return 1;
}
static int
c2a_ASN1_OBJECT(CBS *cbs, CBB *cbb)
{
uint64_t arc, si1, si2;
/*
* X.690 section 8.19 - the first two subidentifiers are encoded as
* (x * 40) + y, with x being limited to [0,1,2].
*/
if (!oid_parse_arc(cbs, &arc))
return 0;
if ((si1 = arc / 40) > 2)
si1 = 2;
si2 = arc - si1 * 40;
if (!oid_add_arc_txt(cbb, si1, 1))
return 0;
if (!oid_add_arc_txt(cbb, si2, 0))
return 0;
while (CBS_len(cbs) > 0) {
if (!oid_parse_arc(cbs, &arc))
return 0;
if (!oid_add_arc_txt(cbb, arc, 0))
return 0;
}
/* NUL terminate. */
if (!CBB_add_u8(cbb, 0))
return 0;
return 1;
}
int
a2d_ASN1_OBJECT(unsigned char *out, int out_len, const char *in, int in_len)
{
uint8_t *data = NULL;
size_t data_len;
CBS cbs;
CBB cbb;
int ret = 0;
memset(&cbb, 0, sizeof(cbb));
if (in_len == -1)
in_len = strlen(in);
if (in_len <= 0)
goto err;
CBS_init(&cbs, in, in_len);
if (!CBB_init(&cbb, 0))
goto err;
if (!a2c_ASN1_OBJECT_internal(&cbb, &cbs))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if (out != NULL) {
if (out_len <= 0 || (size_t)out_len < data_len) {
ASN1error(ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
memcpy(out, data, data_len);
}
ret = (int)data_len;
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
static int
i2t_ASN1_OBJECT_oid(const ASN1_OBJECT *aobj, CBB *cbb)
{
CBS cbs;
CBS_init(&cbs, aobj->data, aobj->length);
return c2a_ASN1_OBJECT(&cbs, cbb);
}
static int
i2t_ASN1_OBJECT_name(const ASN1_OBJECT *aobj, CBB *cbb, const char **out_name)
{
const char *name;
int nid;
*out_name = NULL;
if ((nid = OBJ_obj2nid(aobj)) == NID_undef)
return 0;
if ((name = OBJ_nid2ln(nid)) == NULL)
name = OBJ_nid2sn(nid);
if (name == NULL)
return 0;
*out_name = name;
if (!CBB_add_bytes(cbb, name, strlen(name)))
return 0;
/* NUL terminate. */
if (!CBB_add_u8(cbb, 0))
return 0;
return 1;
}
static int
i2t_ASN1_OBJECT_cbb(const ASN1_OBJECT *aobj, CBB *cbb, int no_name)
{
const char *name;
if (!no_name) {
if (i2t_ASN1_OBJECT_name(aobj, cbb, &name))
return 1;
if (name != NULL)
return 0;
}
return i2t_ASN1_OBJECT_oid(aobj, cbb);
}
int
i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len, int no_name)
{
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
int ret = 0;
if (buf_len < 0)
return 0;
if (buf_len > 0)
buf[0] = '\0';
if (!CBB_init(&cbb, 0))
goto err;
if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, no_name))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
ret = strlcpy(buf, data, buf_len);
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
int
i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *aobj)
{
return i2t_ASN1_OBJECT_internal(aobj, buf, buf_len, 0);
}
ASN1_OBJECT *
t2i_ASN1_OBJECT_internal(const char *oid)
{
ASN1_OBJECT *aobj = NULL;
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
CBS cbs;
memset(&cbb, 0, sizeof(cbb));
CBS_init(&cbs, oid, strlen(oid));
if (!CBB_init(&cbb, 0))
goto err;
if (!a2c_ASN1_OBJECT_internal(&cbb, &cbs))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if ((aobj = ASN1_OBJECT_new()) == NULL)
goto err;
aobj->data = data;
aobj->length = (int)data_len;
aobj->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
data = NULL;
err:
CBB_cleanup(&cbb);
free(data);
return aobj;
}
int
i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *aobj)
{
uint8_t *data = NULL;
size_t data_len;
CBB cbb;
int ret = -1;
if (aobj == NULL || aobj->data == NULL)
return BIO_write(bp, "NULL", 4);
if (!CBB_init(&cbb, 0))
goto err;
if (!i2t_ASN1_OBJECT_cbb(aobj, &cbb, 0)) {
ret = BIO_write(bp, "<INVALID>", 9);
goto err;
}
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
ret = BIO_write(bp, data, strlen(data));
err:
CBB_cleanup(&cbb);
free(data);
return ret;
}
int
c2i_ASN1_OBJECT_cbs(ASN1_OBJECT **out_aobj, CBS *content)
{
ASN1_OBJECT *aobj = NULL;
uint8_t *data = NULL;
size_t data_len;
CBS cbs;
if (out_aobj == NULL || *out_aobj != NULL)
goto err;
/* Parse and validate OID encoding per X.690 8.19.2. */
CBS_dup(content, &cbs);
if (CBS_len(&cbs) == 0) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
goto err;
}
while (CBS_len(&cbs) > 0) {
if (!oid_parse_arc(&cbs, NULL)) {
ASN1error(ASN1_R_INVALID_OBJECT_ENCODING);
goto err;
}
}
if (!CBS_stow(content, &data, &data_len))
goto err;
if (data_len > INT_MAX)
goto err;
if ((aobj = ASN1_OBJECT_new()) == NULL)
goto err;
aobj->data = data;
aobj->length = (int)data_len; /* XXX - change length to size_t. */
aobj->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
*out_aobj = aobj;
return 1;
err:
ASN1_OBJECT_free(aobj);
free(data);
return 0;
}
ASN1_OBJECT *
c2i_ASN1_OBJECT(ASN1_OBJECT **out_aobj, const unsigned char **pp, long len)
{
ASN1_OBJECT *aobj = NULL;
CBS content;
if (out_aobj != NULL) {
ASN1_OBJECT_free(*out_aobj);
*out_aobj = NULL;
}
if (len < 0) {
ASN1error(ASN1_R_LENGTH_ERROR);
return NULL;
}
CBS_init(&content, *pp, len);
if (!c2i_ASN1_OBJECT_cbs(&aobj, &content))
return NULL;
*pp = CBS_data(&content);
if (out_aobj != NULL)
*out_aobj = aobj;
return aobj;
}
int
i2d_ASN1_OBJECT(const 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);
}
ASN1_OBJECT *
d2i_ASN1_OBJECT(ASN1_OBJECT **out_aobj, const unsigned char **pp, long length)
{
ASN1_OBJECT *aobj = NULL;
uint32_t tag_number;
CBS cbs, content;
if (out_aobj != NULL) {
ASN1_OBJECT_free(*out_aobj);
*out_aobj = NULL;
}
if (length < 0) {
ASN1error(ASN1_R_LENGTH_ERROR);
return NULL;
}
CBS_init(&cbs, *pp, length);
if (!asn1_get_primitive(&cbs, 0, &tag_number, &content)) {
ASN1error(ASN1_R_BAD_OBJECT_HEADER);
return NULL;
}
if (tag_number != V_ASN1_OBJECT) {
ASN1error(ASN1_R_EXPECTING_AN_OBJECT);
return NULL;
}
if (!c2i_ASN1_OBJECT_cbs(&aobj, &content))
return NULL;
*pp = CBS_data(&content);
if (out_aobj != NULL)
*out_aobj = aobj;
return aobj;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_octet.c,v 1.10 2015/07/29 14:58:34 jsing Exp $ */
/* $OpenBSD: a_octet.c,v 1.11 2021/12/25 08:52:44 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -59,6 +59,26 @@
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
const ASN1_ITEM ASN1_OCTET_STRING_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_OCTET_STRING,
.sname = "ASN1_OCTET_STRING",
};
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);
}
ASN1_OCTET_STRING *
ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
@ -77,3 +97,16 @@ ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
{
return ASN1_STRING_set(x, d, len);
}
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 *
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);
}

186
externals/libressl/crypto/asn1/a_pkey.c vendored Executable file
View file

@ -0,0 +1,186 @@
/* $OpenBSD: a_pkey.c,v 1.3 2021/12/25 13:17:48 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/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"
#include "evp_locl.h"
EVP_PKEY *
d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, long length)
{
const unsigned char *p = *pp;
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
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;
*pp = p; /* XXX */
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);
}
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);
}
/* 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);
}

160
externals/libressl/crypto/asn1/a_pubkey.c vendored Executable file
View file

@ -0,0 +1,160 @@
/* $OpenBSD: a_pubkey.c,v 1.3 2021/12/25 13:17:48 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/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
#include "evp_locl.h"
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);
}
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);
}
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_strex.c,v 1.28 2018/05/19 10:46:28 tb Exp $ */
/* $OpenBSD: a_strex.c,v 1.31 2021/12/25 12:11:57 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -322,22 +322,6 @@ do_dump(unsigned long lflags, char_io *io_ch, void *arg, const ASN1_STRING *str)
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
@ -371,19 +355,16 @@ do_print_ex(char_io *io_ch, void *arg, unsigned long lflags,
/* Decide what to do with type, either dump content or display it */
/* Dump everything */
if (lflags & ASN1_STRFLGS_DUMP_ALL)
if (lflags & ASN1_STRFLGS_DUMP_ALL) {
/* Dump everything. */
type = -1;
/* Ignore the string type */
else if (lflags & ASN1_STRFLGS_IGNORE_TYPE)
} else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) {
/* Ignore the string 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))
} else {
/* Else determine width based on type. */
type = asn1_tag2charwidth(type);
if (type == -1 && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN))
type = 1;
}
@ -513,7 +494,7 @@ do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, int indent,
else
ent = X509_NAME_get_entry(n, i);
if (prev != -1) {
if (prev == ent->set) {
if (prev == X509_NAME_ENTRY_set(ent)) {
if (!io_ch(arg, sep_mv, sep_mv_len))
return -1;
outlen += sep_mv_len;
@ -526,7 +507,7 @@ do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, int indent,
outlen += indent;
}
}
prev = ent->set;
prev = X509_NAME_ENTRY_set(ent);
fn = X509_NAME_ENTRY_get_object(ent);
val = X509_NAME_ENTRY_get_data(ent);
fn_nid = OBJ_obj2nid(fn);
@ -618,32 +599,3 @@ ASN1_STRING_print_ex_fp(FILE *fp, const 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, const 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;
}

423
externals/libressl/crypto/asn1/a_string.c vendored Executable file
View file

@ -0,0 +1,423 @@
/* $OpenBSD: a_string.c,v 1.7 2022/03/17 17:17:58 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 <limits.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "asn1_locl.h"
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 *astr;
if ((astr = calloc(1, sizeof(ASN1_STRING))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
astr->type = type;
return astr;
}
static void
ASN1_STRING_clear(ASN1_STRING *astr)
{
if (!(astr->flags & ASN1_STRING_FLAG_NDEF))
freezero(astr->data, astr->length);
astr->flags &= ~ASN1_STRING_FLAG_NDEF;
astr->data = NULL;
astr->length = 0;
}
void
ASN1_STRING_free(ASN1_STRING *astr)
{
if (astr == NULL)
return;
ASN1_STRING_clear(astr);
free(astr);
}
int
ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
{
int cmp;
if (a == NULL || b == NULL)
return -1;
if ((cmp = (a->length - b->length)) != 0)
return cmp;
if ((cmp = memcmp(a->data, b->data, a->length)) != 0)
return cmp;
return (a->type - b->type);
}
int
ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *src)
{
if (src == NULL)
return 0;
if (!ASN1_STRING_set(dst, src->data, src->length))
return 0;
dst->type = src->type;
dst->flags = src->flags & ~ASN1_STRING_FLAG_NDEF;
return 1;
}
ASN1_STRING *
ASN1_STRING_dup(const ASN1_STRING *src)
{
ASN1_STRING *astr;
if (src == NULL)
return NULL;
if ((astr = ASN1_STRING_new()) == NULL)
return NULL;
if (!ASN1_STRING_copy(astr, src)) {
ASN1_STRING_free(astr);
return NULL;
}
return astr;
}
int
ASN1_STRING_set(ASN1_STRING *astr, const void *_data, int len)
{
const char *data = _data;
if (len == -1) {
size_t slen;
if (data == NULL)
return 0;
if ((slen = strlen(data)) > INT_MAX)
return 0;
len = (int)slen;
}
ASN1_STRING_clear(astr);
if (len < 0 || len >= INT_MAX)
return 0;
if ((astr->data = calloc(1, len + 1)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
astr->length = len;
if (data != NULL) {
memcpy(astr->data, data, len);
astr->data[len] = '\0';
}
return 1;
}
void
ASN1_STRING_set0(ASN1_STRING *astr, void *data, int len)
{
ASN1_STRING_clear(astr);
astr->data = data;
astr->length = len;
}
void
asn1_add_error(const unsigned char *address, int offset)
{
ERR_asprintf_error_data("offset=%d", offset);
}
int
ASN1_STRING_length(const ASN1_STRING *astr)
{
return astr->length;
}
void
ASN1_STRING_length_set(ASN1_STRING *astr, int len)
{
/* This is dangerous and unfixable. */
astr->length = len;
}
int
ASN1_STRING_type(const ASN1_STRING *astr)
{
return astr->type;
}
unsigned char *
ASN1_STRING_data(ASN1_STRING *astr)
{
return astr->data;
}
const unsigned char *
ASN1_STRING_get0_data(const ASN1_STRING *astr)
{
return astr->data;
}
int
ASN1_STRING_print(BIO *bp, const ASN1_STRING *astr)
{
int i, n;
char buf[80];
const char *p;
if (astr == NULL)
return 0;
n = 0;
p = (const char *)astr->data;
for (i = 0; i < astr->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;
}
/*
* 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, const ASN1_STRING *in)
{
ASN1_STRING stmp, *str = &stmp;
int mbflag, ret;
if (in == NULL)
return -1;
if ((mbflag = asn1_tag2charwidth(in->type)) == -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;
}
int
i2a_ASN1_STRING(BIO *bp, const ASN1_STRING *astr, int type)
{
int i, n = 0;
static const char h[] = "0123456789ABCDEF";
char buf[2];
if (astr == NULL)
return 0;
if (astr->length == 0) {
if (BIO_write(bp, "0", 1) != 1)
goto err;
n = 1;
} else {
for (i = 0; i < astr->length; i++) {
if ((i != 0) && (i % 35 == 0)) {
if (BIO_write(bp, "\\\n", 2) != 2)
goto err;
n += 2;
}
buf[0] = h[((unsigned char)astr->data[i] >> 4) & 0x0f];
buf[1] = h[((unsigned char)astr->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 *astr, 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;
if (buf[i - 1] == '\\') {
i--;
again = 1;
} else
again = 0;
buf[i] = '\0';
if (i < 2)
goto err_sl;
bufp = (unsigned char *)buf;
k = 0;
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;
}
astr->length = num;
astr->data = s;
return 1;
err_sl:
ASN1error(ASN1_R_SHORT_LINE);
err:
free(s);
return ret;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_strnid.c,v 1.21 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: a_strnid.c,v 1.25 2021/12/13 17:55:53 schwarze Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -56,8 +56,9 @@
*
*/
#include <ctype.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
@ -65,12 +66,15 @@
#include <openssl/objects.h>
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
static ASN1_STRING_TABLE *stable_get(int nid);
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
/*
* This is the global mask for the mbstring functions: this is used to
* mask out certain types (such as BMPString and UTF8String) because
* certain software (e.g. Netscape) has problems with them.
*/
@ -89,7 +93,8 @@ ASN1_STRING_get_default_mask(void)
return global_mask;
}
/* This function sets the default to various "flavours" of configuration.
/*
* 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).
@ -103,20 +108,26 @@ ASN1_STRING_set_default_mask_asc(const char *p)
{
unsigned long mask;
char *end;
int save_errno;
if (!strncmp(p, "MASK:", 5)) {
if (!p[5])
if (strncmp(p, "MASK:", 5) == 0) {
if (p[5] == '\0')
return 0;
save_errno = errno;
errno = 0;
mask = strtoul(p + 5, &end, 0);
if (*end)
if (errno == ERANGE && mask == ULONG_MAX)
return 0;
} else if (!strcmp(p, "nombstr"))
errno = save_errno;
if (*end != '\0')
return 0;
} else if (strcmp(p, "nombstr") == 0)
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
else if (!strcmp(p, "pkix"))
else if (strcmp(p, "pkix") == 0)
mask = ~((unsigned long)B_ASN1_T61STRING);
else if (!strcmp(p, "utf8only"))
else if (strcmp(p, "utf8only") == 0)
mask = B_ASN1_UTF8STRING;
else if (!strcmp(p, "default"))
else if (strcmp(p, "default") == 0)
mask = 0xFFFFFFFFL;
else
return 0;
@ -124,7 +135,8 @@ ASN1_STRING_set_default_mask_asc(const char *p)
return 1;
}
/* The following function generates an ASN1_STRING based on limits in a table.
/*
* 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.
*/
@ -137,12 +149,13 @@ ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
ASN1_STRING *str = NULL;
unsigned long mask;
int ret;
if (!out)
if (out == NULL)
out = &str;
tbl = ASN1_STRING_TABLE_get(nid);
if (tbl) {
if (tbl != NULL) {
mask = tbl->mask;
if (!(tbl->flags & STABLE_NO_MASK))
if ((tbl->flags & STABLE_NO_MASK) == 0)
mask &= global_mask;
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
tbl->minsize, tbl->maxsize);
@ -154,7 +167,8 @@ ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen,
return *out;
}
/* Now the tables and helper functions for the string table:
/*
* Now the tables and helper functions for the string table:
*/
/* size limits: this stuff is taken straight from RFC3280 */
@ -231,20 +245,59 @@ 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;
if (stable != NULL) {
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
if (idx < 0)
return NULL;
if (idx >= 0)
return sk_ASN1_STRING_TABLE_value(stable, idx);
}
return OBJ_bsearch_table(&fnd, tbl_standard,
sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
}
/*
* Return a string table pointer which can be modified: either directly
* from table or a copy of an internal value added to the table.
*/
static ASN1_STRING_TABLE *
stable_get(int nid)
{
ASN1_STRING_TABLE *tmp, *rv;
/* Always need a string table so allocate one if NULL */
if (stable == NULL) {
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if (stable == NULL)
return NULL;
}
tmp = ASN1_STRING_TABLE_get(nid);
if (tmp != NULL && (tmp->flags & STABLE_FLAGS_MALLOC) != 0)
return tmp;
if ((rv = calloc(1, sizeof(*rv))) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!sk_ASN1_STRING_TABLE_push(stable, rv)) {
free(rv);
return NULL;
}
if (tmp != NULL) {
rv->nid = tmp->nid;
rv->minsize = tmp->minsize;
rv->maxsize = tmp->maxsize;
rv->mask = tmp->mask;
rv->flags = tmp->flags | STABLE_FLAGS_MALLOC;
} else {
rv->nid = nid;
rv->minsize = -1;
rv->maxsize = -1;
rv->flags = STABLE_FLAGS_MALLOC;
}
return rv;
}
int
@ -252,37 +305,20 @@ 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) {
if ((tmp = stable_get(nid)) == NULL) {
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)
if (minsize >= 0)
tmp->minsize = minsize;
if (maxsize != -1)
if (maxsize >= 0)
tmp->maxsize = maxsize;
if (mask != 0)
tmp->mask = mask;
if (new_nid) {
if (sk_ASN1_STRING_TABLE_push(stable, tmp) == 0) {
free(tmp);
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
}
if (flags != 0)
tmp->flags = flags | STABLE_FLAGS_MALLOC;
return 1;
}
@ -292,7 +328,7 @@ ASN1_STRING_TABLE_cleanup(void)
STACK_OF(ASN1_STRING_TABLE) *tmp;
tmp = stable;
if (!tmp)
if (tmp == NULL)
return;
stable = NULL;
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_time.c,v 1.27 2015/10/19 16:32:37 beck Exp $ */
/* $OpenBSD: a_time.c,v 1.33 2021/12/25 07:48:09 jsing Exp $ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@ -80,6 +80,45 @@ const ASN1_ITEM ASN1_TIME_it = {
.sname = "ASN1_TIME",
};
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);
}
/* Public API in OpenSSL. Kept internal for now. */
static int
ASN1_TIME_to_tm(const ASN1_TIME *s, struct tm *tm)
{
time_t now;
if (s != NULL)
return ASN1_time_parse(s->data, s->length, tm, 0) != -1;
time(&now);
memset(tm, 0, sizeof(*tm));
return gmtime_r(&now, tm) != NULL;
}
int
ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to)
{
struct tm tm_from, tm_to;
if (!ASN1_TIME_to_tm(from, &tm_from))
return 0;
if (!ASN1_TIME_to_tm(to, &tm_to))
return 0;
return OPENSSL_gmtime_diff(pday, psec, &tm_from, &tm_to);
}
ASN1_TIME *
d2i_ASN1_TIME(ASN1_TIME **a, const unsigned char **in, long len)
@ -93,15 +132,3 @@ 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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_time_tm.c,v 1.15 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: a_time_tm.c,v 1.19 2022/03/31 13:04:47 tb Exp $ */
/*
* Copyright (c) 2015 Bob Beck <beck@openbsd.org>
*
@ -163,10 +163,9 @@ ASN1_time_parse(const char *bytes, size_t len, struct tm *tm, int mode)
return (-1);
lt = tm;
if (lt == NULL) {
memset(&ltm, 0, sizeof(ltm));
if (lt == NULL)
lt = &ltm;
}
memset(lt, 0, sizeof(*lt));
/* Timezone is required and must be GMT (Zulu). */
if (bytes[len - 1] != 'Z')
@ -260,7 +259,7 @@ ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
int allocated = 0;
struct tm tm;
size_t len;
char * p;
char *p;
if (gmtime_r(&t, &tm) == NULL)
return (NULL);
@ -289,8 +288,10 @@ ASN1_TIME_adj_internal(ASN1_TIME *s, time_t t, int offset_day, long offset_sec,
}
if (s == NULL) {
if ((s = ASN1_TIME_new()) == NULL)
if ((s = ASN1_TIME_new()) == NULL) {
free(p);
return (NULL);
}
allocated = 1;
}
@ -354,7 +355,6 @@ ASN1_TIME_to_generalizedtime(const ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
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)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: a_type.c,v 1.21 2019/10/24 16:36:10 jsing Exp $ */
/* $OpenBSD: a_type.c,v 1.23 2021/12/25 12:19:16 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -56,11 +56,51 @@
* [including the GNU Public Licence.]
*/
#include <stdio.h>
#include <string.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/objects.h>
typedef struct {
ASN1_INTEGER *num;
ASN1_OCTET_STRING *value;
} ASN1_int_octetstring;
static const ASN1_TEMPLATE ASN1_INT_OCTETSTRING_seq_tt[] = {
{
.offset = offsetof(ASN1_int_octetstring, num),
.field_name = "num",
.item = &ASN1_INTEGER_it,
},
{
.offset = offsetof(ASN1_int_octetstring, value),
.field_name = "value",
.item = &ASN1_OCTET_STRING_it,
},
};
const ASN1_ITEM ASN1_INT_OCTETSTRING_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = ASN1_INT_OCTETSTRING_seq_tt,
.tcount = sizeof(ASN1_INT_OCTETSTRING_seq_tt) / sizeof(ASN1_TEMPLATE),
.size = sizeof(ASN1_int_octetstring),
.sname = "ASN1_INT_OCTETSTRING",
};
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);
}
int
ASN1_TYPE_get(const ASN1_TYPE *a)
{
@ -155,6 +195,108 @@ ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
return result;
}
int
ASN1_TYPE_set_octetstring(ASN1_TYPE *a, const 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
ASN1_TYPE_get_octetstring(const 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 *at, long num, const unsigned char *data,
int len)
{
ASN1_int_octetstring *ios;
ASN1_STRING *sp = NULL;
int ret = 0;
if ((ios = (ASN1_int_octetstring *)ASN1_item_new(
&ASN1_INT_OCTETSTRING_it)) == NULL)
goto err;
if (!ASN1_INTEGER_set(ios->num, num))
goto err;
if (!ASN1_OCTET_STRING_set(ios->value, data, len))
goto err;
if ((sp = ASN1_item_pack(ios, &ASN1_INT_OCTETSTRING_it, NULL)) == NULL)
goto err;
ASN1_TYPE_set(at, V_ASN1_SEQUENCE, sp);
sp = NULL;
ret = 1;
err:
ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it);
ASN1_STRING_free(sp);
return ret;
}
int
ASN1_TYPE_get_int_octetstring(const ASN1_TYPE *at, long *num, unsigned char *data,
int max_len)
{
ASN1_STRING *sp = at->value.sequence;
ASN1_int_octetstring *ios = NULL;
int ret = -1;
int len;
if (at->type != V_ASN1_SEQUENCE || sp == NULL)
goto err;
if ((ios = ASN1_item_unpack(sp, &ASN1_INT_OCTETSTRING_it)) == NULL)
goto err;
if (num != NULL)
*num = ASN1_INTEGER_get(ios->num);
if (data != NULL) {
len = ASN1_STRING_length(ios->value);
if (len > max_len)
len = max_len;
memcpy(data, ASN1_STRING_data(ios->value), len);
}
ret = ASN1_STRING_length(ios->value);
err:
ASN1_item_free((ASN1_VALUE *)ios, &ASN1_INT_OCTETSTRING_it);
if (ret == -1)
ASN1error(ASN1_R_DATA_IS_WRONG);
return ret;
}
ASN1_TYPE *
ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
{
@ -185,3 +327,16 @@ ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
return NULL;
return ASN1_item_unpack(t->value.sequence, it);
}
int
i2d_ASN1_TYPE(ASN1_TYPE *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &ASN1_ANY_it);
}
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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: ameth_lib.c,v 1.21 2019/11/02 16:06:25 inoguchi Exp $ */
/* $OpenBSD: ameth_lib.c,v 1.25 2022/01/10 12:10:26 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
@ -69,6 +69,7 @@
#endif
#include "asn1_locl.h"
#include "evp_locl.h"
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[];
extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth;
@ -340,34 +341,21 @@ EVP_PKEY_asn1_new(int id, int flags, const char *pem_str, const char *info)
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;
EVP_PKEY_ASN1_METHOD preserve;
dst->priv_decode = src->priv_decode;
dst->priv_encode = src->priv_encode;
dst->priv_print = src->priv_print;
preserve.pkey_id = dst->pkey_id;
preserve.pkey_base_id = dst->pkey_base_id;
preserve.pkey_flags = dst->pkey_flags;
preserve.pem_str = dst->pem_str;
preserve.info = dst->info;
dst->old_priv_encode = src->old_priv_encode;
dst->old_priv_decode = src->old_priv_decode;
*dst = *src;
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->sig_print = src->sig_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;
dst->pkey_id = preserve.pkey_id;
dst->pkey_base_id = preserve.pkey_base_id;
dst->pkey_flags = preserve.pkey_flags;
dst->pem_str = preserve.pem_str;
dst->info = preserve.info;
}
void
@ -441,3 +429,24 @@ EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
{
ameth->pkey_ctrl = pkey_ctrl;
}
void
EVP_PKEY_asn1_set_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_check)(const EVP_PKEY *pk))
{
ameth->pkey_check = pkey_check;
}
void
EVP_PKEY_asn1_set_public_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_public_check)(const EVP_PKEY *pk))
{
ameth->pkey_public_check = pkey_public_check;
}
void
EVP_PKEY_asn1_set_param_check(EVP_PKEY_ASN1_METHOD *ameth,
int (*pkey_param_check)(const EVP_PKEY *pk))
{
ameth->pkey_param_check = pkey_param_check;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn1_err.c,v 1.21 2018/03/29 02:29:24 inoguchi Exp $ */
/* $OpenBSD: asn1_err.c,v 1.22 2020/12/08 15:06:42 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@ -85,6 +85,7 @@ static ERR_STRING_DATA ASN1_str_reasons[] = {
{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_BAD_TEMPLATE) , "bad template"},
{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"},

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn1_gen.c,v 1.17 2018/04/25 11:48:21 tb Exp $ */
/* $OpenBSD: asn1_gen.c,v 1.18 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2002.
*/
@ -258,7 +258,7 @@ ASN1_generate_v3(const char *str, X509V3_CTX *cnf)
/* Obtain new ASN1_TYPE structure */
ret = d2i_ASN1_TYPE(NULL, &cp, len);
err:
err:
free(orig_der);
free(new_der);
@ -478,7 +478,7 @@ asn1_multi(int utype, const char *section, X509V3_CTX *cnf)
der = NULL;
bad:
bad:
free(der);
if (sk)
sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free);
@ -771,9 +771,9 @@ asn1_str2type(const char *str, int format, int utype)
atmp->type = utype;
return atmp;
bad_str:
bad_str:
ERR_asprintf_error_data("string=%s", str);
bad_form:
bad_form:
ASN1_TYPE_free(atmp);
return NULL;
}

639
externals/libressl/crypto/asn1/asn1_item.c vendored Executable file
View file

@ -0,0 +1,639 @@
/* $OpenBSD: asn1_item.c,v 1.4 2022/01/14 08:38:05 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* 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 <limits.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "evp_locl.h"
/*
* 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.
*/
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)) {
free(str);
return (0);
}
free(str);
return (1);
}
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);
}
/* Pack an ASN1 object into an ASN1_STRING. */
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(const 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;
}
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 (!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;
}
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);
}
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);
}
#define HEADER_SIZE 8
#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
int
asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
unsigned char *p;
const unsigned char *q;
long slen;
int i, inf, tag, xclass;
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]);
q = p;
inf = ASN1_get_object(&q, &slen, &tag, &xclass, len - off);
if (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 = q - p; /* header length */
off += i; /* end of data */
if (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 && slen == 0 && 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 slen bytes of data */
want = 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 + slen < off) {
ASN1error(ASN1_R_TOO_LONG);
goto err;
}
off += 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;
}
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);
}
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);
}
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);
}

View file

@ -1,436 +1,202 @@
/* $OpenBSD: asn1_lib.c,v 1.44 2018/11/17 09:34:11 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
/* $OpenBSD: asn1_lib.c,v 1.52 2022/03/26 14:47:58 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
* 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.
*
* 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.]
* 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 <limits.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.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);
#include "bytestring.h"
static int
_asn1_check_infinite_end(const unsigned char **p, long len)
asn1_get_identifier_cbs(CBS *cbs, int der_mode, uint8_t *out_class,
int *out_constructed, uint32_t *out_tag_number)
{
/* 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);
}
uint8_t tag_class, tag_val;
int tag_constructed;
uint32_t tag_number;
int
ASN1_check_infinite_end(unsigned char **p, long len)
{
return _asn1_check_infinite_end((const unsigned char **)p, len);
}
/*
* Decode ASN.1 identifier octets - see ITU-T X.690 section 8.1.2.
*/
int
ASN1_const_check_infinite_end(const unsigned char **p, long len)
{
return _asn1_check_infinite_end(p, len);
}
*out_class = 0;
*out_constructed = 0;
*out_tag_number = 0;
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))
if (!CBS_get_u8(cbs, &tag_val))
return 0;
while (i-- > 0) {
ret <<= 8L;
ret |= *(p++);
}
} else
ret = i;
}
if (ret > LONG_MAX)
/*
* ASN.1 tag class, encoding (primitive or constructed) and tag number
* are encoded in one or more identifier octets - the first octet
* contains the 2 bit tag class, the 1 bit encoding type and 5 bits
* of tag number.
*
* For tag numbers larger than 30 (0x1e) the 5 bit tag number in the
* first octet is set to all ones (0x1f) - the tag number is then
* encoded in subsequent octets - each of which have a one bit
* continuation flag and 7 bits of tag number in big-endian form.
* The encoding should not contain leading zeros but can for BER.
*/
tag_class = (tag_val >> 6) & 0x3;
tag_constructed = (tag_val >> 5) & 0x1;
tag_number = tag_val & 0x1f;
/* Long form. */
if (tag_number == 0x1f) {
tag_number = 0;
do {
if (!CBS_get_u8(cbs, &tag_val))
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);
}
int
ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
{
if (str == NULL)
if (der_mode && tag_number == 0 && tag_val == 0x80)
return 0;
dst->type = str->type;
if (!ASN1_STRING_set(dst, str->data, str->length))
if (tag_number > (UINT32_MAX >> 7))
return 0;
dst->flags = str->flags;
tag_number = tag_number << 7 | (tag_val & 0x7f);
} while ((tag_val & 0x80) != 0);
}
*out_class = tag_class;
*out_constructed = tag_constructed;
*out_tag_number = tag_number;
return 1;
}
ASN1_STRING *
ASN1_STRING_dup(const ASN1_STRING *str)
static int
asn1_get_length_cbs(CBS *cbs, int der_mode, int *out_indefinite,
uint32_t *out_length)
{
ASN1_STRING *ret;
uint8_t len_bytes;
uint32_t length;
uint8_t val;
if (!str)
return NULL;
ret = ASN1_STRING_new();
if (!ret)
return NULL;
if (!ASN1_STRING_copy(ret, str)) {
ASN1_STRING_free(ret);
return NULL;
/*
* Decode ASN.1 length octets - see ITU-T X.690 section 8.1.3.
*/
*out_length = 0;
*out_indefinite = 0;
if (!CBS_get_u8(cbs, &val))
return 0;
/*
* Short form - length is encoded in the lower 7 bits of a single byte.
*/
if (val < 0x80) {
*out_length = val;
return 1;
}
return ret;
/*
* Indefinite length - content continues until an End of Content (EOC)
* marker is reached. Must be used with constructed encoding.
*/
if (val == 0x80) {
*out_indefinite = 1;
return 1;
}
/*
* Long form - the lower 7 bits of the first byte specifies the number
* of bytes used to encode the length, the following bytes specify the
* length in big-endian form. The encoding should not contain leading
* zeros but can for BER. A length value of 0x7f is invalid.
*/
if ((len_bytes = val & 0x7f) == 0x7f)
return 0;
length = 0;
while (len_bytes-- > 0) {
if (!CBS_get_u8(cbs, &val))
return 0;
if (der_mode && length == 0 && val == 0)
return 0;
if (length > (UINT32_MAX >> 8))
return 0;
length = (length << 8) | val;
}
*out_length = length;
return 1;
}
int
ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_tag_class,
int *out_constructed, uint32_t *out_tag_number, int *out_indefinite,
uint32_t *out_length)
{
const char *data = _data;
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
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);
}
*out_tag_class = 0;
*out_constructed = 0;
*out_tag_number = 0;
*out_indefinite = 0;
*out_length = 0;
void
ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
freezero(str->data, str->length);
str->data = data;
str->length = len;
}
if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed,
&tag_number))
return 0;
if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length))
return 0;
ASN1_STRING *
ASN1_STRING_new(void)
{
return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
}
/* Indefinite length can only be used with constructed encoding. */
if (indefinite && !constructed)
return 0;
ASN1_STRING *
ASN1_STRING_type_new(int type)
{
ASN1_STRING *ret;
*out_tag_class = tag_class;
*out_constructed = constructed;
*out_tag_number = tag_number;
*out_indefinite = indefinite;
*out_length = length;
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);
return 1;
}
int
ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
CBS *out_content)
{
int i;
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
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);
}
*out_tag_number = 0;
void
asn1_add_error(const unsigned char *address, int offset)
{
ERR_asprintf_error_data("offset=%d", offset);
}
CBS_init(out_content, NULL, 0);
int
ASN1_STRING_length(const ASN1_STRING *x)
{
return (x->length);
}
if (!asn1_get_identifier_cbs(cbs, der_mode, &tag_class, &constructed,
&tag_number))
return 0;
if (!asn1_get_length_cbs(cbs, der_mode, &indefinite, &length))
return 0;
void
ASN1_STRING_length_set(ASN1_STRING *x, int len)
{
x->length = len;
}
/* A primitive is not constructed and has a definite length. */
if (constructed || indefinite)
return 0;
int
ASN1_STRING_type(const ASN1_STRING *x)
{
return (x->type);
}
if (!CBS_get_bytes(cbs, out_content, length))
return 0;
unsigned char *
ASN1_STRING_data(ASN1_STRING *x)
{
return (x->data);
}
*out_tag_number = tag_number;
const unsigned char *
ASN1_STRING_get0_data(const ASN1_STRING *x)
{
return (x->data);
return 1;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn1_locl.h,v 1.12 2019/10/24 16:36:10 jsing Exp $ */
/* $OpenBSD: asn1_locl.h,v 1.24 2022/03/26 14:47:58 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2006.
*/
@ -56,6 +56,8 @@
*
*/
#include "bytestring.h"
__BEGIN_HIDDEN_DECLS
/* Internal ASN1 structures and functions: not for application use */
@ -63,6 +65,20 @@ __BEGIN_HIDDEN_DECLS
ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t);
void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t);
/* These are used internally in the ASN1_OBJECT to keep track of
* whether the names and data need to be free()ed */
#define ASN1_OBJECT_FLAG_DYNAMIC 0x01 /* internal use */
#define ASN1_OBJECT_FLAG_CRITICAL 0x02 /* critical x509v3 object id */
#define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04 /* internal use */
#define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08 /* internal use */
struct asn1_object_st {
const char *sn, *ln;
int nid;
int length;
const unsigned char *data; /* data remains const after init */
int flags; /* Should we free this one */
} /* ASN1_OBJECT */;
/* ASN1 print context structure */
struct asn1_pctx_st {
@ -122,6 +138,9 @@ struct evp_pkey_asn1_method_st {
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig);
int (*pkey_check)(const EVP_PKEY *pk);
int (*pkey_public_check)(const EVP_PKEY *pk);
int (*pkey_param_check)(const EVP_PKEY *pk);
} /* EVP_PKEY_ASN1_METHOD */;
/* Method to handle CRL access.
@ -142,6 +161,23 @@ struct x509_crl_method_st {
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
};
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp);
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length);
/*
* Unicode codepoint constants
*/
@ -155,4 +191,18 @@ struct x509_crl_method_st {
int UTF8_getc(const unsigned char *str, int len, unsigned long *val);
int UTF8_putc(unsigned char *str, int len, unsigned long value);
int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
int asn1_get_object_cbs(CBS *cbs, int der_mode, uint8_t *out_class,
int *out_constructed, uint32_t *out_tag_number, int *out_indefinite,
uint32_t *out_length);
int asn1_get_primitive(CBS *cbs, int der_mode, uint32_t *out_tag_number,
CBS *out_content);
int asn1_tag2charwidth(int tag);
int i2t_ASN1_OBJECT_internal(const ASN1_OBJECT *aobj, char *buf, int buf_len,
int no_name);
ASN1_OBJECT *t2i_ASN1_OBJECT_internal(const char *oid);
__END_HIDDEN_DECLS

180
externals/libressl/crypto/asn1/asn1_old.c vendored Executable file
View file

@ -0,0 +1,180 @@
/* $OpenBSD: asn1_old.c,v 1.2 2021/12/25 13:17:48 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 <limits.h>
#include <stdio.h>
#include <openssl/asn1.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "asn1_locl.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);
}
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);
}
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

211
externals/libressl/crypto/asn1/asn1_old_lib.c vendored Executable file
View file

@ -0,0 +1,211 @@
/* $OpenBSD: asn1_old_lib.c,v 1.3 2022/01/14 07:57:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include "asn1_locl.h"
static void asn1_put_length(unsigned char **pp, int length);
int
ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
int *pclass, long omax)
{
int constructed, indefinite;
uint32_t tag_number, length;
uint8_t tag_class;
CBS cbs;
int ret = 0;
*pclass = 0;
*ptag = 0;
*plength = 0;
CBS_init(&cbs, *pp, omax);
if (!asn1_get_object_cbs(&cbs, 0, &tag_class, &constructed, &tag_number,
&indefinite, &length)) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
return 0x80;
}
if (tag_number > INT_MAX) {
ASN1error(ASN1_R_HEADER_TOO_LONG);
return 0x80;
}
/*
* API insanity ahead... in this case we add an error to the stack and
* signal an error by setting the 8th bit in the return value... but we
* still provide all of the decoded data.
*/
if (length > CBS_len(&cbs)) {
ASN1error(ASN1_R_TOO_LONG);
ret = 0x80;
}
*pclass = tag_class << 6;
*ptag = tag_number;
*plength = length;
*pp = CBS_data(&cbs);
if (constructed)
ret |= 1 << 5;
if (indefinite)
ret |= 1;
return ret;
}
/* 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);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn1_par.c,v 1.28 2020/01/09 11:27:21 inoguchi Exp $ */
/* $OpenBSD: asn1_par.c,v 1.34 2022/02/12 03:07:24 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -80,7 +80,8 @@ asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
p="prim: ";
if (BIO_write(bp, p, 6) < 6)
goto err;
BIO_indent(bp, indent, 128);
if (!BIO_indent(bp, indent, 128))
goto err;
p = str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
@ -97,7 +98,7 @@ asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
if (BIO_printf(bp, "%-18s", p) <= 0)
goto err;
return (1);
err:
err:
return (0);
}
@ -232,16 +233,13 @@ asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
goto end;
}
} else if (tag == V_ASN1_BOOLEAN) {
int ii;
opp = op;
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
if (ii < 0) {
if (len == 1 && p < tot) {
BIO_printf(bp, ":%u", p[0]);
} else {
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) {
@ -375,7 +373,7 @@ asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
}
ret = 1;
end:
end:
if (o != NULL)
ASN1_OBJECT_free(o);
ASN1_OCTET_STRING_free(os);
@ -384,25 +382,3 @@ end:
*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];
}

263
externals/libressl/crypto/asn1/asn1_types.c vendored Executable file
View file

@ -0,0 +1,263 @@
/* $OpenBSD: asn1_types.c,v 1.1 2021/12/14 17:35:21 jsing Exp $ */
/*
* Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <stddef.h>
#include <openssl/asn1.h>
struct asn1_type {
const char *name;
uint32_t bit_value;
int char_width;
};
/*
* Universal class tag types - ITU X.680.
*/
static const struct asn1_type asn1_types[31] = {
[0] = {
/* Tag 0 (0x00) - Reserved for use by encoding rules */
.name = "EOC",
.bit_value = 0,
.char_width = -1,
},
[1] = {
/* Tag 1 (0x01) - Boolean */
.name = "BOOLEAN",
.bit_value = 0,
.char_width = -1,
},
[2] = {
/* Tag 2 (0x02) - Integer */
.name = "INTEGER",
.bit_value = 0,
.char_width = -1,
},
[3] = {
/* Tag 3 (0x03) - BitString */
.name = "BIT STRING",
.bit_value = B_ASN1_BIT_STRING,
.char_width = -1,
},
[4] = {
/* Tag 4 (0x04) - OctetString */
.name = "OCTET STRING",
.bit_value = B_ASN1_OCTET_STRING,
.char_width = -1,
},
[5] = {
/* Tag 5 (0x05) - Null */
.name = "NULL",
.bit_value = 0,
.char_width = -1,
},
[6] = {
/* Tag 6 (0x06) - Object Identifier */
.name = "OBJECT",
.bit_value = 0,
.char_width = -1,
},
[7] = {
/* Tag 7 (0x07) - Object Descriptor */
.name = "OBJECT DESCRIPTOR",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[8] = {
/* Tag 8 (0x08) - External */
.name = "EXTERNAL",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[9] = {
/* Tag 9 (0x09) - Real */
.name = "REAL",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[10] = {
/* Tag 10 (0x0a) - Enumerated */
.name = "ENUMERATED",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[11] = {
/* Tag 11 (0x0b) - Embedded PDV */
.name = "<ASN1 11 EMBEDDED PDV>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[12] = {
/* Tag 12 (0x0c) - UTF8String */
.name = "UTF8STRING",
.bit_value = B_ASN1_UTF8STRING,
.char_width = 0,
},
[13] = {
/* Tag 13 (0x0d) - Relative Object Identifier */
.name = "<ASN1 13 RELATIVE OID>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[14] = {
/* Tag 14 (0x0e) - Time */
.name = "<ASN1 14 TIME>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[15] = {
/* Tag 15 (0x0f) - Reserved */
.name = "<ASN1 15 RESERVED>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[16] = {
/* Tag 16 (0x10)- Sequence */
.name = "SEQUENCE",
.bit_value = B_ASN1_SEQUENCE,
.char_width = -1,
},
[17] = {
/* Tag 17 (0x11) - Set */
.name = "SET",
.bit_value = 0,
.char_width = -1,
},
[18] = {
/* Tag 18 (0x12) - NumericString */
.name = "NUMERICSTRING",
.bit_value = B_ASN1_NUMERICSTRING,
.char_width = -1,
},
[19] = {
/* Tag 19 (0x13) - PrintableString */
.name = "PRINTABLESTRING",
.bit_value = B_ASN1_PRINTABLESTRING,
.char_width = 1,
},
[20] = {
/* Tag 20 (0x14) - TeletexString (T61String) */
.name = "T61STRING",
.bit_value = B_ASN1_T61STRING,
.char_width = 1,
},
[21] = {
/* Tag 21 (0x15) - VideotexString */
.name = "VIDEOTEXSTRING",
.bit_value = B_ASN1_VIDEOTEXSTRING,
.char_width = -1,
},
[22] = {
/* Tag 22 (0x16) - IA5String */
.name = "IA5STRING",
.bit_value = B_ASN1_IA5STRING,
.char_width = 1,
},
[23] = {
/* Tag 23 (0x17) - UTCTime */
.name = "UTCTIME",
.bit_value = B_ASN1_UTCTIME,
.char_width = 1,
},
[24] = {
/* Tag 24 (0x18) - GeneralizedTime */
.name = "GENERALIZEDTIME",
.bit_value = B_ASN1_GENERALIZEDTIME,
.char_width = 1,
},
[25] = {
/* Tag 25 (0x19) - GraphicString */
.name = "GRAPHICSTRING",
.bit_value = B_ASN1_GRAPHICSTRING,
.char_width = -1,
},
[26] = {
/* Tag 26 (0x1a) - VisibleString (ISO646String) */
.name = "VISIBLESTRING",
.bit_value = B_ASN1_ISO64STRING,
.char_width = 1,
},
[27] = {
/* Tag 27 (0x1b) - GeneralString */
.name = "GENERALSTRING",
.bit_value = B_ASN1_GENERALSTRING,
.char_width = -1,
},
[28] = {
/* Tag 28 (0x1c) - UniversalString */
.name = "UNIVERSALSTRING",
.bit_value = B_ASN1_UNIVERSALSTRING,
.char_width = 4,
},
[29] = {
/* Tag 29 (0x1d) - Unallocated */
.name = "<ASN1 29>",
.bit_value = B_ASN1_UNKNOWN,
.char_width = -1,
},
[30] = {
/* Tag 30 (0x1e) - BMPString */
.name = "BMPSTRING",
.bit_value = B_ASN1_BMPSTRING,
.char_width = 2,
},
};
static const struct asn1_type *
asn1_type_by_tag(int tag)
{
if (tag < 0 || tag > 30)
return NULL;
return &asn1_types[tag];
}
int
asn1_tag2charwidth(int tag)
{
const struct asn1_type *at;
if ((at = asn1_type_by_tag(tag)) != NULL)
return at->char_width;
return -1;
}
unsigned long
ASN1_tag2bit(int tag)
{
const struct asn1_type *at;
if ((at = asn1_type_by_tag(tag)) != NULL)
return (unsigned long)at->bit_value;
return 0;
}
const char *
ASN1_tag2str(int tag)
{
const struct asn1_type *at;
if (tag == V_ASN1_NEG_INTEGER || tag == V_ASN1_NEG_ENUMERATED)
tag &= ~V_ASN1_NEG;
if ((at = asn1_type_by_tag(tag)) != NULL)
return at->name;
return "(unknown)";
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn_mime.c,v 1.27 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: asn_mime.c,v 1.29 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@ -63,6 +63,7 @@
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "evp_locl.h"
/* Generalised MIME like utilities for streaming ASN1. Although many
* have a PKCS7/CMS like flavour others are more general purpose.
@ -267,7 +268,7 @@ asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs)
ret = 1;
err:
err:
return ret;
}
@ -778,7 +779,7 @@ STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
return headers;
merr:
merr:
if (mhdr != NULL)
mime_hdr_free(mhdr);
sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
@ -866,7 +867,7 @@ mime_hdr_new(char *name, char *value)
goto err;
}
return mhdr;
err:
err:
free(tmpname);
free(tmpval);
return NULL;
@ -901,7 +902,7 @@ mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
goto err;
}
return 1;
err:
err:
free(tmpname);
free(tmpval);
return 0;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: asn_moid.c,v 1.13 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: asn_moid.c,v 1.14 2022/01/07 11:13:54 tb Exp $ */
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
* project 2001.
*/
@ -65,6 +65,8 @@
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include "asn1_locl.h"
/* Simple ASN1 OID module: add all objects in a given section */
static int do_create(char *value, char *name);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_asn1.c,v 1.13 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bio_asn1.c,v 1.17 2022/01/14 08:40:57 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@ -67,6 +67,8 @@
#include <openssl/bio.h>
#include <openssl/asn1.h>
#include "bio_local.h"
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
@ -116,9 +118,8 @@ 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 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,
@ -148,35 +149,23 @@ static int
asn1_bio_new(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
if ((ctx = calloc(1, sizeof(*ctx))) == NULL)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
if ((ctx->buf = malloc(DEFAULT_ASN1_BUF_SIZE)) == NULL) {
free(ctx);
return 0;
}
ctx->bufsize = DEFAULT_ASN1_BUF_SIZE;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->state = ASN1_STATE_START;
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;
}
@ -284,7 +273,7 @@ asn1_bio_write(BIO *b, const char *in , int inl)
}
done:
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
@ -357,7 +346,7 @@ asn1_bio_gets(BIO *b, char *str, int size)
}
static long
asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
asn1_bio_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
if (b->next_bio == NULL)
return (0);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_ndef.c,v 1.10 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bio_ndef.c,v 1.11 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project.
*/
@ -143,7 +143,7 @@ BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
return sarg.ndef_bio;
err:
err:
BIO_free(asn_bio);
free(ndef_aux);
return NULL;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: p5_pbe.c,v 1.22 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: p5_pbe.c,v 1.23 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -159,7 +159,7 @@ PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
return 1;
err:
err:
if (pbe != NULL)
PBEPARAM_free(pbe);
ASN1_STRING_free(pbe_str);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: p5_pbev2.c,v 1.25 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: p5_pbev2.c,v 1.27 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999-2004.
*/
@ -64,6 +64,8 @@
#include <openssl/err.h>
#include <openssl/x509.h>
#include "evp_locl.h"
/* PKCS#5 v2.0 password based encryption structures */
static const ASN1_TEMPLATE PBE2PARAM_seq_tt[] = {
@ -272,10 +274,10 @@ PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, unsigned char *salt,
return ret;
merr:
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
err:
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
X509_ALGOR_free(kalg);
@ -364,7 +366,7 @@ PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, int prf_nid,
PBKDF2PARAM_free(kdf);
return keyfunc;
merr:
merr:
ASN1error(ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: p8_pkey.c,v 1.19 2018/08/24 20:17:33 tb Exp $ */
/* $OpenBSD: p8_pkey.c,v 1.20 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -62,6 +62,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* Minor tweak to operation: zero private key data */
static int
pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_crl.c,v 1.18 2019/05/12 15:56:31 tb Exp $ */
/* $OpenBSD: t_crl.c,v 1.20 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -66,6 +66,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
int
X509_CRL_print_fp(FILE *fp, X509_CRL *x)
{
@ -138,6 +140,6 @@ X509_CRL_print(BIO *out, X509_CRL *x)
return 1;
err:
err:
return 0;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_pkey.c,v 1.16 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_pkey.c,v 1.17 2021/12/04 16:08:32 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -62,6 +62,8 @@
#include <openssl/buffer.h>
#include <openssl/objects.h>
#include "bn_lcl.h"
int
ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
unsigned char *buf, int off)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_req.c,v 1.19 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: t_req.c,v 1.21 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -74,6 +74,8 @@
#include <openssl/rsa.h>
#endif
#include "x509_lcl.h"
int
X509_REQ_print_fp(FILE *fp, X509_REQ *x)
{
@ -192,7 +194,7 @@ X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
ii = 0;
count = sk_ASN1_TYPE_num(
a->value.set);
get_next:
get_next:
at = sk_ASN1_TYPE_value(
a->value.set, ii);
type = at->type;
@ -255,7 +257,7 @@ get_next:
return (1);
err:
err:
X509error(ERR_R_BUF_LIB);
return (0);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_spki.c,v 1.11 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_spki.c,v 1.13 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -71,6 +71,8 @@
#include <openssl/rsa.h>
#endif
#include "x509_lcl.h"
/* Print out an SPKI */
int
@ -94,7 +96,8 @@ NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
}
chal = spki->spkac->challenge;
if (chal->length)
BIO_printf(out, " Challenge String: %s\n", chal->data);
BIO_printf(out, " Challenge String: %.*s\n", chal->length,
chal->data);
i = OBJ_obj2nid(spki->sig_algor->algorithm);
BIO_printf(out, " Signature Algorithm: %s",
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_x509.c,v 1.32 2020/04/10 07:05:24 tb Exp $ */
/* $OpenBSD: t_x509.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -78,6 +78,7 @@
#endif
#include "asn1_locl.h"
#include "x509_lcl.h"
int
X509_print_fp(FILE *fp, X509 *x)
@ -180,7 +181,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_issuer_name(x),
nmindent, nmflags) < 0)
nmindent, nmflags) < (nmflags == X509_FLAG_COMPAT ? 1 : 0))
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
@ -203,7 +204,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
goto err;
if (X509_NAME_print_ex(bp, X509_get_subject_name(x),
nmindent, nmflags) < 0)
nmindent, nmflags) < (nmflags == X509_FLAG_COMPAT ? 1 : 0))
goto err;
if (BIO_write(bp, "\n", 1) <= 0)
goto err;
@ -243,7 +244,7 @@ X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
}
ret = 1;
err:
err:
free(m);
return (ret);
}
@ -261,10 +262,12 @@ X509_ocspid_print(BIO *bp, X509 *x)
in OCSP requests */
if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
goto err;
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
if ((derlen = i2d_X509_NAME(x->cert_info->subject, NULL)) <= 0)
goto err;
if ((der = dertmp = malloc(derlen)) == NULL)
goto err;
i2d_X509_NAME(x->cert_info->subject, &dertmp);
if (i2d_X509_NAME(x->cert_info->subject, &dertmp) <= 0)
goto err;
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
goto err;
@ -292,7 +295,7 @@ X509_ocspid_print(BIO *bp, X509 *x)
return (1);
err:
err:
free(der);
return (0);
}
@ -348,36 +351,6 @@ X509_signature_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig)
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)
{
@ -443,7 +416,7 @@ ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
else
return (1);
err:
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
@ -486,7 +459,7 @@ ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
else
return (1);
err:
err:
BIO_write(bp, "Bad time value", 14);
return (0);
}
@ -532,7 +505,7 @@ X509_NAME_print(BIO *bp, const X509_NAME *name, int obase)
ret = 1;
if (0) {
err:
err:
X509error(ERR_R_BUF_LIB);
}
free(b);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: t_x509a.c,v 1.8 2014/07/11 08:44:47 jsing Exp $ */
/* $OpenBSD: t_x509a.c,v 1.10 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -62,8 +62,9 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
/* X509_CERT_AUX and string set routines
*/
#include "x509_lcl.h"
/* X509_CERT_AUX and string set routines */
int
X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
@ -105,8 +106,8 @@ X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
} else
BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
if (aux->alias)
BIO_printf(out, "%*sAlias: %s\n", indent, "",
aux->alias->data);
BIO_printf(out, "%*sAlias: %.*s\n", indent, "",
aux->alias->length, aux->alias->data);
if (aux->keyid) {
BIO_printf(out, "%*sKey Id: ", indent, "");
for (i = 0; i < aux->keyid->length; i++)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_dec.c,v 1.37 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_dec.c,v 1.49 2022/03/13 14:58:14 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -56,14 +56,18 @@
*
*/
#include <limits.h>
#include <stddef.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include <openssl/buffer.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include "asn1_locl.h"
#include "bytestring.h"
/* Constructed types with a recursive definition (such as can be found in PKCS7)
* could eventually exceed the stack given malicious input with excessive
@ -74,15 +78,16 @@
static int asn1_check_eoc(const unsigned char **in, long len);
static int asn1_find_end(const unsigned char **in, long len, char inf);
static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
static int asn1_collect(CBB *cbb, const unsigned char **in, long len,
char inf, int tag, int aclass, int depth);
static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen);
static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
char *inf, char *cst, const unsigned char **in, long len, int exptag,
int expclass, char opt, ASN1_TLC *ctx);
static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx,
int depth);
static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_TEMPLATE *tt, char opt, ASN1_TLC *ctx, int depth);
static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
@ -90,68 +95,44 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in,
static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it, int tag, int aclass, char opt,
ASN1_TLC *ctx);
static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len,
int utype, const ASN1_ITEM *it);
/* Table to convert tags to bit values, used for MSTRING type */
static const unsigned long tag2bit[32] = {
0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */
B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN,/* tags 4- 7 */
B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN,/* tags 8-11 */
B_ASN1_UTF8STRING,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,B_ASN1_UNKNOWN,/* tags 12-15 */
B_ASN1_SEQUENCE,0,B_ASN1_NUMERICSTRING,B_ASN1_PRINTABLESTRING, /* tags 16-19 */
B_ASN1_T61STRING,B_ASN1_VIDEOTEXSTRING,B_ASN1_IA5STRING, /* tags 20-22 */
B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */
B_ASN1_GRAPHICSTRING,B_ASN1_ISO64STRING,B_ASN1_GENERALSTRING, /* tags 25-27 */
B_ASN1_UNIVERSALSTRING,B_ASN1_UNKNOWN,B_ASN1_BMPSTRING,B_ASN1_UNKNOWN, /* tags 28-31 */
};
unsigned long
ASN1_tag2bit(int tag)
static void
asn1_tlc_invalidate(ASN1_TLC *ctx)
{
if ((tag < 0) || (tag > 30))
return 0;
return tag2bit[tag];
if (ctx != NULL)
ctx->valid = 0;
}
/* Macro to initialize and invalidate the cache */
#define asn1_tlc_clear(c) if (c) (c)->valid = 0
/* Version to avoid compiler warning about 'c' always non-NULL */
#define asn1_tlc_clear_nc(c) (c)->valid = 0
/* Decode an ASN1 item, this currently behaves just
* like a standard 'd2i' function. 'in' points to
* a buffer to read the data from, in future we will
* have more advanced versions that can input data
* a piece at a time and this will simply be a special
* case.
*/
ASN1_VALUE *
ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it)
{
ASN1_TLC c;
ASN1_VALUE *ptmpval = NULL;
ASN1_TLC ctx;
if (!pval)
asn1_tlc_invalidate(&ctx);
if (pval == NULL)
pval = &ptmpval;
asn1_tlc_clear_nc(&c);
if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0)
return *pval;
if (asn1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &ctx, 0) <= 0)
return NULL;
return *pval;
}
int
ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_TEMPLATE *tt)
{
ASN1_TLC c;
ASN1_TLC ctx;
asn1_tlc_clear_nc(&c);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &c, 0);
asn1_tlc_invalidate(&ctx);
return asn1_template_ex_d2i(pval, in, len, tt, 0, &ctx, 0);
}
/* Decode an item, taking care of IMPLICIT tagging, if any.
* If 'opt' set and tag mismatch return -1 to handle OPTIONAL
*/
@ -210,6 +191,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
break;
case ASN1_ITYPE_MSTRING:
/*
* It never makes sense for multi-strings to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
goto err;
}
p = *in;
/* Just read in tag and class */
ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL,
@ -245,6 +236,16 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
it, tag, aclass, opt, ctx);
case ASN1_ITYPE_CHOICE:
/*
* It never makes sense for CHOICE types to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
goto err;
}
if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL))
goto auxerr;
@ -446,9 +447,9 @@ asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
return 0;
}
auxerr:
auxerr:
ASN1error(ASN1_R_AUX_ERROR);
err:
err:
if (combine == 0)
ASN1_item_ex_free(pval, it);
if (errtt)
@ -535,7 +536,7 @@ asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen,
*in = p;
return 1;
err:
err:
ASN1_template_free(val, tt);
return 0;
}
@ -652,7 +653,7 @@ asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
*in = p;
return 1;
err:
err:
ASN1_template_free(val, tt);
return 0;
}
@ -663,15 +664,15 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
{
int ret = 0, utype;
long plen;
char cst, inf, free_cont = 0;
char cst, inf;
const unsigned char *p;
BUF_MEM buf;
const unsigned char *cont = NULL;
const unsigned char *content = NULL;
uint8_t *data = NULL;
size_t data_len = 0;
CBB cbb;
long len;
buf.length = 0;
buf.max = 0;
buf.data = NULL;
memset(&cbb, 0, sizeof(cbb));
if (!pval) {
ASN1error(ASN1_R_ILLEGAL_NULL);
@ -726,69 +727,68 @@ asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen,
* when we have a exact match wont work
*/
if (utype == V_ASN1_OTHER) {
asn1_tlc_clear(ctx);
}
asn1_tlc_invalidate(ctx);
} else if (!cst) {
/* SEQUENCE and SET must be constructed */
else if (!cst) {
ASN1error(ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
}
cont = *in;
content = *in;
/* If indefinite length constructed find the real end */
if (inf) {
if (!asn1_find_end(&p, plen, inf))
goto err;
len = p - cont;
len = p - content;
} else {
len = p - cont + plen;
len = p - content + plen;
p += plen;
buf.data = NULL;
}
} else if (cst) {
/* Should really check the internal tags are correct but
/*
* Should really check the internal tags are correct but
* some things may get this wrong. The relevant specs
* say that constructed string types should be OCTET STRINGs
* internally irrespective of the type. So instead just check
* for UNIVERSAL class and ignore the tag.
*/
if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) {
free_cont = 1;
if (!CBB_init(&cbb, 0))
goto err;
}
len = buf.length;
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
buf.data[len] = 0;
cont = (const unsigned char *)buf.data;
free_cont = 1;
if (!asn1_collect(&cbb, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0))
goto err;
if (!CBB_finish(&cbb, &data, &data_len))
goto err;
if (data_len > LONG_MAX)
goto err;
content = data;
len = data_len;
} else {
cont = p;
content = p;
len = plen;
p += plen;
}
/* We now have content length and type: translate into a structure */
if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it))
if (!asn1_ex_c2i(pval, content, len, utype, it))
goto err;
*in = p;
ret = 1;
err:
if (free_cont && buf.data)
free(buf.data);
err:
CBB_cleanup(&cbb);
freezero(data, data_len);
return ret;
}
/* Translate ASN1 content octets into a structure */
int
asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
char *free_cont, const ASN1_ITEM *it)
static int
asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *content, int len, int utype,
const ASN1_ITEM *it)
{
ASN1_VALUE **opval = NULL;
ASN1_STRING *stmp;
@ -798,10 +798,11 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
if (it->funcs != NULL) {
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
char free_content = 0;
if (pf->prim_c2i == NULL)
return 0;
return pf->prim_c2i(pval, cont, len, utype, free_cont, it);
return pf->prim_c2i(pval, content, len, utype, &free_content, it);
}
/* If ANY type clear type and set pointer to internal value */
@ -821,7 +822,7 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
}
switch (utype) {
case V_ASN1_OBJECT:
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len))
if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &content, len))
goto err;
break;
@ -840,19 +841,19 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
} else {
ASN1_BOOLEAN *tbool;
tbool = (ASN1_BOOLEAN *)pval;
*tbool = *cont;
*tbool = *content;
}
break;
case V_ASN1_BIT_STRING:
if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len))
if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &content, len))
goto err;
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
tint = (ASN1_INTEGER **)pval;
if (!c2i_ASN1_INTEGER(tint, &cont, len))
if (!c2i_ASN1_INTEGER(tint, &content, len))
goto err;
/* Fixup type to match the expected form */
(*tint)->type = utype | ((*tint)->type & V_ASN1_NEG);
@ -884,10 +885,9 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
ASN1error(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
goto err;
}
/* All based on ASN1_STRING and handled the same */
if (!*pval) {
stmp = ASN1_STRING_type_new(utype);
if (!stmp) {
/* All based on ASN1_STRING and handled the same way. */
if (*pval == NULL) {
if ((stmp = ASN1_STRING_type_new(utype)) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
goto err;
}
@ -896,20 +896,11 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
stmp = (ASN1_STRING *)*pval;
stmp->type = utype;
}
/* If we've already allocated a buffer use it */
if (*free_cont) {
free(stmp->data);
stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */
stmp->length = len;
*free_cont = 0;
} else {
if (!ASN1_STRING_set(stmp, cont, len)) {
ASN1error(ERR_R_MALLOC_FAILURE);
if (!ASN1_STRING_set(stmp, content, len)) {
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
}
}
break;
}
/* If ASN1_ANY and NULL type fix up value */
@ -918,7 +909,7 @@ asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype,
ret = 1;
err:
err:
if (!ret) {
ASN1_TYPE_free(typ);
if (opval)
@ -927,7 +918,6 @@ err:
return ret;
}
/* This function finds the end of an ASN1 structure when passed its maximum
* length, whether it is indefinite length and a pointer to the content.
* This is more efficient than calling asn1_collect because it does not
@ -996,21 +986,21 @@ asn1_find_end(const unsigned char **in, long len, char inf)
#endif
static int
asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
asn1_collect(CBB *cbb, const unsigned char **in, long len, char inf,
int tag, int aclass, int depth)
{
const unsigned char *p, *q;
long plen;
char cst, ininf;
if (depth > ASN1_MAX_STRING_NEST) {
ASN1error(ASN1_R_NESTED_ASN1_STRING);
return 0;
}
p = *in;
inf &= 1;
/* If no buffer and not indefinite length constructed just pass over
* the encoded data */
if (!buf && !inf) {
*in += len;
return 1;
}
while (len > 0) {
q = p;
/* Check for EOC */
@ -1033,15 +1023,14 @@ asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
/* If indefinite length constructed update max length */
if (cst) {
if (depth >= ASN1_MAX_STRING_NEST) {
ASN1error(ASN1_R_NESTED_ASN1_STRING);
return 0;
}
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
if (!asn1_collect(cbb, &p, plen, ininf, tag, aclass,
depth + 1))
return 0;
} else if (plen && !collect_data(buf, &p, plen))
} else if (plen > 0) {
if (!CBB_add_bytes(cbb, p, plen))
return 0;
p += plen;
}
len -= p - q;
}
if (inf) {
@ -1052,22 +1041,6 @@ asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, char inf,
return 1;
}
static int
collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
{
int len;
if (buf) {
len = buf->length;
if (!BUF_MEM_grow_clean(buf, len + plen)) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
}
*p += plen;
return 1;
}
/* Check for ASN1 EOC and swallow it if found */
static int
@ -1125,7 +1098,7 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) {
ASN1error(ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
return 0;
}
}
@ -1133,7 +1106,7 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
if (i & 0x80) {
ASN1error(ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
return 0;
}
if (exptag >= 0) {
@ -1143,13 +1116,13 @@ asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, char *inf,
*/
if (opt)
return -1;
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
ASN1error(ASN1_R_WRONG_TAG);
return 0;
}
/* We have a tag and class match:
* assume we are going to do something with it */
asn1_tlc_clear(ctx);
asn1_tlc_invalidate(ctx);
}
if (i & 1)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_enc.c,v 1.22 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_enc.c,v 1.24 2022/01/07 11:13:54 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -61,8 +61,11 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include "asn1_locl.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,
@ -152,9 +155,27 @@ ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
break;
case ASN1_ITYPE_MSTRING:
/*
* It never makes sense for multi-strings to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
return 0;
}
return asn1_i2d_ex_primitive(pval, out, it, -1, aclass);
case ASN1_ITYPE_CHOICE:
/*
* It never makes sense for CHOICE types to have implicit
* tagging, so if tag != -1, then this looks like an error in
* the template.
*/
if (tag != -1) {
ASN1error(ASN1_R_BAD_TEMPLATE);
return 0;
}
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = asn1_get_choice_selector(pval, it);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_fre.c,v 1.17 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_fre.c,v 1.18 2022/01/07 12:24:17 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -62,6 +62,8 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
#include "asn1_locl.h"
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
int combine);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_new.c,v 1.18 2019/04/01 15:48:04 jsing Exp $ */
/* $OpenBSD: tasn_new.c,v 1.21 2022/01/07 12:24:17 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -64,6 +64,8 @@
#include <openssl/asn1t.h>
#include <string.h>
#include "asn1_locl.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);
@ -103,10 +105,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!combine)
*pval = NULL;
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_push_info(it->sname);
#endif
switch (it->itype) {
case ASN1_ITYPE_EXTERN:
@ -136,10 +134,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
@ -160,10 +154,6 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
if (!i)
goto auxerr;
if (i == 2) {
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
}
}
@ -183,27 +173,15 @@ asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
goto auxerr;
break;
}
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 1;
memerr:
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
auxerr:
auxerr:
ASN1error(ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
#endif
return 0;
}
@ -257,10 +235,6 @@ ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
*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;
@ -276,11 +250,7 @@ ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
}
/* 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
done:
return ret;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_prn.c,v 1.21 2020/03/24 10:46:38 inoguchi Exp $ */
/* $OpenBSD: tasn_prn.c,v 1.22 2021/12/03 17:10:49 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -84,18 +84,14 @@ ASN1_PCTX default_pctx = {
ASN1_PCTX *
ASN1_PCTX_new(void)
{
ASN1_PCTX *ret;
ret = malloc(sizeof(ASN1_PCTX));
if (ret == NULL) {
ASN1_PCTX *p;
if ((p = calloc(1, sizeof(ASN1_PCTX))) == 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;
return p;
}
void

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_typ.c,v 1.13 2015/07/24 15:09:52 jsing Exp $ */
/* $OpenBSD: tasn_typ.c,v 1.17 2021/12/26 15:20:21 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -61,134 +61,6 @@
/* 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,
@ -221,13 +93,6 @@ ASN1_NULL_free(ASN1_NULL *a)
}
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,
@ -552,13 +417,13 @@ 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 = {
@ -568,31 +433,6 @@ const ASN1_ITEM ASN1_SEQUENCE_it = {
};
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 */
@ -712,6 +552,28 @@ const ASN1_ITEM ASN1_BOOLEAN_it = {
.sname = "ASN1_BOOLEAN",
};
int
i2d_ASN1_BOOLEAN(int a, unsigned char **out)
{
return ASN1_item_ex_i2d((ASN1_VALUE **)&a, out,
&ASN1_BOOLEAN_it, -1, 0);
}
int
d2i_ASN1_BOOLEAN(int *a, const unsigned char **in, long len)
{
ASN1_BOOLEAN abool;
if (ASN1_item_ex_d2i((ASN1_VALUE **)&abool, in, len, &ASN1_BOOLEAN_it,
-1, 0, 0, NULL) <= 0)
return -1;
if (a != NULL)
*a = abool;
return abool;
}
const ASN1_ITEM ASN1_TBOOLEAN_it = {
.itype = ASN1_ITYPE_PRIMITIVE,
.utype = V_ASN1_BOOLEAN,

View file

@ -1,4 +1,4 @@
/* $OpenBSD: tasn_utl.c,v 1.12 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: tasn_utl.c,v 1.13 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -272,7 +272,7 @@ asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr)
goto err;
return adb->default_tt;
err:
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr)
ASN1error(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_algor.c,v 1.22 2018/05/01 19:01:27 tb Exp $ */
/* $OpenBSD: x_algor.c,v 1.23 2021/12/12 14:27:20 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -197,12 +197,10 @@ X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, const void **ppval,
void
X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
{
int param_type;
int param_type = V_ASN1_NULL;
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
if ((EVP_MD_flags(md) & EVP_MD_FLAG_DIGALGID_ABSENT) != 0)
param_type = V_ASN1_UNDEF;
else
param_type = V_ASN1_NULL;
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_attrib.c,v 1.14 2020/06/04 21:21:03 schwarze Exp $ */
/* $OpenBSD: x_attrib.c,v 1.16 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -62,6 +62,8 @@
#include <openssl/objects.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_ATTRIBUTE: this has the following form:
*
* typedef struct x509_attributes_st
@ -192,7 +194,7 @@ X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
ASN1_TYPE_set(val, atrtype, value);
return (ret);
err:
err:
if (ret != NULL)
X509_ATTRIBUTE_free(ret);
if (val != NULL)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_crl.c,v 1.34 2019/03/13 20:34:00 tb Exp $ */
/* $OpenBSD: x_crl.c,v 1.37 2022/02/24 22:05:06 beck Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -66,6 +66,7 @@
#include <openssl/x509v3.h>
#include "asn1_locl.h"
#include "x509_lcl.h"
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
const X509_REVOKED * const *b);
@ -287,9 +288,7 @@ crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
break;
case ASN1_OP_D2I_POST:
#ifndef OPENSSL_NO_SHA
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
#endif
X509_CRL_digest(crl, X509_CRL_HASH_EVP, crl->hash, NULL);
crl->idp = X509_CRL_get_ext_d2i(crl,
NID_issuing_distribution_point, NULL, NULL);
if (crl->idp)
@ -659,14 +658,15 @@ X509_CRL_METHOD_new(int (*crl_init)(X509_CRL *crl),
{
X509_CRL_METHOD *m;
m = malloc(sizeof(X509_CRL_METHOD));
if (!m)
if ((m = calloc(1, sizeof(X509_CRL_METHOD))) == NULL)
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;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_exten.c,v 1.16 2015/07/24 15:09:52 jsing Exp $ */
/* $OpenBSD: x_exten.c,v 1.17 2021/11/01 20:53:08 tb Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
@ -61,6 +61,8 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include "x509_lcl.h"
static const ASN1_TEMPLATE X509_EXTENSION_seq_tt[] = {
{
.offset = offsetof(X509_EXTENSION, object),

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_name.c,v 1.34 2018/02/20 17:09:20 jsing Exp $ */
/* $OpenBSD: x_name.c,v 1.37 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -65,6 +65,7 @@
#include <openssl/x509.h>
#include "asn1_locl.h"
#include "x509_lcl.h"
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
@ -256,7 +257,7 @@ x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
*val = (ASN1_VALUE *)ret;
return 1;
memerr:
memerr:
ASN1error(ERR_R_MALLOC_FAILURE);
if (ret) {
if (ret->entries)
@ -336,7 +337,7 @@ x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long len,
*in = p;
return ret;
err:
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
ASN1error(ERR_R_NESTED_ASN1_ERROR);
@ -421,7 +422,7 @@ x509_name_encode(X509_NAME *a)
a->modified = 0;
return len;
memerr:
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
ASN1error(ERR_R_MALLOC_FAILURE);
@ -511,7 +512,7 @@ x509_name_canon(X509_NAME *a)
i2d_name_canon(intname, &p);
ret = 1;
err:
err:
if (tmpentry)
X509_NAME_ENTRY_free(tmpentry);
if (intname)
@ -626,19 +627,13 @@ i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname, unsigned char **in)
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) {
if (*xn == name)
return *xn != NULL;
if ((name = X509_NAME_dup(name)) == NULL)
return 0;
X509_NAME_free(*xn);
*xn = in;
}
}
return (*xn != NULL);
*xn = name;
return 1;
}
int

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_pkey.c,v 1.20 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: x_pkey.c,v 1.21 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -91,7 +91,7 @@ X509_PKEY_new(void)
ret->references = 1;
return (ret);
err:
err:
if (ret) {
X509_ALGOR_free(ret->enc_algor);
free(ret);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_pubkey.c,v 1.27 2018/03/17 14:55:39 jsing Exp $ */
/* $OpenBSD: x_pubkey.c,v 1.31 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -72,6 +72,8 @@
#endif
#include "asn1_locl.h"
#include "evp_locl.h"
#include "x509_lcl.h"
/* Minor tweak to operation: free up EVP_PKEY */
static int
@ -110,7 +112,6 @@ const ASN1_ITEM X509_PUBKEY_it = {
.sname = "X509_PUBKEY",
};
X509_PUBKEY *
d2i_X509_PUBKEY(X509_PUBKEY **a, const unsigned char **in, long len)
{
@ -168,7 +169,7 @@ X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
return 1;
error:
error:
if (pk != NULL)
X509_PUBKEY_free(pk);
return 0;
@ -221,7 +222,7 @@ X509_PUBKEY_get0(X509_PUBKEY *key)
return ret;
error:
error:
EVP_PKEY_free(ret);
return (NULL);
}
@ -239,168 +240,473 @@ X509_PUBKEY_get(X509_PUBKEY *key)
return pkey;
}
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
* and encode or decode as X509_PUBKEY
/*
* Decode an X509_PUBKEY into the specified key type.
*/
EVP_PKEY *
d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
static int
pubkey_ex_d2i(int pkey_type, ASN1_VALUE **pval, const unsigned char **in,
long len, const ASN1_ITEM *it)
{
X509_PUBKEY *xpk;
EVP_PKEY *pktmp;
xpk = d2i_X509_PUBKEY(NULL, pp, length);
if (!xpk)
return NULL;
pktmp = X509_PUBKEY_get(xpk);
X509_PUBKEY_free(xpk);
if (!pktmp)
return NULL;
if (a) {
EVP_PKEY_free(*a);
*a = pktmp;
const ASN1_EXTERN_FUNCS *ef = it->funcs;
const unsigned char *p = *in;
X509_PUBKEY *xpk = NULL;
ASN1_VALUE *key = NULL;
EVP_PKEY *pkey = NULL;
int ret = 0;
if ((xpk = d2i_X509_PUBKEY(NULL, &p, len)) == NULL)
goto err;
if ((pkey = X509_PUBKEY_get(xpk)) == NULL)
goto err;
switch (pkey_type) {
case EVP_PKEY_NONE:
key = (ASN1_VALUE *)pkey;
pkey = NULL;
break;
case EVP_PKEY_DSA:
key = (ASN1_VALUE *)EVP_PKEY_get1_DSA(pkey);
break;
case EVP_PKEY_RSA:
key = (ASN1_VALUE *)EVP_PKEY_get1_RSA(pkey);
break;
case EVP_PKEY_EC:
key = (ASN1_VALUE *)EVP_PKEY_get1_EC_KEY(pkey);
break;
default:
goto err;
}
return pktmp;
if (key == NULL)
goto err;
ef->asn1_ex_free(pval, it);
*pval = key;
*in = p;
ret = 1;
err:
EVP_PKEY_free(pkey);
X509_PUBKEY_free(xpk);
return ret;
}
int
i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
/*
* Encode the specified key type into an X509_PUBKEY.
*/
static int
pubkey_ex_i2d(int pkey_type, ASN1_VALUE **pval, unsigned char **out,
const ASN1_ITEM *it)
{
X509_PUBKEY *xpk = NULL;
int ret;
if (!a)
return 0;
if (!X509_PUBKEY_set(&xpk, a))
return 0;
ret = i2d_X509_PUBKEY(xpk, pp);
EVP_PKEY *pkey, *pktmp;
int ret = -1;
if ((pkey = pktmp = EVP_PKEY_new()) == NULL)
goto err;
switch (pkey_type) {
case EVP_PKEY_NONE:
pkey = (EVP_PKEY *)*pval;
break;
case EVP_PKEY_DSA:
if (!EVP_PKEY_set1_DSA(pkey, (DSA *)*pval))
goto err;
break;
case EVP_PKEY_RSA:
if (!EVP_PKEY_set1_RSA(pkey, (RSA *)*pval))
goto err;
break;
case EVP_PKEY_EC:
if (!EVP_PKEY_set1_EC_KEY(pkey, (EC_KEY*)*pval))
goto err;
break;
default:
goto err;
}
if (!X509_PUBKEY_set(&xpk, pkey))
goto err;
ret = i2d_X509_PUBKEY(xpk, out);
err:
EVP_PKEY_free(pktmp);
X509_PUBKEY_free(xpk);
return ret;
}
/* The following are equivalents but which return RSA and DSA
* keys
*/
#ifndef OPENSSL_NO_RSA
RSA *
d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
static int
pkey_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
RSA *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return NULL;
key = EVP_PKEY_get1_RSA(pkey);
EVP_PKEY_free(pkey);
if (!key)
return NULL;
*pp = q;
if (a) {
RSA_free(*a);
*a = key;
}
return key;
if ((*pval = (ASN1_VALUE *)EVP_PKEY_new()) == NULL)
return 0;
return 1;
}
static void
pkey_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY_free((EVP_PKEY *)*pval);
*pval = NULL;
}
static int
pkey_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_NONE, pval, in, len, it);
}
static int
pkey_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_NONE, pval, out, it);
}
const ASN1_EXTERN_FUNCS pkey_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = pkey_pubkey_ex_new,
.asn1_ex_free = pkey_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = pkey_pubkey_ex_d2i,
.asn1_ex_i2d = pkey_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM EVP_PKEY_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &pkey_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
EVP_PKEY *
d2i_PUBKEY(EVP_PKEY **pkey, const unsigned char **in, long len)
{
return (EVP_PKEY *)ASN1_item_d2i((ASN1_VALUE **)pkey, in, len,
&EVP_PKEY_PUBKEY_it);
}
int
i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
i2d_PUBKEY(EVP_PKEY *pkey, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return ASN1_item_i2d((ASN1_VALUE *)pkey, out, &EVP_PKEY_PUBKEY_it);
}
EVP_PKEY *
d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **pkey)
{
return (EVP_PKEY *)ASN1_item_d2i_bio(&EVP_PKEY_PUBKEY_it, bp,
(ASN1_VALUE **)pkey);
}
int
i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey)
{
return ASN1_item_i2d_bio(&EVP_PKEY_PUBKEY_it, bp, (ASN1_VALUE *)pkey);
}
EVP_PKEY *
d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **pkey)
{
return (EVP_PKEY *)ASN1_item_d2i_fp(&EVP_PKEY_PUBKEY_it, fp,
(ASN1_VALUE **)pkey);
}
int
i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey)
{
return ASN1_item_i2d_fp(&EVP_PKEY_PUBKEY_it, fp, (ASN1_VALUE *)pkey);
}
/*
* The following are equivalents but which return RSA and DSA keys.
*/
#ifndef OPENSSL_NO_RSA
static int
rsa_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
if ((*pval = (ASN1_VALUE *)RSA_new()) == NULL)
return 0;
pktmp = EVP_PKEY_new();
if (!pktmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_RSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
return 1;
}
static void
rsa_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
RSA_free((RSA *)*pval);
*pval = NULL;
}
static int
rsa_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_RSA, pval, in, len, it);
}
static int
rsa_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_RSA, pval, out, it);
}
const ASN1_EXTERN_FUNCS rsa_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = rsa_pubkey_ex_new,
.asn1_ex_free = rsa_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = rsa_pubkey_ex_d2i,
.asn1_ex_i2d = rsa_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM RSA_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &rsa_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
RSA *
d2i_RSA_PUBKEY(RSA **rsa, const unsigned char **in, long len)
{
return (RSA *)ASN1_item_d2i((ASN1_VALUE **)rsa, in, len,
&RSA_PUBKEY_it);
}
int
i2d_RSA_PUBKEY(RSA *rsa, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)rsa, out, &RSA_PUBKEY_it);
}
RSA *
d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
{
return (RSA *)ASN1_item_d2i_bio(&RSA_PUBKEY_it, bp, (ASN1_VALUE **)rsa);
}
int
i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
{
return ASN1_item_i2d_bio(&RSA_PUBKEY_it, bp, (ASN1_VALUE *)rsa);
}
RSA *
d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
{
return (RSA *)ASN1_item_d2i_fp(&RSA_PUBKEY_it, fp, (ASN1_VALUE **)rsa);
}
int
i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
{
return ASN1_item_i2d_fp(&RSA_PUBKEY_it, fp, (ASN1_VALUE *)rsa);
}
#endif
#ifndef OPENSSL_NO_DSA
DSA *
d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
static int
dsa_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
DSA *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return NULL;
key = EVP_PKEY_get1_DSA(pkey);
EVP_PKEY_free(pkey);
if (!key)
return NULL;
*pp = q;
if (a) {
DSA_free(*a);
*a = key;
}
return key;
if ((*pval = (ASN1_VALUE *)DSA_new()) == NULL)
return 0;
return 1;
}
static void
dsa_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
DSA_free((DSA *)*pval);
*pval = NULL;
}
static int
dsa_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_DSA, pval, in, len, it);
}
static int
dsa_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_DSA, pval, out, it);
}
const ASN1_EXTERN_FUNCS dsa_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = dsa_pubkey_ex_new,
.asn1_ex_free = dsa_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = dsa_pubkey_ex_d2i,
.asn1_ex_i2d = dsa_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM DSA_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &dsa_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
DSA *
d2i_DSA_PUBKEY(DSA **dsa, const unsigned char **in, long len)
{
return (DSA *)ASN1_item_d2i((ASN1_VALUE **)dsa, in, len,
&DSA_PUBKEY_it);
}
int
i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
i2d_DSA_PUBKEY(DSA *dsa, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return 0;
pktmp = EVP_PKEY_new();
if (!pktmp) {
ASN1error(ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_DSA(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return ret;
return ASN1_item_i2d((ASN1_VALUE *)dsa, out, &DSA_PUBKEY_it);
}
DSA *
d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa)
{
return (DSA *)ASN1_item_d2i_bio(&DSA_PUBKEY_it, bp, (ASN1_VALUE **)dsa);
}
int
i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa)
{
return ASN1_item_i2d_bio(&DSA_PUBKEY_it, bp, (ASN1_VALUE *)dsa);
}
DSA *
d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa)
{
return (DSA *)ASN1_item_d2i_fp(&DSA_PUBKEY_it, fp, (ASN1_VALUE **)dsa);
}
int
i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa)
{
return ASN1_item_i2d_fp(&DSA_PUBKEY_it, fp, (ASN1_VALUE *)dsa);
}
#endif
#ifndef OPENSSL_NO_EC
EC_KEY *
d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
static int
ec_pubkey_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EVP_PKEY *pkey;
EC_KEY *key;
const unsigned char *q;
q = *pp;
pkey = d2i_PUBKEY(NULL, &q, length);
if (!pkey)
return (NULL);
key = EVP_PKEY_get1_EC_KEY(pkey);
EVP_PKEY_free(pkey);
if (!key)
return (NULL);
*pp = q;
if (a) {
EC_KEY_free(*a);
*a = key;
}
return (key);
if ((*pval = (ASN1_VALUE *)EC_KEY_new()) == NULL)
return 0;
return 1;
}
static void
ec_pubkey_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
{
EC_KEY_free((EC_KEY *)*pval);
*pval = NULL;
}
static int
ec_pubkey_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx)
{
return pubkey_ex_d2i(EVP_PKEY_EC, pval, in, len, it);
}
static int
ec_pubkey_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it,
int tag, int aclass)
{
return pubkey_ex_i2d(EVP_PKEY_EC, pval, out, it);
}
const ASN1_EXTERN_FUNCS ec_pubkey_asn1_ff = {
.app_data = NULL,
.asn1_ex_new = ec_pubkey_ex_new,
.asn1_ex_free = ec_pubkey_ex_free,
.asn1_ex_clear = NULL,
.asn1_ex_d2i = ec_pubkey_ex_d2i,
.asn1_ex_i2d = ec_pubkey_ex_i2d,
.asn1_ex_print = NULL,
};
const ASN1_ITEM EC_PUBKEY_it = {
.itype = ASN1_ITYPE_EXTERN,
.utype = 0,
.templates = NULL,
.tcount = 0,
.funcs = &ec_pubkey_asn1_ff,
.size = 0,
.sname = NULL,
};
EC_KEY *
d2i_EC_PUBKEY(EC_KEY **ec, const unsigned char **in, long len)
{
return (EC_KEY *)ASN1_item_d2i((ASN1_VALUE **)ec, in, len,
&EC_PUBKEY_it);
}
int
i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
i2d_EC_PUBKEY(EC_KEY *ec, unsigned char **out)
{
EVP_PKEY *pktmp;
int ret;
if (!a)
return (0);
if ((pktmp = EVP_PKEY_new()) == NULL) {
ASN1error(ERR_R_MALLOC_FAILURE);
return (0);
}
EVP_PKEY_set1_EC_KEY(pktmp, a);
ret = i2d_PUBKEY(pktmp, pp);
EVP_PKEY_free(pktmp);
return (ret);
return ASN1_item_i2d((ASN1_VALUE *)ec, out, &EC_PUBKEY_it);
}
EC_KEY *
d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **ec)
{
return (EC_KEY *)ASN1_item_d2i_bio(&EC_PUBKEY_it, bp, (ASN1_VALUE **)ec);
}
int
i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ec)
{
return ASN1_item_i2d_bio(&EC_PUBKEY_it, bp, (ASN1_VALUE *)ec);
}
EC_KEY *
d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **ec)
{
return (EC_KEY *)ASN1_item_d2i_fp(&EC_PUBKEY_it, fp, (ASN1_VALUE **)ec);
}
int
i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *ec)
{
return ASN1_item_i2d_fp(&EC_PUBKEY_it, fp, (ASN1_VALUE *)ec);
}
#endif

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_req.c,v 1.17 2018/02/22 16:50:30 jsing Exp $ */
/* $OpenBSD: x_req.c,v 1.18 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -61,6 +61,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_REQ_INFO is handled in an unusual way to get round
* invalid encodings. Some broken certificate requests don't
* encode the attributes field if it is empty. This is in

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_sig.c,v 1.11 2015/02/11 04:00:39 jsing Exp $ */
/* $OpenBSD: x_sig.c,v 1.13 2021/11/01 20:53:08 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -61,6 +61,8 @@
#include <openssl/asn1t.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
static const ASN1_TEMPLATE X509_SIG_seq_tt[] = {
{
.offset = offsetof(X509_SIG, algor),
@ -108,3 +110,22 @@ X509_SIG_free(X509_SIG *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_SIG_it);
}
void
X509_SIG_get0(const X509_SIG *sig, const X509_ALGOR **palg,
const ASN1_OCTET_STRING **pdigest)
{
if (palg != NULL)
*palg = sig->algor;
if (pdigest != NULL)
*pdigest = sig->digest;
}
void
X509_SIG_getm(X509_SIG *sig, X509_ALGOR **palg, ASN1_OCTET_STRING **pdigest)
{
if (palg != NULL)
*palg = sig->algor;
if (pdigest != NULL)
*pdigest = sig->digest;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_x509.c,v 1.26 2018/02/17 15:50:42 jsing Exp $ */
/* $OpenBSD: x_x509.c,v 1.30 2021/12/25 13:17:48 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -65,6 +65,8 @@
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "x509_lcl.h"
static const ASN1_AUX X509_CINF_aux = {
.flags = ASN1_AFLG_ENCODING,
.enc_offset = offsetof(X509_CINF, enc),
@ -185,6 +187,10 @@ x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
ret->akid = NULL;
ret->aux = NULL;
ret->crldp = NULL;
#ifndef OPENSSL_NO_RFC3779
ret->rfc3779_addr = NULL;
ret->rfc3779_asid = NULL;
#endif
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data);
break;
@ -202,6 +208,10 @@ x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg)
policy_cache_free(ret->policy_cache);
GENERAL_NAMES_free(ret->altname);
NAME_CONSTRAINTS_free(ret->nc);
#ifndef OPENSSL_NO_RFC3779
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
ASIdentifiers_free(ret->rfc3779_asid);
#endif
free(ret->name);
ret->name = NULL;
break;
@ -329,7 +339,7 @@ d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
}
return ret;
err:
err:
X509_free(ret);
return NULL;
}
@ -345,6 +355,13 @@ i2d_X509_AUX(X509 *a, unsigned char **pp)
return length;
}
int
i2d_re_X509_tbs(X509 *x, unsigned char **pp)
{
x->cert_info->enc.modified = 1;
return i2d_X509_CINF(x->cert_info, pp);
}
void
X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg,
const X509 *x)

View file

@ -1,4 +1,4 @@
/* $OpenBSD: x_x509a.c,v 1.15 2018/05/01 19:01:27 tb Exp $ */
/* $OpenBSD: x_x509a.c,v 1.18 2021/12/25 13:17:48 jsing Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 1999.
*/
@ -62,6 +62,8 @@
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "x509_lcl.h"
/* X509_CERT_AUX routines. These are used to encode additional
* user modifiable data about a certificate. This data is
* appended to the X509 encoding when the *_X509_AUX routines
@ -226,7 +228,7 @@ X509_add1_trust_object(X509 *x, const ASN1_OBJECT *obj)
if (rc != 0)
return rc;
err:
err:
ASN1_OBJECT_free(objtmp);
return 0;
}
@ -248,7 +250,7 @@ X509_add1_reject_object(X509 *x, const ASN1_OBJECT *obj)
if (rc != 0)
return rc;
err:
err:
ASN1_OBJECT_free(objtmp);
return 0;
}
@ -270,56 +272,3 @@ X509_reject_clear(X509 *x)
x->aux->reject = NULL;
}
}
static const ASN1_TEMPLATE X509_CERT_PAIR_seq_tt[] = {
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 0,
.offset = offsetof(X509_CERT_PAIR, forward),
.field_name = "forward",
.item = &X509_it,
},
{
.flags = ASN1_TFLG_EXPLICIT | ASN1_TFLG_OPTIONAL,
.tag = 1,
.offset = offsetof(X509_CERT_PAIR, reverse),
.field_name = "reverse",
.item = &X509_it,
},
};
const ASN1_ITEM X509_CERT_PAIR_it = {
.itype = ASN1_ITYPE_SEQUENCE,
.utype = V_ASN1_SEQUENCE,
.templates = X509_CERT_PAIR_seq_tt,
.tcount = sizeof(X509_CERT_PAIR_seq_tt) / sizeof(ASN1_TEMPLATE),
.funcs = NULL,
.size = sizeof(X509_CERT_PAIR),
.sname = "X509_CERT_PAIR",
};
X509_CERT_PAIR *
d2i_X509_CERT_PAIR(X509_CERT_PAIR **a, const unsigned char **in, long len)
{
return (X509_CERT_PAIR *)ASN1_item_d2i((ASN1_VALUE **)a, in, len,
&X509_CERT_PAIR_it);
}
int
i2d_X509_CERT_PAIR(X509_CERT_PAIR *a, unsigned char **out)
{
return ASN1_item_i2d((ASN1_VALUE *)a, out, &X509_CERT_PAIR_it);
}
X509_CERT_PAIR *
X509_CERT_PAIR_new(void)
{
return (X509_CERT_PAIR *)ASN1_item_new(&X509_CERT_PAIR_it);
}
void
X509_CERT_PAIR_free(X509_CERT_PAIR *a)
{
ASN1_item_free((ASN1_VALUE *)a, &X509_CERT_PAIR_it);
}

View file

@ -1,10 +1,10 @@
/* $OpenBSD: b_dump.c,v 1.21 2015/04/23 06:11:19 deraadt Exp $ */
/* $OpenBSD: b_dump.c,v 1.22 2021/07/11 20:18:07 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.
* 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
@ -82,7 +82,7 @@ BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
{
int ret = 0;
char buf[288 + 1], tmp[20], str[128 + 1];
int i, j, rows, trc;
int i, j, rows, trc, written;
unsigned char ch;
int dump_width;
@ -133,13 +133,18 @@ BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
/* if this is the last call then update the ddt_dump thing so
* that we will move the selection point in the debug window
*/
ret += cb((void *)buf, strlen(buf), u);
if ((written = cb((void *)buf, strlen(buf), u)) < 0)
return -1;
ret += written;
}
#ifdef TRUNCATE
if (trc > 0) {
snprintf(buf, sizeof buf, "%s%04x - <SPACES/NULS>\n",
str, len + trc);
ret += cb((void *)buf, strlen(buf), u);
if ((written = cb((void *)buf, strlen(buf), u)) < 0)
return -1;
ret += written;
}
#endif
return (ret);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bf_buff.c,v 1.25 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bf_buff.c,v 1.27 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -63,6 +63,8 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include "bio_local.h"
static int buffer_write(BIO *h, const char *buf, int num);
static int buffer_read(BIO *h, char *buf, int size);
static int buffer_puts(BIO *h, const char *str);
@ -70,7 +72,7 @@ static int buffer_gets(BIO *h, char *str, int size);
static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int buffer_new(BIO *h);
static int buffer_free(BIO *data);
static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
#define DEFAULT_BUFFER_SIZE 4096
static const BIO_METHOD methods_buffer = {
@ -450,7 +452,7 @@ malloc_error:
}
static long
buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
buffer_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bf_nbio.c,v 1.20 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bf_nbio.c,v 1.22 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -62,6 +62,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
@ -72,7 +74,7 @@ static int nbiof_gets(BIO *h, char *str, int size);
static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int nbiof_new(BIO *h);
static int nbiof_free(BIO *data);
static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static long nbiof_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
typedef struct nbio_test_st {
/* only set if we sent a 'should retry' error */
@ -221,7 +223,7 @@ nbiof_ctrl(BIO *b, int cmd, long num, void *ptr)
}
static long
nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
nbiof_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bf_null.c,v 1.12 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bf_null.c,v 1.14 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -61,6 +61,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
/* BIO_put and BIO_get both add to the digest,
* BIO_gets returns the digest */
@ -71,7 +73,7 @@ static int nullf_gets(BIO *h, char *str, int size);
static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int nullf_new(BIO *h);
static int nullf_free(BIO *data);
static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
static long nullf_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp);
static const BIO_METHOD methods_nullf = {
.type = BIO_TYPE_NULL_FILTER,
@ -165,7 +167,7 @@ nullf_ctrl(BIO *b, int cmd, long num, void *ptr)
}
static long
nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
nullf_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_cb.c,v 1.16 2014/12/08 03:54:19 bcook Exp $ */
/* $OpenBSD: bio_cb.c,v 1.18 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -63,6 +63,8 @@
#include <openssl/err.h>
#include <openssl/bio.h>
#include "bio_local.h"
long
BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, long argl,
long ret)
@ -70,15 +72,22 @@ BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, long argl,
BIO *b;
char buf[256];
char *p;
int nbuf;
long r = 1;
size_t p_maxlen;
if (BIO_CB_RETURN & cmd)
r = ret;
snprintf(buf, sizeof buf, "BIO[%p]:", bio);
p = &(buf[14]);
p_maxlen = sizeof buf - 14;
nbuf = snprintf(buf, sizeof(buf), "BIO[%p]: ", bio);
if (nbuf < 0)
nbuf = 0; /* Ignore error; continue printing. */
if (nbuf >= sizeof(buf))
goto out;
p = buf + nbuf;
p_maxlen = sizeof(buf) - nbuf;
switch (cmd) {
case BIO_CB_FREE:
snprintf(p, p_maxlen, "Free - %s\n", bio->method->name);
@ -136,6 +145,7 @@ BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, long argl,
break;
}
out:
b = (BIO *)bio->cb_arg;
if (b != NULL)
BIO_write(b, buf, strlen(buf));

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_err.c,v 1.17 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bio_err.c,v 1.18 2022/01/14 08:40:57 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
*
@ -92,6 +92,7 @@ static ERR_STRING_DATA BIO_str_reasons[] = {
{ERR_REASON(BIO_R_INVALID_PORT_NUMBER) , "invalid port number"},
{ERR_REASON(BIO_R_IN_USE) , "in use"},
{ERR_REASON(BIO_R_KEEPALIVE) , "keepalive"},
{ERR_REASON(BIO_R_LENGTH_TOO_LONG) , "too long"},
{ERR_REASON(BIO_R_NBIO_CONNECT_ERROR) , "nbio connect error"},
{ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"},
{ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED) , "no hostname specified"},

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_lib.c,v 1.29 2019/04/14 17:39:03 jsing Exp $ */
/* $OpenBSD: bio_lib.c,v 1.35 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -57,6 +57,7 @@
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <openssl/bio.h>
@ -64,6 +65,57 @@
#include <openssl/err.h>
#include <openssl/stack.h>
#include "bio_local.h"
/*
* Helper function to work out whether to call the new style callback or the old
* one, and translate between the two.
*
* This has a long return type for consistency with the old callback. Similarly
* for the "long" used for "inret"
*/
static long
bio_call_callback(BIO *b, int oper, const char *argp, size_t len, int argi,
long argl, long inret, size_t *processed)
{
long ret;
int bareoper;
if (b->callback_ex != NULL)
return b->callback_ex(b, oper, argp, len, argi, argl, inret,
processed);
/*
* We have an old style callback, so we will have to do nasty casts and
* check for overflows.
*/
bareoper = oper & ~BIO_CB_RETURN;
if (bareoper == BIO_CB_READ || bareoper == BIO_CB_WRITE ||
bareoper == BIO_CB_GETS) {
/* In this case len is set and should be used instead of argi. */
if (len > INT_MAX)
return -1;
argi = (int)len;
}
if (inret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
if (*processed > INT_MAX)
return -1;
inret = *processed;
}
ret = b->callback(b, oper, argp, argi, argl, inret);
if (ret > 0 && (oper & BIO_CB_RETURN) && bareoper != BIO_CB_CTRL) {
*processed = (size_t)ret;
ret = 1;
}
return ret;
}
int
BIO_get_new_index(void)
{
@ -83,6 +135,7 @@ BIO_new(const BIO_METHOD *method)
{
BIO *ret = NULL;
/* XXX calloc */
ret = malloc(sizeof(BIO));
if (ret == NULL) {
BIOerror(ERR_R_MALLOC_FAILURE);
@ -100,6 +153,7 @@ BIO_set(BIO *bio, const BIO_METHOD *method)
{
bio->method = method;
bio->callback = NULL;
bio->callback_ex = NULL;
bio->cb_arg = NULL;
bio->init = 0;
bio->shutdown = 1;
@ -113,29 +167,32 @@ BIO_set(BIO *bio, const BIO_METHOD *method)
bio->num_read = 0L;
bio->num_write = 0L;
CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data);
if (method->create != NULL)
if (method->create != NULL) {
if (!method->create(bio)) {
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio,
&bio->ex_data);
return (0);
}
}
return (1);
}
int
BIO_free(BIO *a)
{
int i;
int ret;
if (a == NULL)
return (0);
i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO);
if (i > 0)
if (CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO) > 0)
return (1);
if ((a->callback != NULL) &&
((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0))
return (i);
if (a->callback != NULL || a->callback_ex != NULL) {
if ((ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0,
0L, 1L, NULL)) <= 0)
return (ret);
}
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data);
@ -170,6 +227,12 @@ BIO_set_data(BIO *a, void *ptr)
a->ptr = ptr;
}
int
BIO_get_init(BIO *a)
{
return a->init;
}
void
BIO_set_init(BIO *a, int init)
{
@ -206,20 +269,30 @@ BIO_set_flags(BIO *b, int flags)
b->flags |= flags;
}
long
(*BIO_get_callback(const BIO *b))(struct bio_st *, int, const char *, int,
long, long)
BIO_callback_fn
BIO_get_callback(const BIO *b)
{
return b->callback;
}
void
BIO_set_callback(BIO *b, long (*cb)(struct bio_st *, int, const char *, int,
long, long))
BIO_set_callback(BIO *b, BIO_callback_fn cb)
{
b->callback = cb;
}
BIO_callback_fn_ex
BIO_get_callback_ex(const BIO *b)
{
return b->callback_ex;
}
void
BIO_set_callback_ex(BIO *b, BIO_callback_fn_ex cb)
{
b->callback_ex = cb;
}
void
BIO_set_callback_arg(BIO *b, char *arg)
{
@ -247,8 +320,8 @@ BIO_method_type(const BIO *b)
int
BIO_read(BIO *b, void *out, int outl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
size_t readbytes = 0;
int ret;
if (b == NULL)
return (0);
@ -261,33 +334,44 @@ BIO_read(BIO *b, void *out, int outl)
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0))
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = (int)bio_call_callback(b, BIO_CB_READ, out, outl, 0,
0L, 1L, NULL)) <= 0)
return (ret);
}
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bread(b, out, outl);
if ((ret = b->method->bread(b, out, outl)) > 0)
readbytes = (size_t)ret;
if (i > 0)
b->num_read += (unsigned long)i;
b->num_read += readbytes;
if (cb != NULL)
i = (int)cb(b, BIO_CB_READ|BIO_CB_RETURN, out, outl,
0L, (long)i);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = (int)bio_call_callback(b, BIO_CB_READ | BIO_CB_RETURN,
out, outl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes);
}
return (i);
if (ret > 0) {
if (readbytes > INT_MAX) {
BIOerror(BIO_R_LENGTH_TOO_LONG);
ret = -1;
} else {
ret = (int)readbytes;
}
}
return (ret);
}
int
BIO_write(BIO *b, const void *in, int inl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
size_t writebytes = 0;
int ret;
if (b == NULL)
return (0);
@ -300,95 +384,132 @@ BIO_write(BIO *b, const void *in, int inl)
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0))
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = (int)bio_call_callback(b, BIO_CB_WRITE, in, inl, 0,
0L, 1L, NULL)) <= 0)
return (ret);
}
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bwrite(b, in, inl);
if ((ret = b->method->bwrite(b, in, inl)) > 0)
writebytes = ret;
if (i > 0)
b->num_write += (unsigned long)i;
b->num_write += writebytes;
if (cb != NULL)
i = (int)cb(b, BIO_CB_WRITE|BIO_CB_RETURN, in, inl,
0L, (long)i);
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = (int)bio_call_callback(b, BIO_CB_WRITE | BIO_CB_RETURN,
in, inl, 0, 0L, (ret > 0) ? 1 : ret, &writebytes);
}
if (ret > 0) {
if (writebytes > INT_MAX) {
BIOerror(BIO_R_LENGTH_TOO_LONG);
ret = -1;
} else {
ret = (int)writebytes;
}
}
return (ret);
}
int
BIO_puts(BIO *b, const char *in)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
size_t writebytes = 0;
int ret;
if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) {
if (b == NULL || b->method == NULL || b->method->bputs == NULL) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0))
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = (int)bio_call_callback(b, BIO_CB_PUTS, in, 0, 0, 0L,
1L, NULL)) <= 0)
return (ret);
}
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bputs(b, in);
if ((ret = b->method->bputs(b, in)) > 0)
writebytes = ret;
if (i > 0)
b->num_write += (unsigned long)i;
b->num_write += writebytes;
if (cb != NULL)
i = (int)cb(b, BIO_CB_PUTS|BIO_CB_RETURN, in, 0, 0L, (long)i);
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = (int)bio_call_callback(b, BIO_CB_PUTS | BIO_CB_RETURN,
in, 0, 0, 0L, (ret > 0) ? 1 : ret, &writebytes);
}
if (ret > 0) {
if (writebytes > INT_MAX) {
BIOerror(BIO_R_LENGTH_TOO_LONG);
ret = -1;
} else {
ret = (int)writebytes;
}
}
return (ret);
}
int
BIO_gets(BIO *b, char *in, int inl)
{
int i;
long (*cb)(BIO *, int, const char *, int, long, long);
size_t readbytes;
int ret;
if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) {
if (b == NULL || b->method == NULL || b->method->bgets == NULL) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0))
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = (int)bio_call_callback(b, BIO_CB_GETS, in, inl, 0, 0L,
1, NULL)) <= 0)
return (ret);
}
if (!b->init) {
BIOerror(BIO_R_UNINITIALIZED);
return (-2);
}
i = b->method->bgets(b, in, inl);
if ((ret = b->method->bgets(b, in, inl)) > 0)
readbytes = ret;
if (cb != NULL)
i = (int)cb(b, BIO_CB_GETS|BIO_CB_RETURN, in, inl, 0L, (long)i);
return (i);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = (int)bio_call_callback(b, BIO_CB_GETS | BIO_CB_RETURN, in,
inl, 0, 0L, (ret > 0) ? 1 : ret, &readbytes);
}
if (ret > 0) {
if (readbytes > INT_MAX) {
BIOerror(BIO_R_LENGTH_TOO_LONG);
ret = -1;
} else {
ret = (int)readbytes;
}
}
return (ret);
}
int
BIO_indent(BIO *b, int indent, int max)
{
if (indent < 0)
indent = 0;
if (indent > max)
indent = max;
if (indent < 0)
indent = 0;
while (indent--)
if (BIO_puts(b, " ") != 1)
return 0;
@ -419,54 +540,58 @@ long
BIO_ctrl(BIO *b, int cmd, long larg, void *parg)
{
long ret;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if ((b->method == NULL) || (b->method->ctrl == NULL)) {
if (b->method == NULL || b->method->ctrl == NULL) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0))
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = bio_call_callback(b, BIO_CB_CTRL, parg, 0, cmd, larg,
1L, NULL)) <= 0)
return (ret);
}
ret = b->method->ctrl(b, cmd, larg, parg);
if (cb != NULL)
ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, parg, cmd, larg, ret);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, 0,
cmd, larg, ret, NULL);
}
return (ret);
}
long
BIO_callback_ctrl(BIO *b, int cmd,
void (*fp)(struct bio_st *, int, const char *, int, long, long))
BIO_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret;
long (*cb)(BIO *, int, const char *, int, long, long);
if (b == NULL)
return (0);
if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) {
if (b->method == NULL || b->method->callback_ctrl == NULL ||
cmd != BIO_CTRL_SET_CALLBACK) {
BIOerror(BIO_R_UNSUPPORTED_METHOD);
return (-2);
}
cb = b->callback;
if ((cb != NULL) &&
((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0))
if (b->callback != NULL || b->callback_ex != NULL) {
if ((ret = bio_call_callback(b, BIO_CB_CTRL, (void *)&fp, 0,
cmd, 0, 1L, NULL)) <= 0)
return (ret);
}
ret = b->method->callback_ctrl(b, cmd, fp);
if (cb != NULL)
ret = cb(b, BIO_CB_CTRL|BIO_CB_RETURN, (void *)&fp, cmd, 0, ret);
if (b->callback != NULL || b->callback_ex != NULL) {
ret = bio_call_callback(b, BIO_CB_CTRL | BIO_CB_RETURN,
(void *)&fp, 0, cmd, 0, ret, NULL);
}
return (ret);
}
@ -552,6 +677,12 @@ BIO_get_retry_reason(BIO *bio)
return (bio->retry_reason);
}
void
BIO_set_retry_reason(BIO *bio, int reason)
{
bio->retry_reason = reason;
}
BIO *
BIO_find_type(BIO *bio, int type)
{
@ -582,6 +713,12 @@ BIO_next(BIO *b)
return b->next_bio;
}
void
BIO_set_next(BIO *b, BIO *next)
{
b->next_bio = next;
}
void
BIO_free_all(BIO *bio)
{
@ -608,6 +745,7 @@ BIO_dup_chain(BIO *in)
if ((new_bio = BIO_new(bio->method)) == NULL)
goto err;
new_bio->callback = bio->callback;
new_bio->callback_ex = bio->callback_ex;
new_bio->cb_arg = bio->cb_arg;
new_bio->init = bio->init;
new_bio->shutdown = bio->shutdown;

123
externals/libressl/crypto/bio/bio_local.h vendored Executable file
View file

@ -0,0 +1,123 @@
/* $OpenBSD: bio_local.h,v 1.3 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_BIO_LOCAL_H
#define HEADER_BIO_LOCAL_H
__BEGIN_HIDDEN_DECLS
struct bio_method_st {
int type;
const char *name;
int (*bwrite)(BIO *, const char *, int);
int (*bread)(BIO *, char *, int);
int (*bputs)(BIO *, const char *);
int (*bgets)(BIO *, char *, int);
long (*ctrl)(BIO *, int, long, void *);
int (*create)(BIO *);
int (*destroy)(BIO *);
long (*callback_ctrl)(BIO *, int, BIO_info_cb *);
} /* BIO_METHOD */;
struct bio_st {
const BIO_METHOD *method;
BIO_callback_fn callback;
BIO_callback_fn_ex callback_ex;
char *cb_arg; /* first argument for the callback */
int init;
int shutdown;
int flags; /* extra storage */
int retry_reason;
int num;
void *ptr;
struct bio_st *next_bio; /* used by filter BIOs */
struct bio_st *prev_bio; /* used by filter BIOs */
int references;
unsigned long num_read;
unsigned long num_write;
CRYPTO_EX_DATA ex_data;
} /* BIO */;
typedef struct bio_f_buffer_ctx_struct {
/* Buffers are setup like this:
*
* <---------------------- size ----------------------->
* +---------------------------------------------------+
* | consumed | remaining | free space |
* +---------------------------------------------------+
* <-- off --><------- len ------->
*/
/* BIO *bio; */ /* this is now in the BIO struct */
int ibuf_size; /* how big is the input buffer */
int obuf_size; /* how big is the output buffer */
char *ibuf; /* the char array */
int ibuf_len; /* how many bytes are in it */
int ibuf_off; /* write/read offset */
char *obuf; /* the char array */
int obuf_len; /* how many bytes are in it */
int obuf_off; /* write/read offset */
} BIO_F_BUFFER_CTX;
__END_HIDDEN_DECLS
#endif /* !HEADER_BIO_LOCAL_H */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bio_meth.c,v 1.6 2018/06/02 04:41:12 tb Exp $ */
/* $OpenBSD: bio_meth.c,v 1.8 2022/01/14 08:40:57 tb Exp $ */
/*
* Copyright (c) 2018 Theo Buehler <tb@openbsd.org>
*
@ -19,6 +19,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
BIO_METHOD *
BIO_meth_new(int type, const char *name)
{
@ -133,15 +135,13 @@ BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy)(BIO *))
long
(*BIO_meth_get_callback_ctrl(const BIO_METHOD *biom))(BIO *, int, BIO_info_cb *)
{
return
(long (*)(BIO *, int, BIO_info_cb *))biom->callback_ctrl; /* XXX */
return biom->callback_ctrl;
}
int
BIO_meth_set_callback_ctrl(BIO_METHOD *biom,
long (*callback_ctrl)(BIO *, int, BIO_info_cb *))
{
biom->callback_ctrl =
(long (*)(BIO *, int, bio_info_cb *))callback_ctrl; /* XXX */
biom->callback_ctrl = callback_ctrl;
return 1;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_acpt.c,v 1.29 2018/05/12 18:51:59 tb Exp $ */
/* $OpenBSD: bss_acpt.c,v 1.30 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -67,6 +67,8 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "bio_local.h"
#define SOCKET_PROTOCOL IPPROTO_TCP
typedef struct bio_accept_st {

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_bio.c,v 1.24 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bss_bio.c,v 1.25 2022/01/07 09:02:17 tb Exp $ */
/* ====================================================================
* Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved.
*
@ -84,6 +84,8 @@
#include <openssl/err.h>
#include <openssl/crypto.h>
#include "bio_local.h"
static int bio_new(BIO *bio);
static int bio_free(BIO *bio);
static int bio_read(BIO *bio, char *buf, int size);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_conn.c,v 1.35 2018/05/12 18:51:59 tb Exp $ */
/* $OpenBSD: bss_conn.c,v 1.37 2022/01/14 08:40:57 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -70,6 +70,8 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "bio_local.h"
#define SOCKET_PROTOCOL IPPROTO_TCP
typedef struct bio_connect_st {
@ -90,7 +92,7 @@ typedef struct bio_connect_st {
/* called when the connection is initially made
* callback(BIO,state,ret); The callback should return
* 'ret'. state is for compatibility with the ssl info_callback */
int (*info_callback)(const BIO *bio, int state, int ret);
BIO_info_cb *info_callback;
} BIO_CONNECT;
static int conn_write(BIO *h, const char *buf, int num);
@ -99,7 +101,7 @@ static int conn_puts(BIO *h, const char *str);
static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int conn_new(BIO *h);
static int conn_free(BIO *data);
static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *);
static long conn_callback_ctrl(BIO *h, int cmd, BIO_info_cb *);
static int conn_state(BIO *b, BIO_CONNECT *c);
static void conn_close_socket(BIO *data);
@ -124,7 +126,7 @@ conn_state(BIO *b, BIO_CONNECT *c)
int ret = -1, i;
unsigned long l;
char *p, *q;
int (*cb)(const BIO *, int, int) = NULL;
BIO_info_cb *cb = NULL;
if (c->info_callback != NULL)
cb = c->info_callback;
@ -521,9 +523,7 @@ conn_ctrl(BIO *b, int cmd, long num, void *ptr)
BIO_set_conn_hostname(dbio,
data->param_hostname);
BIO_set_nbio(dbio, data->nbio);
/* FIXME: the cast of the function seems unlikely to be a good idea */
(void)BIO_set_info_callback(dbio,
(bio_info_cb *)data->info_callback);
(void)BIO_set_info_callback(dbio, data->info_callback);
}
break;
case BIO_CTRL_SET_CALLBACK:
@ -538,9 +538,8 @@ conn_ctrl(BIO *b, int cmd, long num, void *ptr)
break;
case BIO_CTRL_GET_CALLBACK:
{
int (**fptr)(const BIO *bio, int state, int xret);
BIO_info_cb **fptr = ptr;
fptr = (int (**)(const BIO *bio, int state, int xret))ptr;
*fptr = data->info_callback;
}
break;
@ -552,7 +551,7 @@ conn_ctrl(BIO *b, int cmd, long num, void *ptr)
}
static long
conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
conn_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp)
{
long ret = 1;
BIO_CONNECT *data;
@ -561,9 +560,7 @@ conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
switch (cmd) {
case BIO_CTRL_SET_CALLBACK:
{
data->info_callback = (int (*)(const struct bio_st *, int, int))fp;
}
data->info_callback = (BIO_info_cb *)fp;
break;
default:
ret = 0;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_dgram.c,v 1.42 2018/05/12 17:47:53 tb Exp $ */
/* $OpenBSD: bss_dgram.c,v 1.43 2022/01/07 09:02:17 tb Exp $ */
/*
* DTLS implementation written by Nagendra Modadugu
* (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
@ -72,6 +72,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
#ifndef OPENSSL_NO_DGRAM

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_fd.c,v 1.19 2018/05/01 13:29:09 tb Exp $ */
/* $OpenBSD: bss_fd.c,v 1.20 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -65,6 +65,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
static int fd_write(BIO *h, const char *buf, int num);
static int fd_read(BIO *h, char *buf, int size);
static int fd_puts(BIO *h, const char *str);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_file.c,v 1.33 2018/05/30 00:23:04 tb Exp $ */
/* $OpenBSD: bss_file.c,v 1.34 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -90,6 +90,8 @@
#include <openssl/bio.h>
#include <openssl/err.h>
#include "bio_local.h"
static int file_write(BIO *h, const char *buf, int num);
static int file_read(BIO *h, char *buf, int size);
static int file_puts(BIO *h, const char *str);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_log.c,v 1.22 2018/05/01 13:29:10 tb Exp $ */
/* $OpenBSD: bss_log.c,v 1.23 2022/01/07 09:02:17 tb Exp $ */
/* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
*
@ -70,6 +70,8 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
#include "bio_local.h"
#ifndef NO_SYSLOG
static int slg_write(BIO *h, const char *buf, int num);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_mem.c,v 1.17 2018/05/12 18:51:59 tb Exp $ */
/* $OpenBSD: bss_mem.c,v 1.21 2022/02/19 15:59:12 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -57,6 +57,7 @@
*/
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
@ -64,13 +65,35 @@
#include <openssl/err.h>
#include <openssl/buffer.h>
static int mem_write(BIO *h, const char *buf, int num);
static int mem_read(BIO *h, char *buf, int size);
static int mem_puts(BIO *h, const char *str);
static int mem_gets(BIO *h, char *str, int size);
static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int mem_new(BIO *h);
static int mem_free(BIO *data);
#include "bio_local.h"
struct bio_mem {
BUF_MEM *buf;
size_t read_offset;
};
static size_t
bio_mem_pending(struct bio_mem *bm)
{
if (bm->read_offset > bm->buf->length)
return 0;
return bm->buf->length - bm->read_offset;
}
static uint8_t *
bio_mem_read_ptr(struct bio_mem *bm)
{
return &bm->buf->data[bm->read_offset];
}
static int mem_new(BIO *bio);
static int mem_free(BIO *bio);
static int mem_write(BIO *bio, const char *in, int in_len);
static int mem_read(BIO *bio, char *out, int out_len);
static int mem_puts(BIO *bio, const char *in);
static int mem_gets(BIO *bio, char *out, int out_len);
static long mem_ctrl(BIO *bio, int cmd, long arg1, void *arg2);
static const BIO_METHOD mem_method = {
.type = BIO_TYPE_MEM,
@ -84,181 +107,207 @@ static const BIO_METHOD mem_method = {
.destroy = mem_free
};
/* bio->num is used to hold the value to return on 'empty', if it is
* 0, should_retry is not set */
/*
* bio->num is used to hold the value to return on 'empty', if it is
* 0, should_retry is not set.
*/
const BIO_METHOD *
BIO_s_mem(void)
{
return (&mem_method);
return &mem_method;
}
BIO *
BIO_new_mem_buf(const void *buf, int len)
BIO_new_mem_buf(const void *buf, int buf_len)
{
BIO *ret;
BUF_MEM *b;
size_t sz;
struct bio_mem *bm;
BIO *bio;
if (!buf) {
if (buf == NULL) {
BIOerror(BIO_R_NULL_PARAMETER);
return NULL;
}
sz = (len < 0) ? strlen(buf) : (size_t)len;
if (!(ret = BIO_new(BIO_s_mem())))
if (buf_len == -1)
buf_len = strlen(buf);
if (buf_len < 0) {
BIOerror(BIO_R_INVALID_ARGUMENT);
return NULL;
b = (BUF_MEM *)ret->ptr;
b->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */
b->length = sz;
b->max = sz;
ret->flags |= BIO_FLAGS_MEM_RDONLY;
/* Since this is static data retrying wont help */
ret->num = 0;
return ret;
}
if ((bio = BIO_new(BIO_s_mem())) == NULL)
return NULL;
bm = bio->ptr;
bm->buf->data = (void *)buf; /* Trust in the BIO_FLAGS_MEM_RDONLY flag. */
bm->buf->length = buf_len;
bm->buf->max = buf_len;
bio->flags |= BIO_FLAGS_MEM_RDONLY;
/* Since this is static data retrying will not help. */
bio->num = 0;
return bio;
}
static int
mem_new(BIO *bi)
mem_new(BIO *bio)
{
BUF_MEM *b;
struct bio_mem *bm;
if ((b = BUF_MEM_new()) == NULL)
return (0);
bi->shutdown = 1;
bi->init = 1;
bi->num = -1;
bi->ptr = (char *)b;
return (1);
if ((bm = calloc(1, sizeof(*bm))) == NULL)
return 0;
if ((bm->buf = BUF_MEM_new()) == NULL) {
free(bm);
return 0;
}
bio->shutdown = 1;
bio->init = 1;
bio->num = -1;
bio->ptr = bm;
return 1;
}
static int
mem_free(BIO *a)
mem_free(BIO *bio)
{
if (a == NULL)
return (0);
if (a->shutdown) {
if ((a->init) && (a->ptr != NULL)) {
BUF_MEM *b;
b = (BUF_MEM *)a->ptr;
if (a->flags & BIO_FLAGS_MEM_RDONLY)
b->data = NULL;
BUF_MEM_free(b);
a->ptr = NULL;
struct bio_mem *bm;
if (bio == NULL)
return 0;
if (!bio->init || bio->ptr == NULL)
return 1;
bm = bio->ptr;
if (bio->shutdown) {
if (bio->flags & BIO_FLAGS_MEM_RDONLY)
bm->buf->data = NULL;
BUF_MEM_free(bm->buf);
}
}
return (1);
free(bm);
bio->ptr = NULL;
return 1;
}
static int
mem_read(BIO *b, char *out, int outl)
mem_read(BIO *bio, char *out, int out_len)
{
int ret = -1;
BUF_MEM *bm;
struct bio_mem *bm = bio->ptr;
bm = (BUF_MEM *)b->ptr;
BIO_clear_retry_flags(b);
ret = (outl >=0 && (size_t)outl > bm->length) ? (int)bm->length : outl;
if ((out != NULL) && (ret > 0)) {
memcpy(out, bm->data, ret);
bm->length -= ret;
if (b->flags & BIO_FLAGS_MEM_RDONLY)
bm->data += ret;
else {
memmove(&(bm->data[0]), &(bm->data[ret]), bm->length);
BIO_clear_retry_flags(bio);
if (out == NULL || out_len <= 0)
return 0;
if ((size_t)out_len > bio_mem_pending(bm))
out_len = bio_mem_pending(bm);
if (out_len == 0) {
if (bio->num != 0)
BIO_set_retry_read(bio);
return bio->num;
}
} else if (bm->length == 0) {
ret = b->num;
if (ret != 0)
BIO_set_retry_read(b);
}
return (ret);
memcpy(out, bio_mem_read_ptr(bm), out_len);
bm->read_offset += out_len;
return out_len;
}
static int
mem_write(BIO *b, const char *in, int inl)
mem_write(BIO *bio, const char *in, int in_len)
{
int ret = -1;
int blen;
BUF_MEM *bm;
struct bio_mem *bm = bio->ptr;
size_t buf_len;
bm = (BUF_MEM *)b->ptr;
if (in == NULL) {
BIOerror(BIO_R_NULL_PARAMETER);
goto end;
}
BIO_clear_retry_flags(bio);
if (b->flags & BIO_FLAGS_MEM_RDONLY) {
if (in == NULL || in_len <= 0)
return 0;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
BIOerror(BIO_R_WRITE_TO_READ_ONLY_BIO);
goto end;
return -1;
}
BIO_clear_retry_flags(b);
blen = bm->length;
if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl))
goto end;
memcpy(&(bm->data[blen]), in, inl);
ret = inl;
end:
return (ret);
if (bm->read_offset > 4096) {
memmove(bm->buf->data, bio_mem_read_ptr(bm),
bio_mem_pending(bm));
bm->buf->length = bio_mem_pending(bm);
bm->read_offset = 0;
}
/*
* Check for overflow and ensure we do not exceed an int, otherwise we
* cannot tell if BUF_MEM_grow_clean() succeeded.
*/
buf_len = bm->buf->length + in_len;
if (buf_len < bm->buf->length || buf_len > INT_MAX)
return -1;
if (BUF_MEM_grow_clean(bm->buf, buf_len) != buf_len)
return -1;
memcpy(&bm->buf->data[buf_len - in_len], in, in_len);
return in_len;
}
static long
mem_ctrl(BIO *b, int cmd, long num, void *ptr)
mem_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
struct bio_mem *bm = bio->ptr;
void **pptr;
long ret = 1;
char **pptr;
BUF_MEM *bm = (BUF_MEM *)b->ptr;
switch (cmd) {
case BIO_CTRL_RESET:
if (bm->data != NULL) {
/* For read only case reset to the start again */
if (b->flags & BIO_FLAGS_MEM_RDONLY) {
bm->data -= bm->max - bm->length;
bm->length = bm->max;
} else {
memset(bm->data, 0, bm->max);
bm->length = 0;
if (bm->buf->data != NULL) {
if (!(bio->flags & BIO_FLAGS_MEM_RDONLY)) {
memset(bm->buf->data, 0, bm->buf->max);
bm->buf->length = 0;
}
bm->read_offset = 0;
}
break;
case BIO_CTRL_EOF:
ret = (long)(bm->length == 0);
ret = (long)(bio_mem_pending(bm) == 0);
break;
case BIO_C_SET_BUF_MEM_EOF_RETURN:
b->num = (int)num;
bio->num = (int)num;
break;
case BIO_CTRL_INFO:
ret = (long)bm->length;
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)&(bm->data[0]);
pptr = (void **)ptr;
*pptr = bio_mem_read_ptr(bm);
}
ret = (long)bio_mem_pending(bm);
break;
case BIO_C_SET_BUF_MEM:
mem_free(b);
b->shutdown = (int)num;
b->ptr = ptr;
BUF_MEM_free(bm->buf);
bio->shutdown = (int)num;
bm->buf = ptr;
bm->read_offset = 0;
break;
case BIO_C_GET_BUF_MEM_PTR:
if (ptr != NULL) {
pptr = (char **)ptr;
*pptr = (char *)bm;
pptr = (void **)ptr;
*pptr = bm->buf;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = (long)b->shutdown;
ret = (long)bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
bio->shutdown = (int)num;
break;
case BIO_CTRL_WPENDING:
ret = 0L;
break;
case BIO_CTRL_PENDING:
ret = (long)bm->length;
ret = (long)bio_mem_pending(bm);
break;
case BIO_CTRL_DUP:
case BIO_CTRL_FLUSH:
@ -270,27 +319,29 @@ mem_ctrl(BIO *b, int cmd, long num, void *ptr)
ret = 0;
break;
}
return (ret);
return ret;
}
static int
mem_gets(BIO *bp, char *buf, int size)
mem_gets(BIO *bio, char *out, int out_len)
{
int i, j;
int ret = -1;
struct bio_mem *bm = bio->ptr;
int i, out_max;
char *p;
BUF_MEM *bm = (BUF_MEM *)bp->ptr;
int ret = -1;
BIO_clear_retry_flags(bp);
j = bm->length;
if ((size - 1) < j)
j = size - 1;
if (j <= 0) {
*buf = '\0';
BIO_clear_retry_flags(bio);
out_max = bio_mem_pending(bm);
if (out_len - 1 < out_max)
out_max = out_len - 1;
if (out_max <= 0) {
*out = '\0';
return 0;
}
p = bm->data;
for (i = 0; i < j; i++) {
p = bio_mem_read_ptr(bm);
for (i = 0; i < out_max; i++) {
if (p[i] == '\n') {
i++;
break;
@ -298,24 +349,17 @@ mem_gets(BIO *bp, char *buf, int size)
}
/*
* i is now the max num of bytes to copy, either j or up to
* and including the first newline
* i is now the max num of bytes to copy, either out_max or up to and
* including the first newline
*/
if ((ret = mem_read(bio, out, i)) > 0)
out[ret] = '\0';
i = mem_read(bp, buf, i);
if (i > 0)
buf[i] = '\0';
ret = i;
return (ret);
return ret;
}
static int
mem_puts(BIO *bp, const char *str)
mem_puts(BIO *bio, const char *in)
{
int n, ret;
n = strlen(str);
ret = mem_write(bp, str, n);
/* memory semantics is that it will always work */
return (ret);
return mem_write(bio, in, strlen(in));
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_null.c,v 1.11 2018/05/01 13:29:10 tb Exp $ */
/* $OpenBSD: bss_null.c,v 1.12 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -62,6 +62,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
static int null_write(BIO *h, const char *buf, int num);
static int null_read(BIO *h, char *buf, int size);
static int null_puts(BIO *h, const char *str);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bss_sock.c,v 1.24 2018/05/01 13:29:10 tb Exp $ */
/* $OpenBSD: bss_sock.c,v 1.25 2022/01/07 09:02:17 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -65,6 +65,8 @@
#include <openssl/bio.h>
#include "bio_local.h"
static int sock_write(BIO *h, const char *buf, int num);
static int sock_read(BIO *h, char *buf, int size);
static int sock_puts(BIO *h, const char *str);

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_exp2.c,v 1.12 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bn_exp2.c,v 1.13 2022/02/07 19:49:56 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -136,7 +136,7 @@ BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
bn_check_top(p2);
bn_check_top(m);
if (!(m->d[0] & 1)) {
if (!BN_is_odd(m)) {
BNerror(BN_R_CALLED_WITH_EVEN_MODULUS);
return (0);
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_gcd.c,v 1.15 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bn_gcd.c,v 1.16 2021/12/26 15:16:50 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -576,6 +576,9 @@ BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
bn_check_top(a);
bn_check_top(n);
BN_init(&local_A);
BN_init(&local_B);
BN_CTX_start(ctx);
if ((A = BN_CTX_get(ctx)) == NULL)
goto err;
@ -608,10 +611,12 @@ BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
A->neg = 0;
if (B->neg || (BN_ucmp(B, A) >= 0)) {
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
/*
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
* BN_div_no_branch will be called eventually.
*/
pB = &local_B;
/* BN_init() done at the top of the function. */
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
if (!BN_nnmod(B, pB, A, ctx))
goto err;
@ -633,10 +638,12 @@ BN_mod_inverse_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
* sign*Y*a == A (mod |n|)
*/
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
/*
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
* BN_div_no_branch will be called eventually.
*/
pA = &local_A;
/* BN_init() done at the top of the function. */
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
/* (D, M) := (A/B, A%B) ... */
@ -740,6 +747,9 @@ BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
goto err;
R = in;
BN_init(&local_A);
BN_init(&local_B);
bn_check_top(a);
bn_check_top(n);
@ -768,10 +778,12 @@ BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
A->neg = 0;
if (B->neg || (BN_ucmp(B, A) >= 0)) {
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
/*
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
* BN_div_no_branch will be called eventually.
*/
pB = &local_B;
/* BN_init() done at the top of the function. */
BN_with_flags(pB, B, BN_FLG_CONSTTIME);
if (!BN_nnmod(B, pB, A, ctx))
goto err;
@ -793,10 +805,12 @@ BN_gcd_no_branch(BIGNUM *in, const BIGNUM *a, const BIGNUM *n,
* sign*Y*a == A (mod |n|)
*/
/* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
/*
* Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked,
* BN_div_no_branch will be called eventually.
*/
pA = &local_A;
/* BN_init() done at the top of the function. */
BN_with_flags(pA, A, BN_FLG_CONSTTIME);
/* (D, M) := (A/B, A%B) ... */

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_lcl.h,v 1.30 2018/11/05 23:52:47 tb Exp $ */
/* $OpenBSD: bn_lcl.h,v 1.31 2022/01/14 08:01:47 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -118,6 +118,50 @@
__BEGIN_HIDDEN_DECLS
struct bignum_st {
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks. */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
int ri; /* number of bits in R */
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
* (Ni is only stored for bignum algorithm) */
BN_ULONG n0[2];/* least significant word(s) of Ni;
(type changed with 0.9.9, was "BN_ULONG n0;" before) */
int flags;
};
/* Used for reciprocal division/mod functions
* It cannot be shared between threads
*/
struct bn_recp_ctx_st {
BIGNUM N; /* the divisor */
BIGNUM Nr; /* the reciprocal */
int num_bits;
int shift;
int flags;
};
/* Used for slow "generation" functions. */
struct bn_gencb_st {
unsigned int ver; /* To handle binary (in)compatibility */
void *arg; /* callback-specific data */
union {
/* if(ver==1) - handles old style callbacks */
void (*cb_1)(int, int, void *);
/* if(ver==2) - new callback style */
int (*cb_2)(int, int, BN_GENCB *);
} cb;
};
/*
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
*

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_lib.c,v 1.47 2019/06/17 17:11:48 tb Exp $ */
/* $OpenBSD: bn_lib.c,v 1.53 2021/12/27 15:12:22 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -92,6 +92,63 @@ static int bn_limit_num_high = 8; /* (1<<bn_limit_bits_high) */
static int bn_limit_bits_mont = 0;
static int bn_limit_num_mont = 8; /* (1<<bn_limit_bits_mont) */
BIGNUM *
BN_new(void)
{
BIGNUM *ret;
if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
BNerror(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->flags = BN_FLG_MALLOCED;
ret->top = 0;
ret->neg = 0;
ret->dmax = 0;
ret->d = NULL;
bn_check_top(ret);
return (ret);
}
void
BN_init(BIGNUM *a)
{
memset(a, 0, sizeof(BIGNUM));
bn_check_top(a);
}
void
BN_clear(BIGNUM *a)
{
bn_check_top(a);
if (a->d != NULL)
explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
a->top = 0;
a->neg = 0;
}
void
BN_clear_free(BIGNUM *a)
{
int i;
if (a == NULL)
return;
bn_check_top(a);
if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
freezero(a->d, a->dmax * sizeof(a->d[0]));
i = BN_get_flags(a, BN_FLG_MALLOCED);
explicit_bzero(a, sizeof(BIGNUM));
if (i)
free(a);
}
void
BN_free(BIGNUM *a)
{
BN_clear_free(a);
}
void
BN_set_params(int mult, int high, int low, int mont)
{
@ -137,6 +194,30 @@ BN_get_params(int which)
}
#endif
void
BN_set_flags(BIGNUM *b, int n)
{
b->flags |= n;
}
int
BN_get_flags(const BIGNUM *b, int n)
{
return b->flags & n;
}
void
BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
{
int dest_flags;
dest_flags = (dest->flags & BN_FLG_MALLOCED) |
(b->flags & ~BN_FLG_MALLOCED) | BN_FLG_STATIC_DATA | flags;
*dest = *b;
dest->flags = dest_flags;
}
const BIGNUM *
BN_value_one(void)
{
@ -182,53 +263,6 @@ BN_num_bits(const BIGNUM *a)
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
void
BN_clear_free(BIGNUM *a)
{
int i;
if (a == NULL)
return;
bn_check_top(a);
if (a->d != NULL && !(BN_get_flags(a, BN_FLG_STATIC_DATA)))
freezero(a->d, a->dmax * sizeof(a->d[0]));
i = BN_get_flags(a, BN_FLG_MALLOCED);
explicit_bzero(a, sizeof(BIGNUM));
if (i)
free(a);
}
void
BN_free(BIGNUM *a)
{
BN_clear_free(a);
}
void
BN_init(BIGNUM *a)
{
memset(a, 0, sizeof(BIGNUM));
bn_check_top(a);
}
BIGNUM *
BN_new(void)
{
BIGNUM *ret;
if ((ret = malloc(sizeof(BIGNUM))) == NULL) {
BNerror(ERR_R_MALLOC_FAILURE);
return (NULL);
}
ret->flags = BN_FLG_MALLOCED;
ret->top = 0;
ret->neg = 0;
ret->dmax = 0;
ret->d = NULL;
bn_check_top(ret);
return (ret);
}
/* This is used both by bn_expand2() and bn_dup_expand() */
/* The caller MUST check that words > b->dmax before calling this */
static BN_ULONG *
@ -494,16 +528,6 @@ BN_swap(BIGNUM *a, BIGNUM *b)
bn_check_top(b);
}
void
BN_clear(BIGNUM *a)
{
bn_check_top(a);
if (a->d != NULL)
explicit_bzero(a->d, a->dmax * sizeof(a->d[0]));
a->top = 0;
a->neg = 0;
}
BN_ULONG
BN_get_word(const BIGNUM *a)
{
@ -583,20 +607,143 @@ BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
return (ret);
}
typedef enum {
big,
little,
} endianness_t;
/* ignore negative */
static int
bn2binpad(const BIGNUM *a, unsigned char *to, int tolen, endianness_t endianness)
{
int n;
size_t i, lasti, j, atop, mask;
BN_ULONG l;
/*
* In case |a| is fixed-top, BN_num_bytes can return bogus length,
* but it's assumed that fixed-top inputs ought to be "nominated"
* even for padded output, so it works out...
*/
n = BN_num_bytes(a);
if (tolen == -1)
tolen = n;
else if (tolen < n) { /* uncommon/unlike case */
BIGNUM temp = *a;
bn_correct_top(&temp);
n = BN_num_bytes(&temp);
if (tolen < n)
return -1;
}
/* Swipe through whole available data and don't give away padded zero. */
atop = a->dmax * BN_BYTES;
if (atop == 0) {
explicit_bzero(to, tolen);
return tolen;
}
lasti = atop - 1;
atop = a->top * BN_BYTES;
if (endianness == big)
to += tolen; /* start from the end of the buffer */
for (i = 0, j = 0; j < (size_t)tolen; j++) {
unsigned char val;
l = a->d[i / BN_BYTES];
mask = 0 - ((j - atop) >> (8 * sizeof(i) - 1));
val = (unsigned char)(l >> (8 * (i % BN_BYTES)) & mask);
if (endianness == big)
*--to = val;
else
*to++ = val;
i += (i - lasti) >> (8 * sizeof(i) - 1); /* stay on last limb */
}
return tolen;
}
int
BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen)
{
if (tolen < 0)
return -1;
return bn2binpad(a, to, tolen, big);
}
int
BN_bn2bin(const BIGNUM *a, unsigned char *to)
{
int n, i;
BN_ULONG l;
return bn2binpad(a, to, -1, big);
}
bn_check_top(a);
n = i=BN_num_bytes(a);
while (i--) {
l = a->d[i / BN_BYTES];
*(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff;
BIGNUM *
BN_lebin2bn(const unsigned char *s, int len, BIGNUM *ret)
{
unsigned int i, m, n;
BN_ULONG l;
BIGNUM *bn = NULL;
if (ret == NULL)
ret = bn = BN_new();
if (ret == NULL)
return NULL;
bn_check_top(ret);
s += len;
/* Skip trailing zeroes. */
for (; len > 0 && s[-1] == 0; s--, len--)
continue;
n = len;
if (n == 0) {
ret->top = 0;
return ret;
}
return (n);
i = ((n - 1) / BN_BYTES) + 1;
m = (n - 1) % BN_BYTES;
if (bn_wexpand(ret, (int)i) == NULL) {
BN_free(bn);
return NULL;
}
ret->top = i;
ret->neg = 0;
l = 0;
while (n-- > 0) {
s--;
l = (l << 8L) | *s;
if (m-- == 0) {
ret->d[--i] = l;
l = 0;
m = BN_BYTES - 1;
}
}
/*
* need to call this due to clear byte at top if avoiding having the
* top bit set (-ve number)
*/
bn_correct_top(ret);
return ret;
}
int
BN_bn2lebinpad(const BIGNUM *a, unsigned char *to, int tolen)
{
if (tolen < 0)
return -1;
return bn2binpad(a, to, tolen, little);
}
int
@ -914,6 +1061,50 @@ BN_swap_ct(BN_ULONG condition, BIGNUM *a, BIGNUM *b, size_t nwords)
return 1;
}
void
BN_zero_ex(BIGNUM *a)
{
a->neg = 0;
a->top = 0;
/* XXX: a->flags &= ~BN_FIXED_TOP */
}
int
BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
{
return (a->top == 1 && a->d[0] == w) || (w == 0 && a->top == 0);
}
int
BN_is_zero(const BIGNUM *a)
{
return a->top == 0;
}
int
BN_is_one(const BIGNUM *a)
{
return BN_abs_is_word(a, 1) && !a->neg;
}
int
BN_is_word(const BIGNUM *a, const BN_ULONG w)
{
return BN_abs_is_word(a, w) && (w == 0 || !a->neg);
}
int
BN_is_odd(const BIGNUM *a)
{
return a->top > 0 && (a->d[0] & 1);
}
int
BN_is_negative(const BIGNUM *a)
{
return a->neg != 0;
}
BN_GENCB *
BN_GENCB_new(void)
{
@ -933,6 +1124,24 @@ BN_GENCB_free(BN_GENCB *cb)
free(cb);
}
/* Populate a BN_GENCB structure with an "old"-style callback */
void
BN_GENCB_set_old(BN_GENCB *gencb, void (*cb)(int, int, void *), void *cb_arg)
{
gencb->ver = 1;
gencb->cb.cb_1 = cb;
gencb->arg = cb_arg;
}
/* Populate a BN_GENCB structure with a "new"-style callback */
void
BN_GENCB_set(BN_GENCB *gencb, int (*cb)(int, int, BN_GENCB *), void *cb_arg)
{
gencb->ver = 2;
gencb->cb.cb_2 = cb;
gencb->arg = cb_arg;
}
void *
BN_GENCB_get_arg(BN_GENCB *cb)
{

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_mont.c,v 1.26 2017/01/21 11:00:46 beck Exp $ */
/* $OpenBSD: bn_mont.c,v 1.28 2022/02/07 19:44:23 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -175,6 +175,12 @@ err:
return (ret);
}
int
BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont, BN_CTX *ctx)
{
return BN_mod_mul_montgomery(r, a, &mont->RR, mont, ctx);
}
#ifdef MONT_WORD
static int
BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
@ -363,6 +369,9 @@ BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
int ret = 0;
BIGNUM *Ri, *R;
if (BN_is_zero(mod))
return 0;
BN_CTX_start(ctx);
if ((Ri = BN_CTX_get(ctx)) == NULL)
goto err;

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_nist.c,v 1.18 2016/07/18 01:04:52 bcook Exp $ */
/* $OpenBSD: bn_nist.c,v 1.19 2021/11/09 18:40:20 bcook Exp $ */
/*
* Written by Nils Larsch for the OpenSSL project
*/
@ -56,8 +56,7 @@
*
*/
#include <machine/endian.h>
#include <endian.h>
#include <stdint.h>
#include <string.h>

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_print.c,v 1.31 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bn_print.c,v 1.33 2022/01/20 10:53:33 inoguchi Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@ -216,7 +216,7 @@ BN_hex2bn(BIGNUM **bn, const char *a)
if ((ret = BN_new()) == NULL)
return (0);
} else {
ret= *bn;
ret = *bn;
BN_zero(ret);
}
@ -228,7 +228,7 @@ BN_hex2bn(BIGNUM **bn, const char *a)
m = 0;
h = 0;
while (j > 0) {
m = ((BN_BYTES*2) <= j) ? (BN_BYTES * 2) : j;
m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
l = 0;
for (;;) {
c = a[j - m];
@ -310,8 +310,10 @@ BN_dec2bn(BIGNUM **bn, const char *a)
l += *a - '0';
a++;
if (++j == BN_DEC_NUM) {
BN_mul_word(ret, BN_DEC_CONV);
BN_add_word(ret, l);
if (!BN_mul_word(ret, BN_DEC_CONV))
goto err;
if (!BN_add_word(ret, l))
goto err;
l = 0;
j = 0;
}

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_rand.c,v 1.24 2020/09/12 17:16:36 tb Exp $ */
/* $OpenBSD: bn_rand.c,v 1.25 2021/08/31 11:19:19 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_sqrt.c,v 1.9 2017/01/29 17:49:22 beck Exp $ */
/* $OpenBSD: bn_sqrt.c,v 1.10 2022/03/15 15:52:39 tb Exp $ */
/* Written by Lenka Fibikova <fibikova@exp-math.uni-essen.de>
* and Bodo Moeller for the OpenSSL project. */
/* ====================================================================
@ -351,21 +351,22 @@ BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
goto vrfy;
}
/* find smallest i such that b^(2^i) = 1 */
i = 1;
/* Find the smallest i with 0 < i < e such that b^(2^i) = 1. */
for (i = 1; i < e; i++) {
if (i == 1) {
if (!BN_mod_sqr(t, b, p, ctx))
goto end;
while (!BN_is_one(t)) {
i++;
if (i == e) {
} else {
if (!BN_mod_sqr(t, t, p, ctx))
goto end;
}
if (BN_is_one(t))
break;
}
if (i >= e) {
BNerror(BN_R_NOT_A_SQUARE);
goto end;
}
if (!BN_mod_mul(t, t, t, p, ctx))
goto end;
}
/* t := y^2^(e - i - 1) */
if (!BN_copy(t, y))

View file

@ -1,4 +1,4 @@
/* $OpenBSD: bn_x931p.c,v 1.11 2019/01/20 01:56:59 tb Exp $ */
/* $OpenBSD: bn_x931p.c,v 1.13 2022/01/20 10:56:22 inoguchi Exp $ */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2005.
*/
@ -139,13 +139,13 @@ BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
/* First set p to value of Rp */
if (!BN_mod_inverse_ct(p, p2, p1, ctx))
if (BN_mod_inverse_ct(p, p2, p1, ctx) == NULL)
goto err;
if (!BN_mul(p, p, p2, ctx))
goto err;
if (!BN_mod_inverse_ct(t, p1, p2, ctx))
if (BN_mod_inverse_ct(t, p1, p2, ctx) == NULL)
goto err;
if (!BN_mul(t, t, p1, ctx))
@ -154,7 +154,7 @@ BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, const BIGNUM *Xp,
if (!BN_sub(p, p, t))
goto err;
if (p->neg && !BN_add(p, p, p1p2))
if (BN_is_negative(p) && !BN_add(p, p, p1p2))
goto err;
/* p now equals Rp */
@ -237,7 +237,8 @@ BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx)
if (!BN_rand(Xq, nbits, 1, 0))
goto err;
/* Check that |Xp - Xq| > 2^(nbits - 100) */
BN_sub(t, Xp, Xq);
if (!BN_sub(t, Xp, Xq))
goto err;
if (BN_num_bits(t) > (nbits - 100))
break;
}

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