From 0a833d0339fe5bb4c26c30430d74f83d7f2b6519 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 22 Aug 2018 16:50:15 +0200 Subject: crypto: A user's guide chapter on algorithm details Such as keylengths, blocksizes and IV lengths are hard to find otherwise Conflicts: lib/crypto/doc/src/crypto.xml --- lib/crypto/doc/src/Makefile | 2 +- lib/crypto/doc/src/algorithm_details.xml | 290 +++++++++++++++++++++++++++++++ lib/crypto/doc/src/usersguide.xml | 1 + 3 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 lib/crypto/doc/src/algorithm_details.xml diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index 2148062e78..3203324954 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -39,7 +39,7 @@ XML_REF3_FILES = crypto.xml XML_REF6_FILES = crypto_app.xml XML_PART_FILES = usersguide.xml -XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml +XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml engine_keys.xml algorithm_details.xml BOOK_FILES = book.xml diff --git a/lib/crypto/doc/src/algorithm_details.xml b/lib/crypto/doc/src/algorithm_details.xml new file mode 100644 index 0000000000..088f5e8e97 --- /dev/null +++ b/lib/crypto/doc/src/algorithm_details.xml @@ -0,0 +1,290 @@ + + + + +
+ + 20142017 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + + + Algorithm Details + Hans Nilsson + + 2018-08-22 + A + algorithm_details.xml +
+

+ This chapter describes details of algorithms in the crypto application. +

+

The tables only documents the supported cryptos and key lengths. The user should not draw any conclusion + on security from the supplied tables. +

+ +
+ Ciphers +
+ Block Ciphers +

To be used in + block_encrypt/3, + block_encrypt/4, + block_decrypt/3 and + block_decrypt/4. +

+

Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
Block size
[bytes]
+ aes_cbc 16, 24, 321616 + aes_cbc128161616 + aes_cbc256321616 + + aes_cfb8 16, 24, 3216any + + aes_ecb16, 24, 32 16 + + aes_ige256163216 + blowfish_cbc 4-56 8 8 + blowfish_cfb64 1- 8 any + blowfish_ecb1- 8 + blowfish_ofb641-8any + + des3_cbc
(=DES EDE3 CBC)
[8,8,8]88
+ des3_cfb
(=DES EDE3 CFB)
[8,8,8]8any
+ + des_cbc88 8 + des_cfb88any + des_ecb8 8 + des_ede3
(=DES EDE3 CBC)
[8,8,8]88
+ rc2_cbc1-88 + Block cipher key lengths +
+
+ +
+ AEAD Ciphers +

To be used in block_encrypt/4 and + block_decrypt/4. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
AAD length
[bytes]
Block size
[bytes]
Supported with
OpenSSL versions
+ aes_gcm 16 16 0-16 any1.0.1 - + chacha20_poly130532 1-16 any any1.1.0 - + AEAD cipher key lengths +
+
+ +
+ Stream Ciphers +

To be used in stream_init/2 and + stream_init/3. +

+

To dynamically check availability, check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value of + crypto:supports(). +

+ + Cipher and ModeKey length
[bytes]
IV length
[bytes]
Supported with
OpenSSL versions
+ aes_ctr16, 24, 32161.0.1 - + rc41- all + Stream cipher key lengths +
+
+
+ +
+ Message Authentication Codes (MACs) + +
+ CMAC +

To be used in cmac/3 and + cmac/4. +

+

CMAC with the following ciphers are available with OpenSSL 1.0.1 or later if not disabled by configuration. +

+ +

To dynamically check availability, check that the name cmac is present in the + list with the macs tag in the return value of + crypto:supports(). + Also check that the name in the Cipher and Mode column is present in the + list with the cipher tag in the return value. +

+ + Cipher and ModeKey length
[bytes]
Max Mac Length
[bytes]
+ aes_cbc 16, 24, 3216 + aes_cbc1281616 + aes_cbc2563216 + + aes_cfb8 161 + + blowfish_cbc 4-56 8 + blowfish_cfb64 1- 1 + blowfish_ecb1- 8 + blowfish_ofb641- 1 + + des3_cbc
(=DES EDE3 CBC)
[8,8,8]8
+ des3_cfb
(=DES EDE3 CFB)
[8,8,8]1
+ + des_cbc88 + + des_cfb81 + des_ecb81 + rc2_cbc1-8 + CMAC cipher key lengths +
+
+ +
+ HMAC +

Available in all OpenSSL compatible with Erlang CRYPTO if not disabled by configuration. +

+

To dynamically check availability, check that the name hmac is present in the + list with the macs tag in the return value of + crypto:supports(). +

+
+ +
+ POLY1305 +

POLY1305 is available with OpenSSL 1.1.1 or later if not disabled by configuration. +

+

To dynamically check availability, check that the name poly1305 is present in the + list with the macs tag in the return value of + crypto:supports(). +

+
+ +
+ +
+ Hash + +

To dynamically check availability, check that the wanted name in the Names column is present in the + list with the hashs tag in the return value of + crypto:supports(). +

+ + + + Type + Names + Supported with
OpenSSL versions
+
+ SHA1shaall + SHA2sha224, sha256, sha384, sha512all + SHA3sha3_224, sha3_256, sha3_384, sha3_5121.1.1 - + MD4md4all + MD5md5all + RIPEMDripemd160all + +
+
+ +
+ Public Key Cryptography + +
+ RSA +

RSA is available with all OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration. + To dynamically check availability, check that the atom rsa is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+ + + Option sign/verify encrypt/decrypt Supported with
OpenSSL versions
+ {rsa_mgf1_md,atom()} x x 1.0.1 + {rsa_oaep_label, binary()} x + {rsa_oaep_md, atom()} x + {rsa_padding,rsa_pkcs1_pss_padding} x 1.0.0 + {rsa_pss_saltlen, -2..} x 1.0.0 + {rsa_padding,rsa_no_padding} x x + {rsa_padding,rsa_pkcs1_padding} x x + {rsa_padding,rsa_sslv23_padding} x + {rsa_padding,rsa_x931_padding} x + +
+
+ +
+ DSS +

DSS is available with OpenSSL versions compatible with Erlang CRYPTO if not disabled by configuration. + To dynamically check availability, check that the atom dss is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+
+ +
+ ECDSA +

ECDSA is available with OpenSSL 0.9.8o or later if not disabled by configuration. + To dynamically check availability, check that the atom ecdsa is present in the + list with the public_keys tag in the return value of + crypto:supports(). + If the atom ec_gf2m characteristic two field curves are available. +

+

The actual supported named curves could be checked by examining the list with the + curves tag in the return value of + crypto:supports(). +

+
+ +
+ Diffie-Hellman +

Diffie-Hellman computations are available with OpenSSL versions compatible with Erlang CRYPTO + if not disabled by configuration. + To dynamically check availability, check that the atom dh is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+
+ +
+ Elliptic Curve Diffie-Hellman +

Elliptic Curve Diffie-Hellman is available with OpenSSL 0.9.8o or later if not disabled by configuration. + To dynamically check availability, check that the atom ecdh is present in the + list with the public_keys tag in the return value of + crypto:supports(). +

+ +

The Edward curves x25519 and x448 are supported with OpenSSL 1.1.1 or later + if not disabled by configuration. +

+ +

The actual supported named curves could be checked by examining the list with the + curves tag in the return value of + crypto:supports(). +

+
+ +
+ + +
+ + + + + diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml index 0124121433..2dfc966609 100644 --- a/lib/crypto/doc/src/usersguide.xml +++ b/lib/crypto/doc/src/usersguide.xml @@ -50,4 +50,5 @@ + -- cgit v1.2.3 From fa60c386364e4a1852151a56ec6942e394545983 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:04:42 +0200 Subject: crypto: Setup for doc generation --- lib/crypto/doc/specs/.gitignore | 1 + lib/crypto/doc/src/Makefile | 7 +++++++ lib/crypto/doc/src/specs.xml | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 lib/crypto/doc/specs/.gitignore create mode 100644 lib/crypto/doc/src/specs.xml diff --git a/lib/crypto/doc/specs/.gitignore b/lib/crypto/doc/specs/.gitignore new file mode 100644 index 0000000000..322eebcb06 --- /dev/null +++ b/lib/crypto/doc/specs/.gitignore @@ -0,0 +1 @@ +specs_*.xml diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index 3203324954..cbcafb7375 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -62,11 +62,17 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf +SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) + +TOP_SPECS_FILE = specs.xml + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- XML_FLAGS += +#in ssh it looks like this: SPECS_FLAGS = -I../../../public_key/include -I../../../public_key/src -I../../.. + # ---------------------------------------------------- # Targets # ---------------------------------------------------- @@ -93,6 +99,7 @@ clean clean_docs clean_tex: rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f $(SPECS_FILES) rm -f errs core *~ # ---------------------------------------------------- diff --git a/lib/crypto/doc/src/specs.xml b/lib/crypto/doc/src/specs.xml new file mode 100644 index 0000000000..66c79a906b --- /dev/null +++ b/lib/crypto/doc/src/specs.xml @@ -0,0 +1,4 @@ + + + + -- cgit v1.2.3 From 35848c8ba5968b0d9aec3f7aaac6d31000e4da15 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:07:21 +0200 Subject: crypto: Rework -type and -spec Check code and documentation and write -type/-spec or adjust existing. Prepare for doc generation --- lib/crypto/src/crypto.erl | 976 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 739 insertions(+), 237 deletions(-) diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index 17351d10ea..a841f0f168 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -66,12 +66,31 @@ ensure_engine_unloaded/2 ]). +-export_type([ %% A minimum exported: only what public_key needs. + dh_private/0, + dh_public/0, + dss_digest_type/0, + ec_named_curve/0, + ecdsa_digest_type/0, + pk_encrypt_decrypt_opts/0, + pk_sign_verify_opts/0, + rsa_digest_type/0, + sha1/0, + sha2/0 + ]). + -export_type([engine_ref/0, key_id/0, password/0 ]). - +%%% Opaque types must be exported :( +-export_type([ + stream_state/0, + hmac_state/0, + hash_state/0 + ]). + %% Private. For tests. -export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2, get_test_engine/0]). @@ -83,16 +102,187 @@ %% Used by strong_rand_float/0 -define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53) -%%-type ecdsa_digest_type() :: 'md5' | 'sha' | 'sha256' | 'sha384' | 'sha512'. + +%%% ===== BEGIN NEW TYPING ==== + +%%% Basic +-type key_integer() :: integer() | binary(). % Always binary() when used as return value + +%%% Keys +-type rsa_public() :: [key_integer()] . % [E, N] +-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C] +-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} . + +-type dss_public() :: [key_integer()] . % [P, Q, G, Y] +-type dss_private() :: [key_integer()] . % [P, Q, G, X] + +-type ecdsa_public() :: key_integer() . +-type ecdsa_private() :: key_integer() . +-type ecdsa_params() :: ec_named_curve() | edwards_curve() | ec_explicit_curve() . + +-type srp_public() :: key_integer() . +-type srp_private() :: key_integer() . +-type srp_gen_params() :: {user,srp_user_gen_params()} | {host,srp_host_gen_params()}. +-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}. +-type srp_user_gen_params() :: list(binary() | atom() | list()) . +-type srp_host_gen_params() :: list(binary() | atom() | list()) . +-type srp_user_comp_params() :: list(binary() | atom()) . +-type srp_host_comp_params() :: list(binary() | atom()) . + +-type dh_public() :: key_integer() . +-type dh_private() :: key_integer() . +-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength] + +-type ecdh_public() :: key_integer() . +-type ecdh_private() :: key_integer() . +-type ecdh_params() :: ec_named_curve() | edwards_curve() | ec_explicit_curve() . + + +%%% Curves + +-type ec_explicit_curve() :: {Field :: ec_field(), + Curve :: ec_curve(), + BasePoint :: binary(), + Order :: binary(), + CoFactor :: none | % FIXME: Really? + binary() + } . + +-type ec_curve() :: {A :: binary(), + B :: binary(), + Seed :: none | binary() + } . + +-type ec_field() :: ec_prime_field() | ec_characteristic_two_field() . + +-type ec_prime_field() :: {prime_field, Prime :: integer()} . +-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} . + +-type ec_basis() :: {tpbasis, K :: non_neg_integer()} + | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} + | onbasis . + +-type ec_named_curve() :: brainpoolP160r1 + | brainpoolP160t1 + | brainpoolP192r1 + | brainpoolP192t1 + | brainpoolP224r1 + | brainpoolP224t1 + | brainpoolP256r1 + | brainpoolP256t1 + | brainpoolP320r1 + | brainpoolP320t1 + | brainpoolP384r1 + | brainpoolP384t1 + | brainpoolP512r1 + | brainpoolP512t1 + | c2pnb163v1 + | c2pnb163v2 + | c2pnb163v3 + | c2pnb176v1 + | c2pnb208w1 + | c2pnb272w1 + | c2pnb304w1 + | c2pnb368w1 + | c2tnb191v1 + | c2tnb191v2 + | c2tnb191v3 + | c2tnb239v1 + | c2tnb239v2 + | c2tnb239v3 + | c2tnb359v1 + | c2tnb431r1 + | ipsec3 + | ipsec4 + | prime192v1 + | prime192v2 + | prime192v3 + | prime239v1 + | prime239v2 + | prime239v3 + | prime256v1 + | secp112r1 + | secp112r2 + | secp128r1 + | secp128r2 + | secp160k1 + | secp160r1 + | secp160r2 + | secp192k1 + | secp192r1 + | secp224k1 + | secp224r1 + | secp256k1 + | secp256r1 + | secp384r1 + | secp521r1 + | sect113r1 + | sect113r2 + | sect131r1 + | sect131r2 + | sect163k1 + | sect163r1 + | sect163r2 + | sect193r1 + | sect193r2 + | sect233k1 + | sect233r1 + | sect239k1 + | sect283k1 + | sect283r1 + | sect409k1 + | sect409r1 + | sect571k1 + | sect571r1 + | wtls1 + | wtls10 + | wtls11 + | wtls12 + | wtls3 + | wtls4 + | wtls5 + | wtls6 + | wtls7 + | wtls8 + | wtls9 + . + +-type edwards_curve() :: x25519 + | x448 . + +%%% +-type block_cipher_with_iv() :: cbc_cipher() + | cfb_cipher() + | aes_cbc128 + | aes_cbc256 + | aes_ige256 + | blowfish_ofb64 + | des3_cbf % cfb misspelled + | des_ede3 + | rc2_cbc . + +-type cbc_cipher() :: des_cbc | des3_cbc | aes_cbc | blowfish_cbc . +-type aead_cipher() :: aes_gcm | chacha20_poly1305 . +-type cfb_cipher() :: aes_cfb128 | aes_cfb8 | blowfish_cfb64 | des3_cfb | des_cfb . + +-type block_cipher_without_iv() :: ecb_cipher() . +-type ecb_cipher() :: des_ecb | blowfish_ecb | aes_ecb . + +-type key() :: iodata(). +-type des3_key() :: [key()]. + +%%% +-type rsa_digest_type() :: sha1() | sha2() | md5 | ripemd160 . +-type dss_digest_type() :: sha1() | sha2() . +-type ecdsa_digest_type() :: sha1() | sha2() . + +-type sha1() :: sha . +-type sha2() :: sha224 | sha256 | sha384 | sha512 . +-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 . + +-type compatibility_only_hash() :: md5 | md4 . + -type crypto_integer() :: binary() | integer(). -%%-type ec_named_curve() :: atom(). -%%-type ec_point() :: crypto_integer(). -%%-type ec_basis() :: {tpbasis, K :: non_neg_integer()} | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} | onbasis. -%%-type ec_field() :: {prime_field, Prime :: integer()} | {characteristic_two_field, M :: integer(), Basis :: ec_basis()}. -%%-type ec_prime() :: {A :: crypto_integer(), B :: crypto_integer(), Seed :: binary() | none}. -%%-type ec_curve_spec() :: {Field :: ec_field(), Prime :: ec_prime(), Point :: crypto_integer(), Order :: integer(), CoFactor :: none | integer()}. -%%-type ec_curve() :: ec_named_curve() | ec_curve_spec(). -%%-type ec_key() :: {Curve :: ec_curve(), PrivKey :: binary() | undefined, PubKey :: ec_point() | undefined}. -compile(no_native). -on_load(on_load/0). @@ -108,14 +298,36 @@ nif_stub_error(Line) -> %% Crypto app version history: %% (no version): Driver implementation %% 2.0 : NIF implementation, requires OTP R14 + +%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined. +%% That causes the doc generation to stop... +-ifndef(CRYPTO_VSN). +-define(CRYPTO_VSN, "??"). +-endif. version() -> ?CRYPTO_VSN. +-spec start() -> ok | {error, Reason::term()}. start() -> application:start(crypto). +-spec stop() -> ok | {error, Reason::term()}. stop() -> application:stop(crypto). +-spec supports() -> [Support] + when Support :: {hashs, Hashs} + | {ciphers, Ciphers} + | {public_keys, PKs} + | {macs, Macs} + | {curves, Curves}, + Hashs :: [sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash()], + Ciphers :: [stream_cipher() + | block_cipher_with_iv() | block_cipher_without_iv() + | aead_cipher() + ], + PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m], + Macs :: [hmac | cmac | poly1305], + Curves :: [ec_named_curve() | edwards_curve()]. supports()-> {Hashs, PubKeys, Ciphers, Macs, Curves} = algorithms(), [{hashs, Hashs}, @@ -125,6 +337,9 @@ supports()-> {curves, Curves} ]. +-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(), + VerNum :: integer(), + VerStr :: binary() . info_lib() -> ?nif_stub. -spec info_fips() -> not_supported | not_enabled | enabled. @@ -135,85 +350,150 @@ info_fips() -> ?nif_stub. enable_fips_mode(_) -> ?nif_stub. --spec hash(_, iodata()) -> binary(). +%%%================================================================ +%%% +%%% Hashing +%%% +%%%================================================================ -hash(Hash, Data0) -> - Data = iolist_to_binary(Data0), - MaxBytes = max_bytes(), - hash(Hash, Data, erlang:byte_size(Data), MaxBytes). +-define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash() ). --spec hash_init('md5'|'md4'|'ripemd160'| - 'sha'|'sha224'|'sha256'|'sha384'|'sha512'| - 'sha3_224' | 'sha3_256' | 'sha3_384' | 'sha3_512') -> any(). +-spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM, + Data :: iodata(), + Digest :: binary(). +hash(Type, Data) -> + Data1 = iolist_to_binary(Data), + MaxBytes = max_bytes(), + hash(Type, Data1, erlang:byte_size(Data1), MaxBytes). -hash_init(Hash) -> - notsup_to_error(hash_init_nif(Hash)). +-opaque hash_state() :: reference(). --spec hash_update(_, iodata()) -> any(). +-spec hash_init(Type) -> State when Type :: ?HASH_HASH_ALGORITHM, + State :: hash_state(). +hash_init(Type) -> + notsup_to_error(hash_init_nif(Type)). -hash_update(State, Data0) -> - Data = iolist_to_binary(Data0), +-spec hash_update(State, Data) -> NewState when State :: hash_state(), + NewState :: hash_state(), + Data :: iodata() . +hash_update(Context, Data) -> + Data1 = iolist_to_binary(Data), MaxBytes = max_bytes(), - hash_update(State, Data, erlang:byte_size(Data), MaxBytes). + hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes). --spec hash_final(_) -> binary(). +-spec hash_final(State) -> Digest when State :: hash_state(), + Digest :: binary(). +hash_final(Context) -> + notsup_to_error(hash_final_nif(Context)). -hash_final(State) -> - notsup_to_error(hash_final_nif(State)). +%%%================================================================ +%%% +%%% MACs (Message Authentication Codes) +%%% +%%%================================================================ +%%%---- HMAC --spec hmac(_, iodata(), iodata()) -> binary(). --spec hmac(_, iodata(), iodata(), integer()) -> binary(). --spec hmac_init(atom(), iodata()) -> binary(). --spec hmac_update(binary(), iodata()) -> binary(). --spec hmac_final(binary()) -> binary(). --spec hmac_final_n(binary(), integer()) -> binary(). +-define(HMAC_HASH_ALGORITHM, sha1() | sha2() | sha3() | compatibility_only_hash()). -hmac(Type, Key, Data0) -> - Data = iolist_to_binary(Data0), - hmac(Type, Key, Data, undefined, erlang:byte_size(Data), max_bytes()). -hmac(Type, Key, Data0, MacSize) -> - Data = iolist_to_binary(Data0), - hmac(Type, Key, Data, MacSize, erlang:byte_size(Data), max_bytes()). +%%%---- hmac/3,4 + +-spec hmac(Type, Key, Data) -> + Mac when Type :: ?HMAC_HASH_ALGORITHM, + Key :: iodata(), + Data :: iodata(), + Mac :: binary() . +hmac(Type, Key, Data) -> + Data1 = iolist_to_binary(Data), + hmac(Type, Key, Data1, undefined, erlang:byte_size(Data1), max_bytes()). + +-spec hmac(Type, Key, Data, MacLength) -> + Mac when Type :: ?HMAC_HASH_ALGORITHM, + Key :: iodata(), + Data :: iodata(), + MacLength :: integer(), + Mac :: binary() . + +hmac(Type, Key, Data, MacLength) -> + Data1 = iolist_to_binary(Data), + hmac(Type, Key, Data1, MacLength, erlang:byte_size(Data1), max_bytes()). +%%%---- hmac_init, hamc_update, hmac_final + +-opaque hmac_state() :: binary(). + +-spec hmac_init(Type, Key) -> + State when Type :: ?HMAC_HASH_ALGORITHM, + Key :: iodata(), + State :: hmac_state() . hmac_init(Type, Key) -> notsup_to_error(hmac_init_nif(Type, Key)). +%%%---- hmac_update + +-spec hmac_update(State, Data) -> NewState when Data :: iodata(), + State :: hmac_state(), + NewState :: hmac_state(). hmac_update(State, Data0) -> Data = iolist_to_binary(Data0), hmac_update(State, Data, erlang:byte_size(Data), max_bytes()). +%%%---- hmac_final + +-spec hmac_final(State) -> Mac when State :: hmac_state(), + Mac :: binary(). hmac_final(Context) -> notsup_to_error(hmac_final_nif(Context)). + +-spec hmac_final_n(State, HashLen) -> Mac when State :: hmac_state(), + HashLen :: integer(), + Mac :: binary(). hmac_final_n(Context, HashLen) -> notsup_to_error(hmac_final_nif(Context, HashLen)). --spec cmac(_, iodata(), iodata()) -> binary(). --spec cmac(_, iodata(), iodata(), integer()) -> binary(). +%%%---- CMAC + +-define(CMAC_CIPHER_ALGORITHM, cbc_cipher() | cfb_cipher() | blowfish_cbc | des_ede3 | rc2_cbc ). +-spec cmac(Type, Key, Data) -> + Mac when Type :: ?CMAC_CIPHER_ALGORITHM, + Key :: iodata(), + Data :: iodata(), + Mac :: binary(). cmac(Type, Key, Data) -> notsup_to_error(cmac_nif(Type, Key, Data)). -cmac(Type, Key, Data, MacSize) -> - erlang:binary_part(cmac(Type, Key, Data), 0, MacSize). --spec poly1305(iodata(), iodata()) -> binary(). +-spec cmac(Type, Key, Data, MacLength) -> + Mac when Type :: ?CMAC_CIPHER_ALGORITHM, + Key :: iodata(), + Data :: iodata(), + MacLength :: integer(), + Mac :: binary(). +cmac(Type, Key, Data, MacLength) -> + erlang:binary_part(cmac(Type, Key, Data), 0, MacLength). + +%%%---- POLY1305 + +-spec poly1305(iodata(), iodata()) -> Mac when Mac :: binary(). poly1305(Key, Data) -> poly1305_nif(Key, Data). -%% Ecrypt/decrypt %%% +%%%================================================================ +%%% +%%% Encrypt/decrypt +%%% +%%%================================================================ + +%%%---- Block ciphers --spec block_encrypt(des_cbc | des_cfb | - des3_cbc | des3_cbf | des3_cfb | des_ede3 | - blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 | - aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 | - aes_cbc | - rc2_cbc, - Key::iodata(), Ivec::binary(), Data::iodata()) -> binary(); - (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata()}) -> {binary(), binary()}; - (aes_gcm, Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata(), TagLength::1..16}) -> {binary(), binary()}. +-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary(); + (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) -> + {binary(), binary()}; + (aes_gcm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) -> + {binary(), binary()}. -block_encrypt(Type, Key, Ivec, Data) when Type =:= des_cbc; +block_encrypt(Type, Key, Ivec, PlainText) when Type =:= des_cbc; Type =:= des_cfb; Type =:= blowfish_cbc; Type =:= blowfish_cfb64; @@ -224,34 +504,28 @@ block_encrypt(Type, Key, Ivec, Data) when Type =:= des_cbc; Type =:= aes_cbc256; Type =:= aes_cbc; Type =:= rc2_cbc -> - block_crypt_nif(Type, Key, Ivec, Data, true); -block_encrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc; + block_crypt_nif(Type, Key, Ivec, PlainText, true); +block_encrypt(Type, Key0, Ivec, PlainText) when Type =:= des3_cbc; Type =:= des_ede3 -> Key = check_des3_key(Key0), - block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, true); -block_encrypt(des3_cbf, Key0, Ivec, Data) -> + block_crypt_nif(des_ede3_cbc, Key, Ivec, PlainText, true); +block_encrypt(des3_cbf, Key0, Ivec, PlainText) -> % cfb misspelled Key = check_des3_key(Key0), - block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, true); -block_encrypt(des3_cfb, Key0, Ivec, Data) -> + block_crypt_nif(des_ede3_cbf, Key, Ivec, PlainText, true); +block_encrypt(des3_cfb, Key0, Ivec, PlainText) -> Key = check_des3_key(Key0), - block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, true); -block_encrypt(aes_ige256, Key, Ivec, Data) -> - notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, true)); -block_encrypt(aes_gcm, Key, Ivec, {AAD, Data}) -> - aes_gcm_encrypt(Key, Ivec, AAD, Data); -block_encrypt(aes_gcm, Key, Ivec, {AAD, Data, TagLength}) -> - aes_gcm_encrypt(Key, Ivec, AAD, Data, TagLength); -block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, Data}) -> - chacha20_poly1305_encrypt(Key, Ivec, AAD, Data). - --spec block_decrypt(des_cbc | des_cfb | - des3_cbc | des3_cbf | des3_cfb | des_ede3 | - blowfish_cbc | blowfish_cfb64 | blowfish_ofb64 | - aes_cbc128 | aes_cfb8 | aes_cfb128 | aes_cbc256 | aes_ige256 | - aes_cbc | - rc2_cbc, - Key::iodata(), Ivec::binary(), Data::iodata()) -> binary(); - (aes_gcm | chacha20_poly1305, Key::iodata(), Ivec::binary(), + block_crypt_nif(des_ede3_cfb, Key, Ivec, PlainText, true); +block_encrypt(aes_ige256, Key, Ivec, PlainText) -> + notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true)); +block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText}) -> + aes_gcm_encrypt(Key, Ivec, AAD, PlainText); +block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) -> + aes_gcm_encrypt(Key, Ivec, AAD, PlainText, TagLength); +block_encrypt(chacha20_poly1305, Key, Ivec, {AAD, PlainText}) -> + chacha20_poly1305_encrypt(Key, Ivec, AAD, PlainText). + +-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) -> binary(); + (Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error. block_decrypt(Type, Key, Ivec, Data) when Type =:= des_cbc; Type =:= des_cfb; @@ -269,7 +543,7 @@ block_decrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc; Type =:= des_ede3 -> Key = check_des3_key(Key0), block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, false); -block_decrypt(des3_cbf, Key0, Ivec, Data) -> +block_decrypt(des3_cbf, Key0, Ivec, Data) -> % cfb misspelled Key = check_des3_key(Key0), block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, false); block_decrypt(des3_cfb, Key0, Ivec, Data) -> @@ -282,18 +556,23 @@ block_decrypt(aes_gcm, Key, Ivec, {AAD, Data, Tag}) -> block_decrypt(chacha20_poly1305, Key, Ivec, {AAD, Data, Tag}) -> chacha20_poly1305_decrypt(Key, Ivec, AAD, Data, Tag). --spec block_encrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary(). -block_encrypt(Type, Key, Data) -> - block_crypt_nif(Type, Key, Data, true). --spec block_decrypt(des_ecb | blowfish_ecb | aes_ecb, Key::iodata(), Data::iodata()) -> binary(). +-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary(). + +block_encrypt(Type, Key, PlainText) -> + block_crypt_nif(Type, Key, PlainText, true). + + +-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary(). block_decrypt(Type, Key, Data) -> block_crypt_nif(Type, Key, Data, false). --spec next_iv(des_cbc | des3_cbc | aes_cbc | aes_ige, Data::iodata()) -> binary(). +-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige, + Data :: iodata(), + NextIVec :: binary(). next_iv(Type, Data) when is_binary(Data) -> IVecSize = case Type of des_cbc -> 8; @@ -308,7 +587,9 @@ next_iv(Type, Data) when is_binary(Data) -> next_iv(Type, Data) when is_list(Data) -> next_iv(Type, list_to_binary(Data)). --spec next_iv(des_cfb, Data::iodata(), Ivec::binary()) -> binary(). +-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(), + IVec :: binary(), + NextIVec :: binary(). next_iv(des_cfb, Data, IVec) -> IVecAndData = list_to_binary([IVec, Data]), @@ -317,41 +598,57 @@ next_iv(des_cfb, Data, IVec) -> next_iv(Type, Data, _Ivec) -> next_iv(Type, Data). +%%%---- Stream ciphers + +-opaque stream_state() :: {stream_cipher(), reference()}. + +-type stream_cipher() :: rc4 | aes_ctr | chacha20 . + +-spec stream_init(Type, Key, IVec) -> State when Type :: aes_ctr | chacha20, + Key :: iodata(), + IVec :: binary(), + State :: stream_state() . stream_init(aes_ctr, Key, Ivec) -> {aes_ctr, aes_ctr_stream_init(Key, Ivec)}; stream_init(chacha20, Key, Ivec) -> {chacha20, chacha20_stream_init(Key,Ivec)}. +-spec stream_init(Type, Key) -> State when Type :: rc4, + Key :: iodata(), + State :: stream_state() . stream_init(rc4, Key) -> {rc4, notsup_to_error(rc4_set_key(Key))}. +-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} + when State :: stream_state(), + PlainText :: iodata(), + NewState :: stream_state(), + CipherText :: iodata() . stream_encrypt(State, Data0) -> Data = iolist_to_binary(Data0), MaxByts = max_bytes(), stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). +-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} + when State :: stream_state(), + CipherText :: iodata(), + NewState :: stream_state(), + PlainText :: iodata() . stream_decrypt(State, Data0) -> Data = iolist_to_binary(Data0), MaxByts = max_bytes(), stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []). -%% -%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib -%% + +%%%================================================================ +%%% +%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib +%%% +%%%================================================================ -type rand_cache_seed() :: nonempty_improper_list(non_neg_integer(), binary()). --spec strong_rand_bytes(non_neg_integer()) -> binary(). --spec rand_seed() -> rand:state(). --spec rand_seed_s() -> rand:state(). --spec rand_seed_alg(Alg :: atom()) -> - {rand:alg_handler(), - atom() | rand_cache_seed()}. --spec rand_seed_alg_s(Alg :: atom()) -> - {rand:alg_handler(), - atom() | rand_cache_seed()}. --spec rand_uniform(crypto_integer(), crypto_integer()) -> - crypto_integer(). +-spec strong_rand_bytes(N::non_neg_integer()) -> binary(). strong_rand_bytes(Bytes) -> case strong_rand_bytes_nif(Bytes) of false -> erlang:error(low_entropy); @@ -360,16 +657,24 @@ strong_rand_bytes(Bytes) -> strong_rand_bytes_nif(_Bytes) -> ?nif_stub. +-spec rand_seed() -> rand:state(). rand_seed() -> rand:seed(rand_seed_s()). +-spec rand_seed_s() -> rand:state(). rand_seed_s() -> rand_seed_alg_s(?MODULE). +-spec rand_seed_alg(Alg :: atom()) -> + {rand:alg_handler(), + atom() | rand_cache_seed()}. rand_seed_alg(Alg) -> rand:seed(rand_seed_alg_s(Alg)). -define(CRYPTO_CACHE_BITS, 56). +-spec rand_seed_alg_s(Alg :: atom()) -> + {rand:alg_handler(), + atom() | rand_cache_seed()}. rand_seed_alg_s(?MODULE) -> {#{ type => ?MODULE, bits => 64, @@ -427,7 +732,9 @@ strong_rand_float() -> WholeRange = strong_rand_range(1 bsl 53), ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange). -rand_uniform(From,To) when is_binary(From), is_binary(To) -> +-spec rand_uniform(crypto_integer(), crypto_integer()) -> + crypto_integer(). +rand_uniform(From, To) when is_binary(From), is_binary(To) -> case rand_uniform_nif(From,To) of <> when MSB > 127 -> <<(Len + 1):32/integer, 0, MSB, Rest/binary>>; @@ -462,116 +769,228 @@ rand_seed(Seed) when is_binary(Seed) -> rand_seed_nif(_Seed) -> ?nif_stub. --spec mod_pow(binary()|integer(), binary()|integer(), binary()|integer()) -> binary() | error. -mod_pow(Base, Exponent, Prime) -> - case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of - <<0>> -> error; - R -> R - end. +%%%================================================================ +%%% +%%% Sign/verify +%%% +%%%================================================================ +-type pk_sign_verify_algs() :: rsa | dss | ecdsa . -verify(Algorithm, Type, Data, Signature, Key) -> - verify(Algorithm, Type, Data, Signature, Key, []). +-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] . -%% Backwards compatible -verify(Algorithm = dss, none, Digest, Signature, Key, Options) -> - verify(Algorithm, sha, {digest, Digest}, Signature, Key, Options); -verify(Algorithm, Type, Data, Signature, Key, Options) -> - case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of - notsup -> erlang:error(notsup); - Boolean -> Boolean - end. +-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()} + | {rsa_pss_saltlen, integer()} . +-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding + | rsa_x931_padding | rsa_no_padding + . + + +%%%---------------------------------------------------------------- +%%% Sign + +-spec sign(Algorithm, DigestType, Msg, Key) + -> Signature + when Algorithm :: pk_sign_verify_algs(), + DigestType :: rsa_digest_type() + | dss_digest_type() + | ecdsa_digest_type(), + Msg :: binary() | {digest,binary()}, + Key :: rsa_private() + | dss_private() + | [ecdsa_private()|ecdsa_params()] + | engine_key_ref(), + Signature :: binary() . sign(Algorithm, Type, Data, Key) -> sign(Algorithm, Type, Data, Key, []). -%% Backwards compatible -sign(Algorithm = dss, none, Digest, Key, Options) -> - sign(Algorithm, sha, {digest, Digest}, Key, Options); -sign(Algorithm, Type, Data, Key, Options) -> + +-spec sign(Algorithm, DigestType, Msg, Key, Options) + -> Signature + when Algorithm :: pk_sign_verify_algs(), + DigestType :: rsa_digest_type() + | dss_digest_type() + | ecdsa_digest_type() + | none, + Msg :: binary() | {digest,binary()}, + Key :: rsa_private() + | dss_private() + | [ecdsa_private() | ecdsa_params()] + | engine_key_ref(), + Options :: pk_sign_verify_opts(), + Signature :: binary() . + +sign(Algorithm0, Type0, Data, Key, Options) -> + {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data), case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]); notsup -> erlang:error(notsup); Signature -> Signature end. +pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub. +%%%---------------------------------------------------------------- +%%% Verify + +-spec verify(Algorithm, DigestType, Msg, Signature, Key) + -> Result + when Algorithm :: pk_sign_verify_algs(), + DigestType :: rsa_digest_type() + | dss_digest_type() + | ecdsa_digest_type(), + Msg :: binary() | {digest,binary()}, + Signature :: binary(), + Key :: rsa_private() + | dss_private() + | [ecdsa_private() | ecdsa_params()] + | engine_key_ref(), + Result :: boolean(). --type key_id() :: string() | binary() . --type password() :: string() | binary() . - --type engine_key_ref() :: #{engine := engine_ref(), - key_id := key_id(), - password => password(), - term() => term() - }. - --type pk_algs() :: rsa | ecdsa | dss . --type pk_key() :: engine_key_ref() | [integer() | binary()] . --type pk_opt() :: list() | rsa_padding() . - --spec public_encrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary(). --spec public_decrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary(). --spec private_encrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary(). --spec private_decrypt(pk_algs(), binary(), pk_key(), pk_opt()) -> binary(). +verify(Algorithm, Type, Data, Signature, Key) -> + verify(Algorithm, Type, Data, Signature, Key, []). -public_encrypt(Algorithm, In, Key, Options) when is_list(Options) -> - case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, false, true) of - error -> erlang:error(encrypt_failed, [Algorithm, In, Key, Options]); +-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options) + -> Result + when Algorithm :: pk_sign_verify_algs(), + DigestType :: rsa_digest_type() + | dss_digest_type() + | ecdsa_digest_type(), + Msg :: binary() | {digest,binary()}, + Signature :: binary(), + Key :: rsa_public() + | dss_public() + | [ecdsa_public() | ecdsa_params()] + | engine_key_ref(), + Options :: pk_sign_verify_opts(), + Result :: boolean(). + +verify(Algorithm0, Type0, Data, Signature, Key, Options) -> + {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data), + case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of notsup -> erlang:error(notsup); - Out -> Out - end; -%% Backwards compatible -public_encrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) -> - public_encrypt(Algorithm, In, Key, [{rsa_padding, Padding}]). + Boolean -> Boolean + end. -private_decrypt(Algorithm, In, Key, Options) when is_list(Options) -> - case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, true, false) of - error -> erlang:error(decrypt_failed, [Algorithm, In, Key, Options]); - notsup -> erlang:error(notsup); - Out -> Out - end; -%% Backwards compatible -private_decrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) -> - private_decrypt(Algorithm, In, Key, [{rsa_padding, Padding}]). +pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub. -private_encrypt(Algorithm, In, Key, Options) when is_list(Options) -> - case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, true, true) of - error -> erlang:error(encrypt_failed, [Algorithm, In, Key, Options]); - notsup -> erlang:error(notsup); - Out -> Out - end; -%% Backwards compatible -private_encrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) -> - private_encrypt(Algorithm, In, Key, [{rsa_padding, Padding}]). +%% Backwards compatible: +sign_verify_compatibility(dss, none, Digest) -> + {sha, {digest, Digest}}; +sign_verify_compatibility(Algorithm0, Type0, _Digest) -> + {Algorithm0, Type0}. -public_decrypt(Algorithm, In, Key, Options) when is_list(Options) -> - case pkey_crypt_nif(Algorithm, In, format_pkey(Algorithm, Key), Options, false, false) of - error -> erlang:error(decrypt_failed, [Algorithm, In, Key, Options]); +%%%================================================================ +%%% +%%% Public/private encrypt/decrypt +%%% +%%% Only rsa works so far (although ecdsa | dss should do it) +%%%================================================================ +-type pk_encrypt_decrypt_algs() :: rsa . + +-type pk_encrypt_decrypt_opts() :: [rsa_opt()] | rsa_compat_opts(). + +-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}] + | rsa_padding() . + +-type rsa_padding() :: rsa_pkcs1_padding + | rsa_pkcs1_oaep_padding + | rsa_sslv23_padding + | rsa_x931_padding + | rsa_no_padding. + +-type rsa_opt() :: {rsa_padding, rsa_padding()} + | {signature_md, atom()} + | {rsa_mgf1_md, sha} + | {rsa_oaep_label, binary()} + | {rsa_oaep_md, sha} . + +%%%---- Encrypt with public key + +-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) -> + CipherText when Algorithm :: pk_encrypt_decrypt_algs(), + PlainText :: binary(), + PublicKey :: rsa_public() | engine_key_ref(), + Options :: pk_encrypt_decrypt_opts(), + CipherText :: binary(). +public_encrypt(Algorithm, PlainText, PublicKey, Options) -> + pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true). + +%%%---- Decrypt with private key + +-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) -> + PlainText when Algorithm :: pk_encrypt_decrypt_algs(), + CipherText :: binary(), + PrivateKey :: rsa_private() | engine_key_ref(), + Options :: pk_encrypt_decrypt_opts(), + PlainText :: binary() . +private_decrypt(Algorithm, CipherText, PrivateKey, Options) -> + pkey_crypt(Algorithm, CipherText, PrivateKey, Options, true, false). + +%%%---- Encrypt with private key + +-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) -> + CipherText when Algorithm :: pk_encrypt_decrypt_algs(), + PlainText :: binary(), + PrivateKey :: rsa_private() | engine_key_ref(), + Options :: pk_encrypt_decrypt_opts(), + CipherText :: binary(). +private_encrypt(Algorithm, PlainText, PrivateKey, Options) -> + pkey_crypt(Algorithm, PlainText, PrivateKey, Options, true, true). + +%%%---- Decrypt with public key + +-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) -> + PlainText when Algorithm :: pk_encrypt_decrypt_algs(), + CipherText :: binary(), + PublicKey :: rsa_public() | engine_key_ref(), + Options :: pk_encrypt_decrypt_opts(), + PlainText :: binary() . +public_decrypt(Algorithm, CipherText, PublicKey, Options) -> + pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false). + +%%%---- Call the nif, but fix a compatibility issue first + +%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif): +pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) -> + pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec); + +pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) -> + case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of + error when EncDec==true -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]); + error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]); notsup -> erlang:error(notsup); Out -> Out - end; -%% Backwards compatible -public_decrypt(Algorithm = rsa, In, Key, Padding) when is_atom(Padding) -> - public_decrypt(Algorithm, In, Key, [{rsa_padding, Padding}]). - - -%% -%% XOR - xor to iolists and return a binary -%% NB doesn't check that they are the same size, just concatenates -%% them and sends them to the driver -%% --spec exor(iodata(), iodata()) -> binary(). + end. -exor(Bin1, Bin2) -> - Data1 = iolist_to_binary(Bin1), - Data2 = iolist_to_binary(Bin2), - MaxBytes = max_bytes(), - exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []). +pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub. +%%%================================================================ +%%% +%%% +%%% +%%%================================================================ + +-spec generate_key(Type, Params) + -> {PublicKey, PrivKeyOut} + when Type :: dh | ecdh | rsa | srp, + PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(), + PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, + Params :: dh_params() | ecdh_params() | rsa_params() | srp_gen_params() + . generate_key(Type, Params) -> generate_key(Type, Params, undefined). +-spec generate_key(Type, Params, PrivKeyIn) + -> {PublicKey, PrivKeyOut} + when Type :: dh | ecdh | rsa | srp, + PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(), + PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, + PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()}, + Params :: dh_params() | ecdh_params() | rsa_params() | srp_comp_params() + . + generate_key(dh, DHParameters0, PrivateKey) -> {DHParameters, Len} = case DHParameters0 of @@ -618,6 +1037,14 @@ generate_key(ecdh, Curve, PrivKey) -> evp_generate_key_nif(_Curve) -> ?nif_stub. +-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params) + -> SharedSecret + when Type :: dh | ecdh | srp, + SharedSecret :: binary(), + OthersPublicKey :: dh_public() | ecdh_public() | srp_public(), + MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()}, + Params :: dh_params() | ecdh_params() | srp_comp_params() + . compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) -> case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey), @@ -670,9 +1097,59 @@ compute_key(ecdh, Others, My, Curve) -> evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub. -%%====================================================================== -%% Engine functions -%%====================================================================== + +%%%================================================================ +%%% +%%% XOR - xor to iolists and return a binary +%%% NB doesn't check that they are the same size, just concatenates +%%% them and sends them to the driver +%%% +%%%================================================================ + +-spec exor(iodata(), iodata()) -> binary(). + +exor(Bin1, Bin2) -> + Data1 = iolist_to_binary(Bin1), + Data2 = iolist_to_binary(Bin2), + MaxBytes = max_bytes(), + exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []). + + +%%%================================================================ +%%% +%%% Exponentiation modulo +%%% +%%%================================================================ + +-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(), + P :: binary() | integer(), + M :: binary() | integer(), + Result :: binary() | error . +mod_pow(Base, Exponent, Prime) -> + case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of + <<0>> -> error; + R -> R + end. + +%%%====================================================================== +%%% +%%% Engine functions +%%% +%%%====================================================================== + +%%%---- Refering to keys stored in an engine: +-type key_id() :: string() | binary() . +-type password() :: string() | binary() . + +-type engine_key_ref() :: #{engine := engine_ref(), + key_id := key_id(), + password => password(), + term() => term() + }. + +%%%---- Commands: +-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}. + %%---------------------------------------------------------------------- %% Function: engine_get_all_methods/0 %%---------------------------------------------------------------------- @@ -684,18 +1161,18 @@ evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub. -type engine_ref() :: term(). --spec engine_get_all_methods() -> - [engine_method_type()]. +-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()]. engine_get_all_methods() -> notsup_to_error(engine_get_all_methods_nif()). %%---------------------------------------------------------------------- %% Function: engine_load/3 %%---------------------------------------------------------------------- --spec engine_load(EngineId::unicode:chardata(), - PreCmds::[{unicode:chardata(), unicode:chardata()}], - PostCmds::[{unicode:chardata(), unicode:chardata()}]) -> - {ok, Engine::engine_ref()} | {error, Reason::term()}. +-spec engine_load(EngineId, PreCmds, PostCmds) -> + Result when EngineId::unicode:chardata(), + PreCmds::[engine_cmnd()], + PostCmds::[engine_cmnd()], + Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds), is_list(PostCmds) -> engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()). @@ -703,11 +1180,12 @@ engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds), %%---------------------------------------------------------------------- %% Function: engine_load/4 %%---------------------------------------------------------------------- --spec engine_load(EngineId::unicode:chardata(), - PreCmds::[{unicode:chardata(), unicode:chardata()}], - PostCmds::[{unicode:chardata(), unicode:chardata()}], - EngineMethods::[engine_method_type()]) -> - {ok, Engine::term()} | {error, Reason::term()}. +-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> + Result when EngineId::unicode:chardata(), + PreCmds::[engine_cmnd()], + PostCmds::[engine_cmnd()], + EngineMethods::[engine_method_type()], + Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds), is_list(PostCmds) -> try @@ -752,13 +1230,14 @@ engine_load_2(Engine, PostCmds, EngineMethods) -> %%---------------------------------------------------------------------- %% Function: engine_unload/1 %%---------------------------------------------------------------------- --spec engine_unload(Engine::term()) -> - ok | {error, Reason::term()}. +-spec engine_unload(Engine) -> Result when Engine :: engine_ref(), + Result :: ok | {error, Reason::term()}. engine_unload(Engine) -> engine_unload(Engine, engine_get_all_methods()). --spec engine_unload(Engine::term(), EngineMethods::[engine_method_type()]) -> - ok | {error, Reason::term()}. +-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(), + EngineMethods :: [engine_method_type()], + Result :: ok | {error, Reason::term()}. engine_unload(Engine, EngineMethods) -> try [ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) || @@ -775,6 +1254,8 @@ engine_unload(Engine, EngineMethods) -> %%---------------------------------------------------------------------- %% Function: engine_by_id/1 %%---------------------------------------------------------------------- +-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(), + Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} . engine_by_id(EngineId) -> try notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) @@ -786,32 +1267,39 @@ engine_by_id(EngineId) -> %%---------------------------------------------------------------------- %% Function: engine_add/1 %%---------------------------------------------------------------------- +-spec engine_add(Engine) -> Result when Engine :: engine_ref(), + Result :: ok | {error, Reason::term()} . engine_add(Engine) -> notsup_to_error(engine_add_nif(Engine)). %%---------------------------------------------------------------------- %% Function: engine_remove/1 %%---------------------------------------------------------------------- +-spec engine_remove(Engine) -> Result when Engine :: engine_ref(), + Result :: ok | {error, Reason::term()} . engine_remove(Engine) -> notsup_to_error(engine_remove_nif(Engine)). %%---------------------------------------------------------------------- %% Function: engine_get_id/1 %%---------------------------------------------------------------------- +-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(), + EngineId :: unicode:chardata(). engine_get_id(Engine) -> notsup_to_error(engine_get_id_nif(Engine)). %%---------------------------------------------------------------------- %% Function: engine_get_name/1 %%---------------------------------------------------------------------- +-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(), + EngineName :: unicode:chardata(). engine_get_name(Engine) -> notsup_to_error(engine_get_name_nif(Engine)). %%---------------------------------------------------------------------- %% Function: engine_list/0 %%---------------------------------------------------------------------- --spec engine_list() -> - [EngineId::binary()]. +-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()]. engine_list() -> case notsup_to_error(engine_get_first_nif()) of {ok, <<>>} -> @@ -841,21 +1329,23 @@ engine_list(Engine0, IdList) -> %%---------------------------------------------------------------------- %% Function: engine_ctrl_cmd_string/3 %%---------------------------------------------------------------------- --spec engine_ctrl_cmd_string(Engine::term(), - CmdName::unicode:chardata(), - CmdArg::unicode:chardata()) -> - ok | {error, Reason::term()}. +-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> + Result when Engine::term(), + CmdName::unicode:chardata(), + CmdArg::unicode:chardata(), + Result :: ok | {error, Reason::term()}. engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false). %%---------------------------------------------------------------------- %% Function: engine_ctrl_cmd_string/4 %%---------------------------------------------------------------------- --spec engine_ctrl_cmd_string(Engine::term(), - CmdName::unicode:chardata(), - CmdArg::unicode:chardata(), - Optional::boolean()) -> - ok | {error, Reason::term()}. +-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> + Result when Engine::term(), + CmdName::unicode:chardata(), + CmdArg::unicode:chardata(), + Optional::boolean(), + Result :: ok | {error, Reason::term()}. engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> case engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds([{CmdName, CmdArg}]), @@ -872,6 +1362,10 @@ engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> %% Function: ensure_engine_loaded/2 %% Special version of load that only uses dynamic engine to load %%---------------------------------------------------------------------- +-spec ensure_engine_loaded(EngineId, LibPath) -> + Result when EngineId :: unicode:chardata(), + LibPath :: unicode:chardata(), + Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. ensure_engine_loaded(EngineId, LibPath) -> ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()). @@ -879,6 +1373,11 @@ ensure_engine_loaded(EngineId, LibPath) -> %% Function: ensure_engine_loaded/3 %% Special version of load that only uses dynamic engine to load %%---------------------------------------------------------------------- +-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> + Result when EngineId :: unicode:chardata(), + LibPath :: unicode:chardata(), + EngineMethods :: [engine_method_type()], + Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}. ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> try List = crypto:engine_list(), @@ -930,12 +1429,18 @@ ensure_engine_loaded_2(Engine, Methods) -> %%---------------------------------------------------------------------- %% Function: ensure_engine_unloaded/1 %%---------------------------------------------------------------------- +-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(), + Result :: ok | {error, Reason::term()}. ensure_engine_unloaded(Engine) -> ensure_engine_unloaded(Engine, engine_get_all_methods()). %%---------------------------------------------------------------------- %% Function: ensure_engine_unloaded/2 %%---------------------------------------------------------------------- +-spec ensure_engine_unloaded(Engine, EngineMethods) -> + Result when Engine :: engine_ref(), + EngineMethods :: [engine_method_type()], + Result :: ok | {error, Reason::term()}. ensure_engine_unloaded(Engine, EngineMethods) -> case engine_remove(Engine) of ok -> @@ -1010,9 +1515,13 @@ path2bin(Path) when is_list(Path) -> Bin end. -%%-------------------------------------------------------------------- +%%%================================================================ +%%%================================================================ +%%% %%% Internal functions -%%-------------------------------------------------------------------- +%%% +%%%================================================================ + max_bytes() -> ?MAX_BYTES_TO_NIF. @@ -1151,14 +1660,6 @@ do_stream_decrypt({chacha20, State0}, Data) -> %% %% AES - in counter mode (CTR) with state maintained for multi-call streaming %% --type ctr_state() :: { iodata(), binary(), binary(), integer() } | binary(). - --spec aes_ctr_stream_init(iodata(), binary()) -> ctr_state(). --spec aes_ctr_stream_encrypt(ctr_state(), binary()) -> - { ctr_state(), binary() }. --spec aes_ctr_stream_decrypt(ctr_state(), binary()) -> - { ctr_state(), binary() }. - aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub. aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub. aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub. @@ -1172,11 +1673,6 @@ rc4_encrypt_with_state(_State, _Data) -> ?nif_stub. %% %% CHACHA20 - stream cipher %% --type chacha20_state() :: term(). --spec chacha20_stream_init(iodata(), binary()) -> chacha20_state(). --spec chacha20_stream_encrypt(chacha20_state(), binary()) -> {chacha20_state(), binary()}. --spec chacha20_stream_decrypt(chacha20_state(), binary()) -> {chacha20_state(), binary()}. - chacha20_stream_init(_Key, _IVec) -> ?nif_stub. chacha20_stream_encrypt(_State, _Data) -> ?nif_stub. chacha20_stream_decrypt(_State, _Data) -> ?nif_stub. @@ -1247,11 +1743,6 @@ srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ? srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub. -%% Digital signatures -------------------------------------------------------------------- - -pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub. -pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub. - %% Public Keys -------------------------------------------------------------------- %% RSA Rivest-Shamir-Adleman functions %% @@ -1273,13 +1764,20 @@ ec_key_generate(_Curve, _Key) -> ?nif_stub. ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub. +-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve() | edwards_curve() . + ec_curves() -> crypto_ec_curves:curves(). +-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(), + ExplicitCurve :: ec_explicit_curve() . ec_curve(X) -> crypto_ec_curves:curve(X). +-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss, + EnginePrivateKeyRef :: engine_key_ref(), + PublicKey :: rsa_public() | dss_public() . privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa -> try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap)) of @@ -1305,10 +1803,16 @@ term_to_nif_prime({prime_field, Prime}) -> {prime_field, ensure_int_as_bin(Prime)}; term_to_nif_prime(PrimeField) -> PrimeField. + term_to_nif_curve({A, B, Seed}) -> {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}. + nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) -> - {term_to_nif_prime(PrimeField), term_to_nif_curve(Curve), ensure_int_as_bin(BasePoint), ensure_int_as_bin(Order), ensure_int_as_bin(CoFactor)}; + {term_to_nif_prime(PrimeField), + term_to_nif_curve(Curve), + ensure_int_as_bin(BasePoint), + ensure_int_as_bin(Order), + ensure_int_as_bin(CoFactor)}; nif_curve_params(Curve) when is_atom(Curve) -> %% named curve case Curve of @@ -1348,6 +1852,7 @@ int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 -> int_to_bin_neg(X,Ds) -> int_to_bin_neg(X bsr 8, [(X band 255)|Ds]). +-spec bytes_to_integer(binary()) -> integer() . bytes_to_integer(Bin) -> bin_to_int(Bin). @@ -1395,9 +1900,6 @@ format_pwd(M) -> M. %%-------------------------------------------------------------------- %% --type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' | 'rsa_no_padding'. - -pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub. %% large integer in a binary with 32bit length %% MP representaion (SSH2) -- cgit v1.2.3 From cb654518a4fa58fa65f46e1386ff91c6375f6f5a Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:08:13 +0200 Subject: crypto: Generate refman from types and specs and fix links in engine chapter for generated crypto module refman --- lib/crypto/doc/src/crypto.xml | 1104 ++++++++++++++++-------------------- lib/crypto/doc/src/engine_keys.xml | 2 +- 2 files changed, 481 insertions(+), 625 deletions(-) diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 4289bd4a64..9d436847ac 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -46,6 +46,12 @@

Block ciphers - DES and AES in Block Cipher Modes - ECB, CBC, CFB, OFB, CTR and GCM

+ +

GCM: Dworkin, M., + "Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC", + National Institute of Standards and Technology SP 800-38D, November 2007. +

+

RSA encryption RFC 1321

@@ -56,192 +62,358 @@

Secure Remote Password Protocol (SRP - RFC 2945)

- -

gcm: Dworkin, M., "Recommendation for Block Cipher Modes of - Operation: Galois/Counter Mode (GCM) and GMAC", - National Institute of Standards and Technology SP 800- - 38D, November 2007.

-
- -
- DATA TYPES - - key_value() = integer() | binary() -

Always binary() when used as return value

+ +

The actual supported algorithms and features depends on their availability in the actual libcrypto used. + See the crypto (App) about dependencies. +

+

Enabling FIPS mode will also disable algorithms and features. +

+
- rsa_public() = [key_value()] = [E, N] -

Where E is the public exponent and N is public modulus.

+

The CRYPTO User's Guide has more information on + FIPS, Engines and Algorithm Details like key lengths. +

+ - rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] -

Where E is the public exponent, N is public modulus and D is - the private exponent. The longer key format contains redundant - information that will make the calculation faster. P1,P2 are first - and second prime factors. E1,E2 are first and second exponents. C - is the CRT coefficient. Terminology is taken from RFC 3447.

+ + Ciphers + + + +

Stream ciphers for + stream_encrypt/2 and + stream_decrypt/2 . +

+
+
- dss_public() = [key_value()] = [P, Q, G, Y] -

Where P, Q and G are the dss parameters and Y is the public key.

+ + + + + +

Block ciphers with initialization vector for + block_encrypt/4 and + block_decrypt/4 . +

+
+
- dss_private() = [key_value()] = [P, Q, G, X] -

Where P, Q and G are the dss parameters and X is the private key.

+ + + + +

Block ciphers without initialization vector for + block_encrypt/3 and + block_decrypt/3 . +

+
+
- srp_public() = key_value() -

Where is A or B from SRP design

+ + + +

Ciphers with simultaneous MAC-calculation or MAC-checking. + block_encrypt/4 and + block_decrypt/4 . +

+
+
- srp_private() = key_value() -

Where is a or b from SRP design

+ Digests + + + + + + + -

Where Verifier is v, Generator is g and Prime is N, DerivedKey is X, and Scrambler is - u (optional will be generated if not provided) from SRP design - Version = '3' | '6' | '6a' -

+ + + +

The compatibility_only_hash() algorithms are recommended only for compatibility with existing applications.

+
+
- dh_public() = key_value() + + + + + - dh_private() = key_value() + + + + + - dh_params() = [key_value()] = [P, G] | [P, G, PrivateKeyBitLength] + + + + + - ecdh_public() = key_value() + Elliptic Curves + + + + +

Note that some curves are disabled if FIPS is enabled.

+
+
- ecdh_private() = key_value() + + + + + +

Parametric curve definition.

+
+
- ecdh_params() = ec_named_curve() | ec_explicit_curve() + + + + + +

Curve definition details.

+
+
- ed_named_curves_ecdh() -> x448 | x25519 -

Note that the curves are only supported if the underlying OpenSSL has support for them.

+ Keys + + + + +

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

+

A key for des3 is a list of three iolists

+
+
- ec_explicit_curve() = - {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), - CoFactor :: none | integer()} + + + +

Always binary() when used as return value

+
+
- ec_field() = {prime_field, Prime :: integer()} | - {characteristic_two_field, M :: integer(), Basis :: ec_basis()} + Public/Private Keys + + + + + + rsa_public() = [E, N] + rsa_private() = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] +

Where E is the public exponent, N is public modulus and D is + the private exponent. The longer key format contains redundant + information that will make the calculation faster. P1,P2 are first + and second prime factors. E1,E2 are first and second exponents. C + is the CRT coefficient. Terminology is taken from RFC 3447.

+
+
- ec_basis() = {tpbasis, K :: non_neg_integer()} | - {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} | - onbasis + + + + + dss_public() = [P, Q, G, Y] +

Where P, Q and G are the dss parameters and Y is the public key.

- ec_named_curve() -> - sect571r1| sect571k1| sect409r1| sect409k1| secp521r1| secp384r1| secp224r1| secp224k1| - secp192k1| secp160r2| secp128r2| secp128r1| sect233r1| sect233k1| sect193r2| sect193r1| - sect131r2| sect131r1| sect283r1| sect283k1| sect163r2| secp256k1| secp160k1| secp160r1| - secp112r2| secp112r1| sect113r2| sect113r1| sect239k1| sect163r1| sect163k1| secp256r1| - secp192r1| - brainpoolP160r1| brainpoolP160t1| brainpoolP192r1| brainpoolP192t1| brainpoolP224r1| - brainpoolP224t1| brainpoolP256r1| brainpoolP256t1| brainpoolP320r1| brainpoolP320t1| - brainpoolP384r1| brainpoolP384t1| brainpoolP512r1| brainpoolP512t1 - -

Note that the sect curves are GF2m (characteristic two) curves and are only supported if the - underlying OpenSSL has support for them. - See also crypto:supports/0 -

+ dss_private() = [P, Q, G, X] +

Where P, Q and G are the dss parameters and X is the private key.

+
+
- - - engine_key_ref() = #{engine := engine_ref(), - key_id := key_id(), - password => password()} + + + + + + + - engine_ref() = term() -

The result of a call to for example engine_load/3. -

+ + + + + srp_public() = key_integer() +

Where is A or B from SRP design

+ + srp_private() = key_integer() +

Where is a or b from SRP design

+
+
- key_id() = string() | binary() -

Identifies the key to be used. The format depends on the loaded engine. It is passed to - the ENGINE_load_(private|public)_key functions in libcrypto. -

+ + + + + + srp_user_gen_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom()] + + srp_host_gen_params() = [Verifier::binary(), Prime::binary(), Version::atom() ] + + srp_user_comp_params() = [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | ScramblerArg::list()] + + srp_host_comp_params() = [Verifier::binary(), Prime::binary(), Version::atom() | ScramblerArg::list()] +

Where Verifier is v, Generator is g and Prime is N, DerivedKey is X, and Scrambler is + u (optional will be generated if not provided) from SRP design + Version = '3' | '6' | '6a' +

+
+
- password() = string() | binary() -

The key's password -

+ Public Key Ciphers - stream_cipher() = rc4 | aes_ctr | chacha20 + + + +

Algorithms for public key encrypt/decrypt. Only RSA is supported.

+
+
- block_cipher() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc | - blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc + + + + + +

Options for public key encrypt/decrypt. Only RSA is supported.

+
+
- aead_cipher() = aes_gcm | chacha20_poly1305 -

Note that the actual supported algorithms depends on the underlying crypto library.

+ + + +

Those option forms are kept only for compatibility and should not be used in new code.

+
+
- stream_key() = aes_key() | rc4_key() + Public Key Sign and Verify - block_key() = aes_key() | blowfish_key() | des_key()| des3_key() + + + +

Algorithms for sign and verify.

+
+
- aes_key() = iodata()

Key length is 128, 192 or 256 bits

+ + + + + +

Options for sign and verify.

+
+
- rc4_key() = iodata()

Variable key length from 8 bits up to 2048 bits (usually between 40 and 256)

+ Diffie-Hellman Keys and parameters + + + + + + - blowfish_key() = iodata()

Variable key length from 32 bits up to 448 bits

+ + + + dh_params() = [P, G] | [P, G, PrivateKeyBitLength] + + - des_key() = iodata()

Key length is 64 bits (in CBC mode only 8 bits are used)

+ + + + + + + - des3_key() = [binary(), binary(), binary()]

Each key part is 64 bits (in CBC mode only 8 bits are used)

+ Types for Engines - digest_type() = md5 | sha | sha224 | sha256 | sha384 | sha512 + + + + +

The result of a call to engine_load/3. +

+
+
- rsa_digest_type() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 + + + +

Identifies the key to be used. The format depends on the loaded engine. It is passed to + the ENGINE_load_(private|public)_key functions in libcrypto. +

+
+
- dss_digest_type() = sha | sha224 | sha256 | sha384 | sha512

Note that the actual supported - dss_digest_type depends on the underlying crypto library. In OpenSSL version >= 1.0.1 the listed digest are supported, while in 1.0.0 only sha, sha224 and sha256 are supported. In version 0.9.8 only sha is supported.

+ + + +

The password of the key stored in an engine. +

+
+
- ecdsa_digest_type() = sha | sha224 | sha256 | sha384 | sha512 + + + - sign_options() = [{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}] + + + +

Pre and Post commands for engine_load/3 and /4. +

+
+
- rsa_sign_padding() = rsa_pkcs1_padding | rsa_pkcs1_pss_padding + Internal data types - hash_algorithms() = md5 | ripemd160 | sha | sha224 | sha256 | sha384 | sha512 | - sha3_224 | sha3_256 | sha3_384 | sha3_512 -

md4 is also supported for hash_init/1 and hash/2. - Note that both md4 and md5 are recommended only for compatibility with existing applications. - Note that the actual supported hash_algorithms depends on the underlying crypto library. -

- cipher_algorithms() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ctr | aes_gcm | - aes_ige256 | blowfish_cbc | blowfish_cfb64 | chacha20 | chacha20_poly1305 | des_cbc | - des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc | rc4 - mac_algorithms() = hmac | cmac | poly1305 - public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m -

Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported - with ecdsa and ecdh. -

- engine_method_type() = engine_method_rsa | engine_method_dsa | engine_method_dh | - engine_method_rand | engine_method_ecdh | engine_method_ecdsa | - engine_method_ciphers | engine_method_digests | engine_method_store | - engine_method_pkey_meths | engine_method_pkey_asn1_meths + + + + + +

Contexts with an internal state that should not be manipulated but passed between function calls. +

+
+
-
+ + - block_encrypt(Type, Key, PlainText) -> CipherText + Encrypt PlainText according to Type block cipher - - Type = des_ecb | blowfish_ecb | aes_ecb - Key = block_key() - PlainText = iodata() - -

Encrypt PlainText according to Type block cipher.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

Encrypt PlainText according to Type block cipher.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths and blocksizes see the + User's Guide. +

- block_decrypt(Type, Key, CipherText) -> PlainText + Decrypt CipherText according to Type block cipher - - Type = des_ecb | blowfish_ecb | aes_ecb - Key = block_key() - PlainText = iodata() -

Decrypt CipherText according to Type block cipher.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths and blocksizes see the + User's Guide. +

@@ -251,10 +423,10 @@ block_encrypt(aes_gcm, Key, Ivec, {AAD, PlainText, TagLength}) -> {CipherText, CipherTag} Encrypt PlainText according to Type block cipher - Type = block_cipher() - AeadType = aead_cipher() - Key = block_key() - PlainText = iodata() + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() AAD = IVec = CipherText = CipherTag = binary() TagLength = 1..16 @@ -264,8 +436,11 @@

In AEAD (Authenticated Encryption with Associated Data) mode, encrypt PlainTextaccording to Type block cipher and calculate CipherTag that also authenticates the AAD (Associated Authenticated Data).

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

@@ -274,10 +449,10 @@ block_decrypt(AeadType, Key, Ivec, {AAD, CipherText, CipherTag}) -> PlainText | error Decrypt CipherText according to Type block cipher - Type = block_cipher() - AeadType = aead_cipher() - Key = block_key() - PlainText = iodata() + Type = block_cipher_with_iv() + AeadType = aead_cipher() + Key = key() | des3_key() + PlainText = iodata() AAD = IVec = CipherText = CipherTag = binary() @@ -287,19 +462,17 @@ CipherTextaccording to Type block cipher and check the authenticity the PlainText and AAD (Associated Authenticated Data) using the CipherTag. May return error if the decryption or validation fail's

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

+

For keylengths, iv-sizes and blocksizes see the + User's Guide. +

- bytes_to_integer(Bin) -> Integer + Convert binary representation, of an integer, to an Erlang integer. - - Bin = binary() - as returned by crypto functions - - Integer = integer() -

Convert binary representation, of an integer, to an Erlang integer.

@@ -307,17 +480,8 @@
- compute_key(Type, OthersPublicKey, MyKey, Params) -> SharedSecret + Computes the shared secret - - Type = dh | ecdh | srp - OthersPublicKey = dh_public() | ecdh_public() | srp_public() - MyKey = dh_private() | ecdh_private() | {srp_public(),srp_private()} - Params = dh_params() | ecdh_params() | ed_named_curves_ecdh() | SrpUserParams | SrpHostParams - SrpUserParams = {user, [DerivedKey::binary(), Prime::binary(), Generator::binary(), Version::atom() | [Scrambler:binary()]]} - SrpHostParams = {host, [Verifier::binary(), Prime::binary(), Version::atom() | [Scrambler::binary]]} - SharedSecret = binary() -

Computes the shared secret from the private key and the other party's public key. See also public_key:compute_key/2 @@ -326,85 +490,61 @@ - exor(Data1, Data2) -> Result + XOR data - - Data1, Data2 = iodata() - Result = binary() -

Performs bit-wise XOR (exclusive or) on the data supplied.

- - generate_key(Type, Params) -> {PublicKey, PrivKeyOut} - generate_key(Type, Params, PrivKeyIn) -> {PublicKey, PrivKeyOut} + + + + Generates a public key of type Type - - Type = dh | ecdh | rsa | srp - Params = dh_params() | ecdh_params() | ed_named_curves_ecdh()| RsaParams | SrpUserParams | SrpHostParams - RsaParams = {ModulusSizeInBits::integer(), PublicExponent::key_value()} - SrpUserParams = {user, [Generator::binary(), Prime::binary(), Version::atom()]} - SrpHostParams = {host, [Verifier::binary(), Generator::binary(), Prime::binary(), Version::atom()]} - PublicKey = dh_public() | ecdh_public() | rsa_public() | srp_public() - PrivKeyIn = undefined | dh_private() | ecdh_private() | srp_private() - PrivKeyOut = dh_private() | ecdh_private() | rsa_private() | srp_private() -

Generates a public key of type Type. See also public_key:generate_key/1. - May throw exception an exception of class error: + May raise exception:

- badarg: an argument is of wrong type or has an illegal value, - low_entropy: the random generator failed due to lack of secure "randomness", - computation_failed: the computation fails of another reason than low_entropy. + error:badarg: an argument is of wrong type or has an illegal value, + error:low_entropy: the random generator failed due to lack of secure "randomness", + error:computation_failed: the computation fails of another reason than low_entropy.

RSA key generation is only available if the runtime was built with dirty scheduler support. Otherwise, attempting to - generate an RSA key will throw exception error:notsup.

+ generate an RSA key will raise exception error:notsup.

- hash(Type, Data) -> Digest + - - Type = md4 | hash_algorithms() - Data = iodata() - Digest = binary() -

Computes a message digest of type Type from Data.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

- hash_init(Type) -> Context + - - Type = md4 | hash_algorithms() -

Initializes the context for streaming hash operations. Type determines which digest to use. The returned context should be used as argument to hash_update.

-

May throw exception notsup in case the chosen Type - is not supported by the underlying OpenSSL implementation.

+

May raise exception error:notsup in case the chosen Type + is not supported by the underlying libcrypto implementation.

- hash_update(Context, Data) -> NewContext + - - Data = iodata() -

Updates the digest represented by Context using the given Data. Context must have been generated using hash_init @@ -413,12 +553,10 @@ or hash_final.

+ - hash_final(Context) -> Digest + - - Digest = binary() -

Finalizes the hash operation referenced by Context returned from a previous call to hash_update. @@ -428,16 +566,9 @@ - hmac(Type, Key, Data) -> Mac - hmac(Type, Key, Data, MacLength) -> Mac + + - - Type = hash_algorithms() - except ripemd160 - Key = iodata() - Data = iodata() - MacLength = integer() - Mac = binary() -

Computes a HMAC of type Type from Data using Key as the authentication key.

MacLength @@ -446,13 +577,8 @@ - hmac_init(Type, Key) -> Context + - - Type = hash_algorithms() - except ripemd160 - Key = iodata() - Context = binary() -

Initializes the context for streaming HMAC operations. Type determines which hash function to use in the HMAC operation. Key is the authentication @@ -461,12 +587,8 @@ - hmac_update(Context, Data) -> NewContext + - - Context = NewContext = binary() - Data = iodata() -

Updates the HMAC represented by Context using the given Data. Context must have been generated using an HMAC init function (such as @@ -479,16 +601,13 @@ call to hmac_update or hmac_final. The semantics of reusing old contexts in any way is undefined and could even crash the VM in earlier releases. The reason for this limitation is a lack of support in the underlying - OpenSSL API.

+ libcrypto API.

- hmac_final(Context) -> Mac + - - Context = Mac = binary() -

Finalizes the HMAC operation referenced by Context. The size of the resultant MAC is determined by the type of hash function used to generate it.

@@ -496,12 +615,8 @@
- hmac_final_n(Context, HashLen) -> Mac + - - Context = Mac = binary() - HashLen = non_neg_integer() -

Finalizes the HMAC operation referenced by Context. HashLen must be greater than zero. Mac will be a binary with at most HashLen bytes. Note that if HashLen is greater than the actual number of bytes returned from the underlying hash, the returned hash will have fewer than HashLen bytes.

@@ -509,16 +624,9 @@
- cmac(Type, Key, Data) -> Mac - cmac(Type, Key, Data, MacLength) -> Mac + + Calculates the Cipher-based Message Authentication Code. - - Type = block_cipher() - Key = iodata() - Data = iodata() - MacLength = integer() - Mac = binary() -

Computes a CMAC of type Type from Data using Key as the authentication key.

MacLength @@ -527,20 +635,17 @@ - info_fips() -> Status + Provides information about the FIPS operating status. - - Status = enabled | not_enabled | not_supported -

Provides information about the FIPS operating status of - crypto and the underlying OpenSSL library. If crypto was built + crypto and the underlying libcrypto library. If crypto was built with FIPS support this can be either enabled (when running in FIPS mode) or not_enabled. For other builds this value is always not_supported.

In FIPS mode all non-FIPS compliant algorithms are - disabled and throw exception not_supported. Check + disabled and raise exception error:notsup. Check supports that in FIPS mode returns the restricted list of available algorithms.

@@ -549,13 +654,8 @@
- info_lib() -> [{Name,VerNum,VerStr}] + Provides information about the libraries used by crypto. - - Name = binary() - VerNum = integer() - VerStr = binary() -

Provides the name and version of the libraries used by crypto.

Name is the name of the library. VerNum is @@ -568,50 +668,36 @@

From OTP R16 the numeric version represents the version of the OpenSSL header files (openssl/opensslv.h) used when crypto was compiled. - The text variant represents the OpenSSL library used at runtime. + The text variant represents the libcrypto library used at runtime. In earlier OTP versions both numeric and text was taken from the library.

- mod_pow(N, P, M) -> Result + Computes the function: N^P mod M - - N, P, M = binary() | integer() - Result = binary() | error -

Computes the function N^P mod M.

- next_iv(Type, Data) -> NextIVec - next_iv(Type, Data, IVec) -> NextIVec - - - Type = des_cbc | des3_cbc | aes_cbc | des_cfb - Data = iodata() - IVec = NextIVec = binary() - - -

Returns the initialization vector to be used in the next - iteration of encrypt/decrypt of type Type. Data is the - encrypted data from the previous iteration step. The IVec - argument is only needed for des_cfb as the vector used - in the previous iteration step.

-
+ + + + +

Returns the initialization vector to be used in the next + iteration of encrypt/decrypt of type Type. Data is the + encrypted data from the previous iteration step. The IVec + argument is only needed for des_cfb as the vector used + in the previous iteration step.

+
- poly1305(Key, Data) -> Mac + - - Key = iodata() - Data = iodata() - Mac = binary() -

Computes a POLY1305 message authentication code (Mac) from Data using Key as the authentication key.

@@ -619,15 +705,8 @@
- private_decrypt(Type, CipherText, PrivateKey, Padding) -> PlainText + Decrypts CipherText using the private Key. - - Type = rsa - CipherText = binary() - PrivateKey = rsa_private() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding - PlainText = binary() -

Decrypts the CipherText, encrypted with public_encrypt/4 (or equivalent function) @@ -640,34 +719,8 @@ - privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey - Fetches a public key from an Engine stored private key. - - Type = rsa | dss - EnginePrivateKeyRef = engine_key_ref() - PublicKey = rsa_public() | dss_public() - - -

Fetches the corresponding public key from a private key stored in an Engine. - The key must be of the type indicated by the Type parameter. -

-
-
- - - private_encrypt(Type, PlainText, PrivateKey, Padding) -> CipherText + Encrypts PlainText using the private Key. - - Type = rsa - PlainText = binary() - The size of the PlainText must be less - than byte_size(N)-11 if rsa_pkcs1_padding is - used, and byte_size(N) if rsa_no_padding is - used, where N is public modulus of the RSA key. - PrivateKey = rsa_private() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_no_padding - CipherText = binary() -

Encrypts the PlainText using the PrivateKey and returns the ciphertext. This is a low level signature operation @@ -677,16 +730,10 @@

+ - public_decrypt(Type, CipherText, PublicKey, Padding) -> PlainText + Decrypts CipherText using the public Key. - - Type = rsa - CipherText = binary() - PublicKey = rsa_public() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_no_padding - PlainText = binary() -

Decrypts the CipherText, encrypted with private_encrypt/4(or equivalent function) @@ -699,19 +746,8 @@ - public_encrypt(Type, PlainText, PublicKey, Padding) -> CipherText + Encrypts PlainText using the public Key. - - Type = rsa - PlainText = binary() - The size of the PlainText must be less - than byte_size(N)-11 if rsa_pkcs1_padding is - used, and byte_size(N) if rsa_no_padding is - used, where N is public modulus of the RSA key. - PublicKey = rsa_public() | engine_key_ref() - Padding = rsa_pkcs1_padding | rsa_pkcs1_oaep_padding | rsa_no_padding - CipherText = binary() -

Encrypts the PlainText (message digest) using the PublicKey and returns the CipherText. This is a low level signature operation @@ -722,18 +758,15 @@ - rand_seed(Seed) -> ok + Set the seed for random bytes generation - - Seed = binary() -

Set the seed for PRNG to the given binary. This calls the RAND_seed function from openssl. Only use this if the system you are running on does not have enough "randomness" built in. Normally this is when strong_rand_bytes/1 - throws low_entropy

+ raises error:low_entropy

@@ -751,36 +784,15 @@
- sign(Algorithm, DigestType, Msg, Key) -> binary() - sign(Algorithm, DigestType, Msg, Key, Options) -> binary() - Create digital signature. - - Algorithm = rsa | dss | ecdsa - Msg = binary() | {digest,binary()} - The msg is either the binary "cleartext" data to be - signed or it is the hashed value of "cleartext" i.e. the - digest (plaintext). - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Key = rsa_private() | dss_private() | [ecdh_private(),ecdh_params()] | engine_key_ref() - Options = sign_options() - - -

Creates a digital signature.

-

Algorithm dss can only be used together with digest type - sha.

-

See also public_key:sign/3.

-
-
- - - start() -> ok + Equivalent to application:start(crypto).

Equivalent to application:start(crypto).

+ - stop() -> ok + Equivalent to application:stop(crypto).

Equivalent to application:stop(crypto).

@@ -788,23 +800,20 @@
- strong_rand_bytes(N) -> binary() + Generate a binary of random bytes - - N = integer() -

Generates N bytes randomly uniform 0..255, and returns the result in a binary. Uses a cryptographically secure prng seeded and periodically mixed with operating system provided entropy. By default this is the RAND_bytes method from OpenSSL.

-

May throw exception low_entropy in case the random generator +

May raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

- rand_seed() -> rand:state() + Strong random number generation plugin state

@@ -820,7 +829,7 @@

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

Example

@@ -832,7 +841,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[
- rand_seed_s() -> rand:state() + Strong random number generation plugin state

@@ -846,7 +855,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -885,7 +894,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -930,7 +939,7 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[

When using the state object from this function the rand functions using it - may throw exception low_entropy in case the random generator + may raise exception error:low_entropy in case the random generator failed due to lack of secure "randomness".

@@ -961,45 +970,36 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - stream_init(Type, Key) -> State + - - Type = rc4 - State = opaque() - Key = iodata() -

Initializes the state for use in RC4 stream encryption stream_encrypt and stream_decrypt

+

For keylengths see the + User's Guide. +

- stream_init(Type, Key, IVec) -> State + - - Type = aes_ctr | chacha20 - State = opaque() - Key = iodata() - IVec = binary() -

Initializes the state for use in streaming AES encryption using Counter mode (CTR). Key is the AES key and must be either 128, 192, or 256 bits long. IVec is an arbitrary initializing vector of 128 bits (16 bytes). This state is for use with stream_encrypt and stream_decrypt.

+

For keylengths and iv-sizes see the + User's Guide. +

- stream_encrypt(State, PlainText) -> { NewState, CipherText} + - - Text = iodata() - CipherText = binary() -

Encrypts PlainText according to the stream cipher Type specified in stream_init/3. Text can be any number of bytes. The initial State is created using @@ -1009,12 +1009,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - stream_decrypt(State, CipherText) -> { NewState, PlainText } + - - CipherText = iodata() - PlainText = binary() -

Decrypts CipherText according to the stream cipher Type specified in stream_init/3. PlainText can be any number of bytes. The initial State is created using @@ -1024,60 +1020,54 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - supports() -> AlgorithmList + Provide a list of available crypto algorithms. - - AlgorithmList = [{hashs, [hash_algorithms()]}, - {ciphers, [cipher_algorithms()]}, - {public_keys, [public_key_algorithms()]}, - {macs, [mac_algorithms()]}] - -

Can be used to determine which crypto algorithms that are supported - by the underlying OpenSSL library

+ by the underlying libcrypto library

- ec_curves() -> EllipticCurveList + Provide a list of available named elliptic curves. - - EllipticCurveList = [ec_named_curve()] -

Can be used to determine which named elliptic curves are supported.

- ec_curve(NamedCurve) -> EllipticCurve + Get the defining parameters of a elliptic curve. - - NamedCurve = ec_named_curve() - EllipticCurve = ec_explicit_curve() -

Return the defining parameters of a elliptic curve.

- - verify(Algorithm, DigestType, Msg, Signature, Key) -> boolean() - verify(Algorithm, DigestType, Msg, Signature, Key, Options) -> boolean() + + + + Create digital signature. + +

Creates a digital signature.

+

The msg is either the binary "cleartext" data to be + signed or it is the hashed value of "cleartext" i.e. the + digest (plaintext).

+

Algorithm dss can only be used together with digest type + sha.

+

See also public_key:sign/3.

+
+
+ + + + Verifies a digital signature. - - Algorithm = rsa | dss | ecdsa - Msg = binary() | {digest,binary()} - The msg is either the binary "cleartext" data - or it is the hashed value of "cleartext" i.e. the digest (plaintext). - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Signature = binary() - Key = rsa_public() | dss_public() | [ecdh_public(),ecdh_params()] | engine_key_ref() - Options = sign_options() -

Verifies a digital signature

+

The msg is either the binary "cleartext" data to be + signed or it is the hashed value of "cleartext" i.e. the + digest (plaintext).

Algorithm dss can only be used together with digest type sha.

@@ -1087,17 +1077,24 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_get_all_methods() -> Result + + Fetches a public key from an Engine stored private key. + +

Fetches the corresponding public key from a private key stored in an Engine. + The key must be of the type indicated by the Type parameter. +

+
+
+ + + Return list of all possible engine methods - - Result = [EngineMethod::atom()] -

Returns a list of all possible engine methods.

- May throw exception notsup in case there is + May raise exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1108,13 +1105,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_load(EngineId, PreCmds, PostCmds) -> Result + Dynamical load an encryption engine - - EngineId = unicode:chardata() - PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId if it is available and then returns ok and @@ -1123,8 +1115,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be loaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1135,22 +1127,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> Result + Dynamical load an encryption engine - - EngineId = unicode:chardata() - PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] - EngineMethods = [engine_method_type()] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId if it is available and then returns ok and an engine handle. An error tuple is returned if the engine can't be loaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1161,20 +1147,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_unload(Engine) -> Result + Dynamical load an encryption engine - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Unloads the OpenSSL engine given by Engine. An error tuple is returned if the engine can't be unloaded.

- The function throws a badarg if the parameter is in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameter is in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1185,20 +1167,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_by_id(EngineId) -> Result + Get a reference to an already loaded engine - - EngineID = unicode:chardata()engine_ref() - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Get a reference to an already loaded engine with EngineId. An error tuple is returned if the engine can't be unloaded.

- The function throws a badarg if the parameter is in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameter is in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1209,14 +1187,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - engine_ctrl_cmd_string(Engine, CmdName, CmdArg) -> Result + Sends ctrl commands to an OpenSSL engine - - Engine = engine_ref() - CmdName = unicode:chardata() - CmdArg = unicode:chardata() - Result = ok | {error, Reason::term()} -

Sends ctrl commands to the OpenSSL engine given by Engine. @@ -1224,23 +1196,16 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ Optional set to false.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) -> Result + Sends ctrl commands to an OpenSSL engine - - Engine = engine_ref() - CmdName = unicode:chardata() - CmdArg = unicode:chardata() - Optional = boolean() - Result = ok | {error, Reason::term()} -

Sends ctrl commands to the OpenSSL engine given by Engine. @@ -1252,91 +1217,72 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ false.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_add(Engine) -> Result + Add engine to OpenSSL internal list - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Add the engine to OpenSSL's internal list.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_remove(Engine) -> Result + Remove engine to OpenSSL internal list - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Remove the engine from OpenSSL's internal list.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_get_id(Engine) -> EngineId + Fetch engine ID - - Engine = engine_ref() - EngineId = unicode:chardata() -

Return the ID for the engine, or an empty binary if there is no id set.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_get_name(Engine) -> EngineName + Fetch engine name - - Engine = engine_ref() - EngineName = unicode:chardata() -

Return the name (eg a description) for the engine, or an empty binary if there is no name set.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

- engine_list() -> Result + List the known engine ids - - Result = [EngineId::unicode:chardata()] -

List the id's of all engines in OpenSSL's internal list.

- It may also throw the exception notsup in case there is + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1344,20 +1290,15 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ in the User's Guide.

- May throw exception notsup in case engine functionality is not supported by the underlying + May raise exception error:notsup in case engine functionality is not supported by the underlying OpenSSL implementation.

- ensure_engine_loaded(EngineId, LibPath) -> Result + Ensure encryption engine just loaded once - - EngineId = unicode:chardata() - LibPath = unicode:chardata() - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId and the path to the dynamic library @@ -1366,8 +1307,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be loaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1378,14 +1319,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_loaded(EngineId, LibPath, EngineMethods) -> Result + Ensure encryption engine just loaded once - - EngineId = unicode:chardata() - LibPath = unicode:chardata() - EngineMethods = [engine_method_type()] - Result = {ok, Engine::engine_ref()} | {error, Reason::term()} -

Loads the OpenSSL engine given by EngineId and the path to the dynamic library @@ -1395,8 +1330,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ An error tuple is returned if the engine can't be loaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1407,12 +1342,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_unloaded(Engine) -> Result + Unload an engine loaded with the ensure function - - Engine = engine_ref() - Result = ok | {error, Reason::term()} -

Unloads an engine loaded with the ensure_engine_loaded function. @@ -1422,8 +1353,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ returned if the engine can't be unloaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1434,13 +1365,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - ensure_engine_unloaded(Engine, EngineMethods) -> Result + Unload an engine loaded with the ensure function - - Engine = engine_ref() - EngineMethods = [engine_method_type()] - Result = ok | {error, Reason::term()} -

Unloads an engine loaded with the ensure_engine_loaded function. @@ -1448,8 +1374,8 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ An error tuple is returned if the engine can't be unloaded.

- The function throws a badarg if the parameters are in wrong format. - It may also throw the exception notsup in case there is + The function raises a error:badarg if the parameters are in wrong format. + It may also raise the exception error:notsup in case there is no engine support in the underlying OpenSSL implementation.

@@ -1461,75 +1387,5 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/lib/crypto/doc/src/engine_keys.xml b/lib/crypto/doc/src/engine_keys.xml index 38714fed8a..4f7b0243fb 100644 --- a/lib/crypto/doc/src/engine_keys.xml +++ b/lib/crypto/doc/src/engine_keys.xml @@ -62,7 +62,7 @@ on the Engine loaded an Erlang map is constructed with the Engine reference, the key reference and possibly a key passphrase if - needed by the Engine. See the Reference Manual for + needed by the Engine. See the Reference Manual for details of the map. -- cgit v1.2.3 From 882fa794883e6dbc0e56f22645cd3aec21920c53 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Fri, 7 Sep 2018 13:46:52 +0200 Subject: crypto: Add missing documentation for enable_fips_mode/1 --- lib/crypto/doc/src/crypto.xml | 21 ++++++++++++++++++++- lib/crypto/src/crypto.erl | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 9d436847ac..d5f5009297 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -642,7 +642,11 @@ crypto and the underlying libcrypto library. If crypto was built with FIPS support this can be either enabled (when running in FIPS mode) or not_enabled. For other builds - this value is always not_supported.

+ this value is always not_supported. +

+

See enable_fips_mode/1 about how to enable + FIPS mode. +

In FIPS mode all non-FIPS compliant algorithms are disabled and raise exception error:notsup. Check @@ -653,6 +657,21 @@ + + + Change FIPS mode. + +

Enables (Enable = true) or disables (Enable = false) FIPS mode. Returns true if + the operation was successful or false otherwise. +

+

Note that to enable FIPS mode succesfully, OTP must be built with the configure option --enable-fips, + and the underlying libcrypto must also support FIPS. +

+

See also info_fips/0. +

+
+
+ Provides information about the libraries used by crypto. diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl index a841f0f168..c64586897e 100644 --- a/lib/crypto/src/crypto.erl +++ b/lib/crypto/src/crypto.erl @@ -346,8 +346,8 @@ info_lib() -> ?nif_stub. info_fips() -> ?nif_stub. --spec enable_fips_mode(boolean()) -> boolean(). - +-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(), + Result :: boolean(). enable_fips_mode(_) -> ?nif_stub. %%%================================================================ -- cgit v1.2.3 From 5a67298324cc03454e659a1983fd7696451998aa Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 15:52:52 +0200 Subject: public_key: Remove special type signature for one test --- lib/public_key/test/public_key_SUITE.erl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl index cfd8e7a34b..1955e9e119 100644 --- a/lib/public_key/test/public_key_SUITE.erl +++ b/lib/public_key/test/public_key_SUITE.erl @@ -718,12 +718,8 @@ encrypt_decrypt(Config) when is_list(Config) -> Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")), RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey), Msg = public_key:decrypt_public(RsaEncrypted, PublicKey), - Msg = public_key:decrypt_public(RsaEncrypted, PrivateKey), RsaEncrypted2 = public_key:encrypt_public(Msg, PublicKey), - RsaEncrypted3 = public_key:encrypt_public(Msg, PrivateKey), Msg = public_key:decrypt_private(RsaEncrypted2, PrivateKey), - Msg = public_key:decrypt_private(RsaEncrypted3, PrivateKey), - ok. %%-------------------------------------------------------------------- -- cgit v1.2.3 From dce332fd4adca8e1ef1b54db69f14ec7186a3a44 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 15:59:37 +0200 Subject: public_key: Setup for doc generation --- lib/public_key/doc/specs/.gitignore | 1 + lib/public_key/doc/src/Makefile | 7 +++++++ lib/public_key/doc/src/specs.xml | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 lib/public_key/doc/specs/.gitignore create mode 100644 lib/public_key/doc/src/specs.xml diff --git a/lib/public_key/doc/specs/.gitignore b/lib/public_key/doc/specs/.gitignore new file mode 100644 index 0000000000..322eebcb06 --- /dev/null +++ b/lib/public_key/doc/specs/.gitignore @@ -0,0 +1 @@ +specs_*.xml diff --git a/lib/public_key/doc/src/Makefile b/lib/public_key/doc/src/Makefile index 03467e9783..8575b196b7 100644 --- a/lib/public_key/doc/src/Makefile +++ b/lib/public_key/doc/src/Makefile @@ -77,12 +77,18 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf +SPECS_FILES = $(XML_REF3_FILES:%.xml=$(SPECDIR)/specs_%.xml) + +TOP_SPECS_FILE = specs.xml + # ---------------------------------------------------- # FLAGS # ---------------------------------------------------- XML_FLAGS += DVIPS_FLAGS += +SPECS_FLAGS = -I../../include -I../../src -I../../.. + # ---------------------------------------------------- # Targets # ---------------------------------------------------- @@ -103,6 +109,7 @@ clean clean_docs: rm -f $(MAN3DIR)/* rm -f $(MAN6DIR)/* rm -f $(TOP_PDF_FILE) $(TOP_PDF_FILE:%.pdf=%.fo) + rm -f $(SPECS_FILES) rm -f errs core *~ man: $(MAN3_FILES) $(MAN6_FILES) diff --git a/lib/public_key/doc/src/specs.xml b/lib/public_key/doc/src/specs.xml new file mode 100644 index 0000000000..e358ea1154 --- /dev/null +++ b/lib/public_key/doc/src/specs.xml @@ -0,0 +1,4 @@ + + + + -- cgit v1.2.3 From 2920aa71a9163ea495e896264daa1b56bd845d12 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Tue, 28 Aug 2018 16:01:19 +0200 Subject: public_key: Rework -type and -spec Check existing specs with code and documentation and adjust. Prepare for doc generation --- lib/public_key/src/public_key.erl | 439 +++++++++++++++++++++++--------------- 1 file changed, 269 insertions(+), 170 deletions(-) diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl index 3704503f1e..3f609ce6c6 100644 --- a/lib/public_key/src/public_key.erl +++ b/lib/public_key/src/public_key.erl @@ -76,7 +76,7 @@ -type dsa_private_key() :: #'DSAPrivateKey'{}. -type dsa_public_key() :: {integer(), #'Dss-Parms'{}}. -type ecpk_parameters() :: {ecParameters, #'ECParameters'{}} | {namedCurve, Oid::tuple()}. --type ecpk_parameters_api() :: ecpk_parameters() | #'ECParameters'{} | {namedCurve, Name::atom()}. +-type ecpk_parameters_api() :: ecpk_parameters() | #'ECParameters'{} | {namedCurve, Name::crypto:ec_named_curve()}. -type ec_public_key() :: {#'ECPoint'{}, ecpk_parameters_api()}. -type ec_private_key() :: #'ECPrivateKey'{}. -type key_params() :: #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} | @@ -88,28 +88,41 @@ 'CertificationRequest' | 'CertificateList' | 'ECPrivateKey' | 'EcpkParameters'. -type pem_entry() :: {pki_asn1_type(), - binary(), %% DER or Encrypted DER - not_encrypted | {Cipher :: string(), Salt :: binary()} | - {Cipher :: string(), #'PBES2-params'{}} | - {Cipher :: string(), {#'PBEParameter'{}, atom()}} %% hash type + der_or_encrypted_der(), + not_encrypted | cipher_info() }. +-type der_or_encrypted_der() :: binary(). +-type cipher_info() :: {cipher(), + cipher_info_params()} . +-type cipher() :: string() . % "RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC", +-type cipher_info_params() :: salt() + | {#'PBEParameter'{}, digest_type()} + | #'PBES2-params'{} . + +-type salt() :: binary(). % crypto:strong_rand_bytes(8) +%% -type cipher_info() :: {Cipher :: string(), Salt :: binary()} | +%% {Cipher :: string(), #'PBES2-params'{}} | +%% {Cipher :: string(), {#'PBEParameter'{}, atom()}} %% hash type +%% . + -type asn1_type() :: atom(). %% see "OTP-PUB-KEY.hrl -type ssh_file() :: openssh_public_key | rfc4716_public_key | known_hosts | auth_keys. --type rsa_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_oaep_padding' - | 'rsa_no_padding'. --type rsa_sign_padding() :: 'rsa_pkcs1_padding' | 'rsa_pkcs1_pss_padding'. --type public_crypt_options() :: [{rsa_pad, rsa_padding()}]. --type rsa_digest_type() :: 'md5' | 'ripemd160' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. --type dss_digest_type() :: 'none' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. %% None is for backwards compatibility --type ecdsa_digest_type() :: 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'. --type public_sign_options() :: [{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}]. --type digest_type() :: rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(). +-type digest_type() :: none % None is for backwards compatibility + | crypto:rsa_digest_type() + | crypto:dss_digest_type() + | crypto:ecdsa_digest_type(). -type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded | cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise. -type oid() :: tuple(). -type chain_type() :: server_chain | client_chain. +-type issuer_id() :: {SerialNr::integer(), issuer_name()} . + +-type issuer_name() :: {rdnSequence,[#'AttributeTypeAndValue'{}]} . + + + -define(UINT32(X), X:32/unsigned-big-integer). -define(DER_NULL, <<5, 0>>). @@ -134,11 +147,11 @@ pem_encode(PemEntries) when is_list(PemEntries) -> iolist_to_binary(pubkey_pem:encode(PemEntries)). %%-------------------------------------------------------------------- --spec pem_entry_decode(pem_entry(), string()) -> term(). -% %% Description: Decodes a pem entry. pem_decode/1 returns a list of %% pem entries. %%-------------------------------------------------------------------- +-spec pem_entry_decode(PemEntry) -> term() when PemEntry :: pem_entry() . + pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> {_, {'AlgorithmIdentifier', AlgId, Params}, Key0} = der_decode('SubjectPublicKeyInfo', Der), @@ -156,6 +169,9 @@ pem_entry_decode({'SubjectPublicKeyInfo', Der, _}) -> pem_entry_decode({Asn1Type, Der, not_encrypted}) when is_atom(Asn1Type), is_binary(Der) -> der_decode(Asn1Type, Der). + +-spec pem_entry_decode(PemEntry, Password) -> term() when PemEntry :: pem_entry(), + Password :: string() . pem_entry_decode({Asn1Type, Der, not_encrypted}, _) when is_atom(Asn1Type), is_binary(Der) -> der_decode(Asn1Type, Der); @@ -181,11 +197,12 @@ pem_entry_decode({Asn1Type, CryptDer, {Cipher, Salt}} = PemEntry, %%-------------------------------------------------------------------- --spec pem_entry_encode(pki_asn1_type(), term()) -> pem_entry(). --spec pem_entry_encode(pki_asn1_type(), term(), term()) -> pem_entry(). %% %% Description: Creates a pem entry that can be feed to pem_encode/1. %%-------------------------------------------------------------------- +-spec pem_entry_encode(Asn1Type, Entity) -> pem_entry() when Asn1Type :: pki_asn1_type(), + Entity :: term() . + pem_entry_encode('SubjectPublicKeyInfo', Entity=#'RSAPublicKey'{}) -> Der = der_encode('RSAPublicKey', Entity), Spki = {'SubjectPublicKeyInfo', @@ -208,6 +225,13 @@ pem_entry_encode('SubjectPublicKeyInfo', pem_entry_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> Der = der_encode(Asn1Type, Entity), {Asn1Type, Der, not_encrypted}. + +-spec pem_entry_encode(Asn1Type, Entity, InfoPwd) -> + pem_entry() when Asn1Type :: pki_asn1_type(), + Entity :: term(), + InfoPwd :: {CipherInfo,Password}, + CipherInfo :: cipher_info(), + Password :: string() . pem_entry_encode(Asn1Type, Entity, {{Cipher, #'PBES2-params'{}} = CipherInfo, Password}) when is_atom(Asn1Type) andalso is_list(Password) andalso @@ -229,7 +253,9 @@ pem_entry_encode(Asn1Type, Entity, {{Cipher, Salt} = CipherInfo, do_pem_entry_encode(Asn1Type, Entity, CipherInfo, Password). %%-------------------------------------------------------------------- --spec der_decode(asn1_type(), Der::binary()) -> term(). +-spec der_decode(Asn1Type, Der) -> Entity when Asn1Type :: asn1_type(), + Der :: binary(), + Entity :: term(). %% %% Description: Decodes a public key asn1 der encoded entity. %%-------------------------------------------------------------------- @@ -269,7 +295,9 @@ der_priv_key_decode(PKCS8Key) -> PKCS8Key. %%-------------------------------------------------------------------- --spec der_encode(asn1_type(), term()) -> Der::binary(). +-spec der_encode(Asn1Type, Entity) -> Der when Asn1Type :: asn1_type(), + Entity :: term(), + Der :: binary() . %% %% Description: Encodes a public key entity with asn1 DER encoding. %%-------------------------------------------------------------------- @@ -311,8 +339,10 @@ der_encode(Asn1Type, Entity) when is_atom(Asn1Type) -> end. %%-------------------------------------------------------------------- --spec pkix_decode_cert(Cert::binary(), plain | otp) -> - #'Certificate'{} | #'OTPCertificate'{}. +-spec pkix_decode_cert(Cert, Type) -> + #'Certificate'{} | #'OTPCertificate'{} + when Cert :: der_encoded(), + Type :: plain | otp . %% %% Description: Decodes an asn1 der encoded pkix certificate. The otp %% option will use the customized asn1 specification OTP-PKIX.asn1 for @@ -332,7 +362,11 @@ pkix_decode_cert(DerCert, otp) when is_binary(DerCert) -> end. %%-------------------------------------------------------------------- --spec pkix_encode(asn1_type(), term(), otp | plain) -> Der::binary(). +-spec pkix_encode(Asn1Type, Entity, Type) -> Der + when Asn1Type :: asn1_type(), + Entity :: term(), + Type :: otp | plain, + Der :: der_encoded() . %% %% Description: Der encodes a certificate or part of a certificate. %% This function must be used for encoding certificates or parts of certificates @@ -347,16 +381,21 @@ pkix_encode(Asn1Type, Term0, otp) when is_atom(Asn1Type) -> der_encode(Asn1Type, Term). %%-------------------------------------------------------------------- --spec decrypt_private(CipherText :: binary(), rsa_private_key()) -> - PlainText :: binary(). --spec decrypt_private(CipherText :: binary(), rsa_private_key(), - public_crypt_options()) -> PlainText :: binary(). %% %% Description: Public key decryption using the private key. %%-------------------------------------------------------------------- +-spec decrypt_private(CipherText, Key) -> + PlainText when CipherText :: binary(), + Key :: rsa_private_key(), + PlainText :: binary() . decrypt_private(CipherText, Key) -> decrypt_private(CipherText, Key, []). +-spec decrypt_private(CipherText, Key, Options) -> + PlainText when CipherText :: binary(), + Key :: rsa_private_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + PlainText :: binary() . decrypt_private(CipherText, #'RSAPrivateKey'{} = Key, Options) @@ -366,61 +405,69 @@ decrypt_private(CipherText, crypto:private_decrypt(rsa, CipherText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- --spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key()) -> - PlainText :: binary(). --spec decrypt_public(CipherText :: binary(), rsa_public_key() | rsa_private_key(), - public_crypt_options()) -> PlainText :: binary(). -%% NOTE: The rsa_private_key() is not part of the documented API it is -%% here for testing purposes, in a real situation this is not a relevant -%% thing to do. -%% %% Description: Public key decryption using the public key. %%-------------------------------------------------------------------- +-spec decrypt_public(CipherText, Key) -> + PlainText + when CipherText :: binary(), + Key :: rsa_public_key(), + PlainText :: binary() . decrypt_public(CipherText, Key) -> decrypt_public(CipherText, Key, []). +-spec decrypt_public(CipherText, Key, Options) -> + PlainText + when CipherText :: binary(), + Key :: rsa_public_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + PlainText :: binary() . decrypt_public(CipherText, #'RSAPublicKey'{modulus = N, publicExponent = E}, Options) when is_binary(CipherText), is_list(Options) -> - decrypt_public(CipherText, N,E, Options); - -decrypt_public(CipherText,#'RSAPrivateKey'{modulus = N, publicExponent = E}, - Options) when is_binary(CipherText), is_list(Options) -> - decrypt_public(CipherText, N,E, Options). + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:public_decrypt(rsa, CipherText,[E, N], Padding). %%-------------------------------------------------------------------- --spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key()) -> - CipherText :: binary(). --spec encrypt_public(PlainText :: binary(), rsa_public_key() | rsa_private_key(), - public_crypt_options()) -> CipherText :: binary(). - -%% NOTE: The rsa_private_key() is not part of the documented API it is -%% here for testing purposes, in a real situation this is not a relevant -%% thing to do. -%% %% Description: Public key encryption using the public key. %%-------------------------------------------------------------------- +-spec encrypt_public(PlainText, Key) -> + CipherText + when PlainText :: binary(), + Key :: rsa_public_key(), + CipherText :: binary() . encrypt_public(PlainText, Key) -> encrypt_public(PlainText, Key, []). -encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, - Options) when is_binary(PlainText), is_list(Options) -> - encrypt_public(PlainText, N,E, Options); -encrypt_public(PlainText, #'RSAPrivateKey'{modulus=N,publicExponent=E}, +-spec encrypt_public(PlainText, Key, Options) -> + CipherText + when PlainText :: binary(), + Key :: rsa_public_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + CipherText :: binary() . +encrypt_public(PlainText, #'RSAPublicKey'{modulus=N,publicExponent=E}, Options) when is_binary(PlainText), is_list(Options) -> - encrypt_public(PlainText, N,E, Options). + Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), + crypto:public_encrypt(rsa, PlainText, [E,N], Padding). %%-------------------------------------------------------------------- --spec encrypt_private(PlainText :: binary(), rsa_private_key()) -> - CipherText :: binary(). --spec encrypt_private(PlainText :: binary(), rsa_private_key(), - public_crypt_options()) -> CipherText :: binary(). %% %% Description: Public key encryption using the private key. %%-------------------------------------------------------------------- +-spec encrypt_private(PlainText, Key) -> + CipherText + when PlainText :: binary(), + Key :: rsa_private_key(), + CipherText :: binary() . encrypt_private(PlainText, Key) -> encrypt_private(PlainText, Key, []). + +-spec encrypt_private(PlainText, Key, Options) -> + CipherText + when PlainText :: binary(), + Key :: rsa_private_key(), + Options :: crypto:pk_encrypt_decrypt_opts(), + CipherText :: binary() . encrypt_private(PlainText, #'RSAPrivateKey'{modulus = N, publicExponent = E, privateExponent = D} = Key, @@ -432,22 +479,42 @@ encrypt_private(PlainText, crypto:private_encrypt(rsa, PlainText, format_rsa_private_key(Key), Padding). %%-------------------------------------------------------------------- +%% Description: List available group sizes among the pre-computed dh groups +%%-------------------------------------------------------------------- +-spec dh_gex_group_sizes() -> [pos_integer()]. dh_gex_group_sizes() -> pubkey_ssh:dh_gex_group_sizes(). +%%-------------------------------------------------------------------- +%% Description: Select a precomputed group +%%-------------------------------------------------------------------- +-spec dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> + {ok,{Size,Group}} | {error,term()} + when MinSize :: pos_integer(), + SuggestedSize :: pos_integer(), + MaxSize :: pos_integer(), + Groups :: undefined | [{Size,[Group]}], + Size :: pos_integer(), + Group :: {G,P}, + G :: pos_integer(), + P :: pos_integer() . dh_gex_group(Min, N, Max, Groups) -> pubkey_ssh:dh_gex_group(Min, N, Max, Groups). %%-------------------------------------------------------------------- --spec generate_key(#'DHParameter'{}) -> - {Public::binary(), Private::binary()}; - (ecpk_parameters_api()) -> - #'ECPrivateKey'{}; - ({rsa, Size::pos_integer(), PubExp::pos_integer()}) -> - #'RSAPrivateKey'{}. - -%% Description: Generates a new keypair +%% Description: Generate a new key pair %%-------------------------------------------------------------------- +-spec generate_key(DHparams | ECparams | RSAparams) -> + DHkeys | ECkey | RSAkey + when DHparams :: #'DHParameter'{}, + DHkeys :: {PublicDH::binary(), PrivateDH::binary()}, + ECparams :: ecpk_parameters_api(), + ECkey :: #'ECPrivateKey'{}, + RSAparams :: {rsa, Size, PubExp}, + Size::pos_integer(), + PubExp::pos_integer(), + RSAkey :: #'RSAPrivateKey'{} . + generate_key(#'DHParameter'{prime = P, base = G}) -> crypto:generate_key(dh, [P, G]); generate_key({namedCurve, _} = Params) -> @@ -494,24 +561,34 @@ generate_key({rsa, ModulusSize, PublicExponent}) -> end. %%-------------------------------------------------------------------- --spec compute_key(#'ECPoint'{} , #'ECPrivateKey'{}) -> binary(). --spec compute_key(OthersKey ::binary(), MyKey::binary(), #'DHParameter'{}) -> binary(). %% Description: Compute shared secret %%-------------------------------------------------------------------- +-spec compute_key(OthersECDHkey, MyECDHkey) -> + SharedSecret + when OthersECDHkey :: #'ECPoint'{}, + MyECDHkey :: #'ECPrivateKey'{}, + SharedSecret :: binary(). compute_key(#'ECPoint'{point = Point}, #'ECPrivateKey'{privateKey = PrivKey, parameters = Param}) -> ECCurve = ec_curve_spec(Param), crypto:compute_key(ecdh, Point, PrivKey, ECCurve). +-spec compute_key(OthersDHkey, MyDHkey, DHparms) -> + SharedSecret + when OthersDHkey :: crypto:dh_public(), % Was: binary(), + MyDHkey :: crypto:dh_private(), % Was: binary(), + DHparms :: #'DHParameter'{}, + SharedSecret :: binary(). compute_key(PubKey, PrivKey, #'DHParameter'{prime = P, base = G}) -> crypto:compute_key(dh, PubKey, PrivKey, [P, G]). %%-------------------------------------------------------------------- --spec pkix_sign_types(SignatureAlg::oid()) -> - %% Relevant dsa digest type is subpart of rsa digest type - { DigestType :: rsa_digest_type(), - SignatureType :: rsa | dsa | ecdsa - }. +-spec pkix_sign_types(AlgorithmId) -> + {DigestType, SignatureType} + when AlgorithmId :: oid(), + %% Relevant dsa digest type is a subset of rsa_digest_type() + DigestType :: crypto:rsa_digest_type(), + SignatureType :: rsa | dsa | ecdsa . %% Description: %%-------------------------------------------------------------------- pkix_sign_types(?sha1WithRSAEncryption) -> @@ -542,24 +619,24 @@ pkix_sign_types(?'ecdsa-with-SHA512') -> {sha512, ecdsa}. %%-------------------------------------------------------------------- --spec sign(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - rsa_private_key() | dsa_private_key() | ec_private_key() - ) -> Signature :: binary(). - --spec sign(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - rsa_private_key() | dsa_private_key() | ec_private_key(), - public_sign_options() - ) -> Signature :: binary(). - %% Description: Create digital signature. %%-------------------------------------------------------------------- +-spec sign(Msg, DigestType, Key) -> + Signature when Msg :: binary() | {digest,binary()}, + DigestType :: digest_type(), + Key :: private_key(), + Signature :: binary() . sign(DigestOrPlainText, DigestType, Key) -> sign(DigestOrPlainText, DigestType, Key, []). -%% Backwards compatible +-spec sign(Msg, DigestType, Key, Options) -> + Signature when Msg :: binary() | {digest,binary()}, + DigestType :: digest_type(), + Key :: private_key(), + Options :: crypto:pk_sign_verify_opts(), + Signature :: binary() . sign(Digest, none, Key = #'DSAPrivateKey'{}, Options) when is_binary(Digest) -> + %% Backwards compatible sign({digest, Digest}, sha, Key, Options); sign(DigestOrPlainText, DigestType, Key, Options) -> case format_sign_key(Key) of @@ -570,28 +647,26 @@ sign(DigestOrPlainText, DigestType, Key, Options) -> end. %%-------------------------------------------------------------------- --spec verify(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - Signature :: binary(), - rsa_public_key() | dsa_public_key() | ec_public_key() - | rsa_private_key() | dsa_private_key() | ec_private_key() - ) -> boolean(). - --spec verify(binary() | {digest, binary()}, - rsa_digest_type() | dss_digest_type() | ecdsa_digest_type(), - Signature :: binary(), - rsa_public_key() | dsa_public_key() | ec_public_key() - | rsa_private_key() | dsa_private_key() | ec_private_key(), - public_sign_options() - ) -> boolean(). - %% Description: Verifies a digital signature. %%-------------------------------------------------------------------- +-spec verify(Msg, DigestType, Signature, Key) -> + boolean() when Msg :: binary() | {digest, binary()}, + DigestType :: digest_type(), + Signature :: binary(), + Key :: public_key() . + verify(DigestOrPlainText, DigestType, Signature, Key) -> verify(DigestOrPlainText, DigestType, Signature, Key, []). -%% Backwards compatible +-spec verify(Msg, DigestType, Signature, Key, Options) -> + boolean() when Msg :: binary() | {digest, binary()}, + DigestType :: digest_type(), + Signature :: binary(), + Key :: public_key(), + Options :: crypto:pk_sign_verify_opts(). + verify(Digest, none, Signature, Key = {_, #'Dss-Parms'{}}, Options) when is_binary(Digest) -> + %% Backwards compatible verify({digest, Digest}, sha, Signature, Key, Options); verify(DigestOrPlainText, DigestType, Signature, Key, Options) when is_binary(Signature) -> case format_verify_key(Key) of @@ -606,8 +681,8 @@ verify(_,_,_,_,_) -> false. %%-------------------------------------------------------------------- --spec pkix_dist_point(der_encoded() | #'OTPCertificate'{}) -> - #'DistributionPoint'{}. +-spec pkix_dist_point(Cert) -> DistPoint when Cert :: der_encoded() | #'OTPCertificate'{}, + DistPoint :: #'DistributionPoint'{}. %% Description: Creates a distribution point for CRLs issued by the same issuer as Cert. %%-------------------------------------------------------------------- pkix_dist_point(OtpCert) when is_binary(OtpCert) -> @@ -630,8 +705,8 @@ pkix_dist_point(OtpCert) -> reasons = asn1_NOVALUE, distributionPoint = Point}. %%-------------------------------------------------------------------- --spec pkix_dist_points(der_encoded() | #'OTPCertificate'{}) -> - [#'DistributionPoint'{}]. +-spec pkix_dist_points(Cert) -> DistPoints when Cert :: der_encoded() | #'OTPCertificate'{}, + DistPoints :: [ #'DistributionPoint'{} ]. %% Description: Extracts distributionpoints specified in the certificates extensions. %%-------------------------------------------------------------------- pkix_dist_points(OtpCert) when is_binary(OtpCert) -> @@ -645,8 +720,10 @@ pkix_dist_points(OtpCert) -> [], Value). %%-------------------------------------------------------------------- --spec pkix_match_dist_point(der_encoded() | #'CertificateList'{}, - #'DistributionPoint'{}) -> boolean(). +-spec pkix_match_dist_point(CRL, DistPoint) -> + boolean() + when CRL :: der_encoded() | #'CertificateList'{}, + DistPoint :: #'DistributionPoint'{}. %% Description: Check whether the given distribution point matches %% the "issuing distribution point" of the CRL. %%-------------------------------------------------------------------- @@ -677,8 +754,9 @@ pkix_match_dist_point(#'CertificateList'{ end. %%-------------------------------------------------------------------- --spec pkix_sign(#'OTPTBSCertificate'{}, - rsa_private_key() | dsa_private_key() | ec_private_key()) -> Der::binary(). +-spec pkix_sign(Cert, Key) -> Der when Cert :: #'OTPTBSCertificate'{}, + Key :: private_key(), + Der :: der_encoded() . %% %% Description: Sign a pkix x.509 certificate. Returns the corresponding %% der encoded 'Certificate'{} @@ -697,8 +775,8 @@ pkix_sign(#'OTPTBSCertificate'{signature = pkix_encode('OTPCertificate', Cert, otp). %%-------------------------------------------------------------------- --spec pkix_verify(Cert::binary(), rsa_public_key()| - dsa_public_key() | ec_public_key()) -> boolean(). +-spec pkix_verify(Cert, Key) -> boolean() when Cert :: der_encoded(), + Key :: public_key() . %% %% Description: Verify pkix x.509 certificate signature. %%-------------------------------------------------------------------- @@ -718,7 +796,9 @@ pkix_verify(DerCert, Key = {#'ECPoint'{}, _}) verify(PlainText, DigestType, Signature, Key). %%-------------------------------------------------------------------- --spec pkix_crl_verify(CRL::binary() | #'CertificateList'{}, Cert::binary() | #'OTPCertificate'{}) -> boolean(). +-spec pkix_crl_verify(CRL, Cert) -> boolean() + when CRL :: der_encoded() | #'CertificateList'{}, + Cert :: der_encoded() | #'OTPCertificate'{} . %% %% Description: Verify that Cert is the CRL signer. %%-------------------------------------------------------------------- @@ -737,9 +817,12 @@ pkix_crl_verify(#'CertificateList'{} = CRL, #'OTPCertificate'{} = Cert) -> PublicKey, PublicKeyParams). %%-------------------------------------------------------------------- --spec pkix_is_issuer(Cert :: der_encoded()| #'OTPCertificate'{} | #'CertificateList'{}, - IssuerCert :: der_encoded()| - #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_issuer(Cert, IssuerCert) -> + boolean() when Cert :: der_encoded() + | #'OTPCertificate'{} + | #'CertificateList'{}, + IssuerCert :: der_encoded() + | #'OTPCertificate'{} . %% %% Description: Checks if issued . %%-------------------------------------------------------------------- @@ -759,7 +842,7 @@ pkix_is_issuer(#'CertificateList'{tbsCertList = TBSCRL}, pubkey_cert_records:transform(TBSCRL#'TBSCertList'.issuer, decode)). %%-------------------------------------------------------------------- --spec pkix_is_self_signed(Cert::binary()| #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_self_signed(Cert) -> boolean() when Cert::der_encoded()| #'OTPCertificate'{}. %% %% Description: Checks if a Certificate is self signed. %%-------------------------------------------------------------------- @@ -770,7 +853,7 @@ pkix_is_self_signed(Cert) when is_binary(Cert) -> pkix_is_self_signed(OtpCert). %%-------------------------------------------------------------------- --spec pkix_is_fixed_dh_cert(Cert::binary()| #'OTPCertificate'{}) -> boolean(). +-spec pkix_is_fixed_dh_cert(Cert) -> boolean() when Cert::der_encoded()| #'OTPCertificate'{}. %% %% Description: Checks if a Certificate is a fixed Diffie-Hellman Cert. %%-------------------------------------------------------------------- @@ -781,13 +864,12 @@ pkix_is_fixed_dh_cert(Cert) when is_binary(Cert) -> pkix_is_fixed_dh_cert(OtpCert). %%-------------------------------------------------------------------- --spec pkix_issuer_id(Cert::binary()| #'OTPCertificate'{}, - IssuedBy :: self | other) -> - {ok, {SerialNr :: integer(), - Issuer :: {rdnSequence, - [#'AttributeTypeAndValue'{}]}}} - | {error, Reason :: term()}. -% +-spec pkix_issuer_id(Cert, IssuedBy) -> + {ok, issuer_id()} | {error, Reason} + when Cert::der_encoded()| #'OTPCertificate'{}, + IssuedBy :: self | other, + Reason :: term() . + %% Description: Returns the issuer id. %%-------------------------------------------------------------------- pkix_issuer_id(#'OTPCertificate'{} = OtpCert, Signed) when (Signed == self) or @@ -798,9 +880,9 @@ pkix_issuer_id(Cert, Signed) when is_binary(Cert) -> pkix_issuer_id(OtpCert, Signed). %%-------------------------------------------------------------------- --spec pkix_crl_issuer(CRL::binary()| #'CertificateList'{}) -> - {rdnSequence, - [#'AttributeTypeAndValue'{}]}. +-spec pkix_crl_issuer(CRL| #'CertificateList'{}) -> + Issuer when CRL :: der_encoded(), + Issuer :: issuer_name() . % %% Description: Returns the issuer. %%-------------------------------------------------------------------- @@ -811,10 +893,9 @@ pkix_crl_issuer(#'CertificateList'{} = CRL) -> CRL#'CertificateList'.tbsCertList#'TBSCertList'.issuer, decode). %%-------------------------------------------------------------------- --spec pkix_normalize_name({rdnSequence, - [#'AttributeTypeAndValue'{}]}) -> - {rdnSequence, - [#'AttributeTypeAndValue'{}]}. +-spec pkix_normalize_name(Issuer) -> Normalized + when Issuer :: issuer_name(), + Normalized :: issuer_name() . %% %% Description: Normalizes a issuer name so that it can be easily %% compared to another issuer name. @@ -825,7 +906,7 @@ pkix_normalize_name(Issuer) -> %%-------------------------------------------------------------------- -spec pkix_path_validation(Cert::binary()| #'OTPCertificate'{} | atom(), CertChain :: [binary()] , - Options :: proplists:proplist()) -> + Options :: [{atom(),term()}]) -> {ok, {PublicKeyInfo :: term(), PolicyTree :: term()}} | {error, {bad_cert, Reason :: term()}}. @@ -861,11 +942,19 @@ pkix_path_validation(#'OTPCertificate'{} = TrustedCert, CertChain, Options) path_validation(CertChain, ValidationState). %-------------------------------------------------------------------- --spec pkix_crls_validate(#'OTPCertificate'{}, - [{DP::#'DistributionPoint'{}, {DerCRL::binary(), CRL::#'CertificateList'{}}}], - Options :: proplists:proplist()) -> valid | {bad_cert, revocation_status_undetermined} | - {bad_cert, {revocation_status_undetermined, Reason::term()}} | - {bad_cert, {revoked, crl_reason()}}. +-spec pkix_crls_validate(OTPcertificate, DPandCRLs, Options) -> + CRLstatus when OTPcertificate :: #'OTPCertificate'{}, + DPandCRLs :: [DPandCRL], + DPandCRL :: {DP, {DerCRL, CRL}}, + DP :: #'DistributionPoint'{}, + DerCRL :: der_encoded(), + CRL :: #'CertificateList'{}, + Options :: [{atom(),term()}], + CRLstatus :: valid + | {bad_cert, BadCertReason}, + BadCertReason :: revocation_status_undetermined + | {revocation_status_undetermined, Reason::term()} + | {revoked, crl_reason()}. %% Description: Performs a CRL validation according to RFC 5280. %%-------------------------------------------------------------------- @@ -882,20 +971,10 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) -> Options, pubkey_crl:init_revokation_state()). %-------------------------------------------------------------------- --spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), - referenceIDs() - ) -> boolean(). - --spec pkix_verify_hostname(#'OTPCertificate'{} | binary(), - referenceIDs(), - proplists:proplist()) -> boolean(). - -type referenceIDs() :: [referenceID()] . -type referenceID() :: {uri_id | dns_id | ip | srv_id | oid(), string()} | {ip, inet:ip_address()} . --spec pkix_verify_hostname_match_fun(high_level_alg()) -> match_fun() . - -type high_level_alg() :: https . -type match_fun() :: fun((ReferenceID::referenceID() | string(), PresentedID::{atom()|oid(),string()}) -> match_fun_result() ) . @@ -903,9 +982,20 @@ pkix_crls_validate(OtpCert, DPAndCRLs0, Options) -> %% Description: Validates a hostname to RFC 6125 %%-------------------------------------------------------------------- +-spec pkix_verify_hostname(Cert, ReferenceIDs) -> boolean() + when Cert :: der_encoded() + | #'OTPCertificate'{}, + ReferenceIDs :: referenceIDs() . pkix_verify_hostname(Cert, ReferenceIDs) -> pkix_verify_hostname(Cert, ReferenceIDs, []). +-spec pkix_verify_hostname(Cert, ReferenceIDs, Options) -> + boolean() + when Cert :: der_encoded() + | #'OTPCertificate'{}, + ReferenceIDs :: referenceIDs(), + Options :: [{atom(),term()}] . + pkix_verify_hostname(BinCert, ReferenceIDs, Options) when is_binary(BinCert) -> pkix_verify_hostname(pkix_decode_cert(BinCert,otp), ReferenceIDs, Options); @@ -964,15 +1054,25 @@ pkix_verify_hostname(Cert = #'OTPCertificate'{tbsCertificate = TbsCert}, Referen end end. + +-spec pkix_verify_hostname_match_fun(high_level_alg()) -> match_fun() . + pkix_verify_hostname_match_fun(https) -> fun({dns_id,FQDN=[_|_]}, {dNSName,Name=[_|_]}) -> verify_hostname_match_wildcard(FQDN, Name); (_, _) -> default end. %%-------------------------------------------------------------------- --spec ssh_decode(binary(), public_key | ssh_file()) -> [{public_key(), Attributes::list()}] - ; (binary(), ssh2_pubkey) -> public_key() - . +-spec ssh_decode(SshBin, Type) -> + Decoded + when SshBin :: binary(), + Type :: ssh2_pubkey | OtherType, + OtherType :: public_key | ssh_file(), + Decoded :: Decoded_ssh2_pubkey + | Decoded_OtherType, + Decoded_ssh2_pubkey :: public_key(), + Decoded_OtherType :: [{public_key(), Attributes}], + Attributes :: [{atom(),term()}] . %% %% Description: Decodes a ssh file-binary. In the case of know_hosts %% or auth_keys the binary may include one or more lines of the @@ -990,9 +1090,15 @@ ssh_decode(SshBin, Type) when is_binary(SshBin), pubkey_ssh:decode(SshBin, Type). %%-------------------------------------------------------------------- --spec ssh_encode([{public_key(), Attributes::list()}], ssh_file()) -> binary() - ; (public_key(), ssh2_pubkey) -> binary() - . +-spec ssh_encode(InData, Type) -> + binary() + when Type :: ssh2_pubkey | OtherType, + OtherType :: public_key | ssh_file(), + InData :: InData_ssh2_pubkey | OtherInData, + InData_ssh2_pubkey :: public_key(), + OtherInData :: [{Key,Attributes}], + Key :: public_key(), + Attributes :: [{atom(),term()}] . %% %% Description: Encodes a list of ssh file entries (public keys and %% attributes) to a binary. Possible attributes depends on the file @@ -1027,13 +1133,14 @@ oid2ssh_curvename(?'secp521r1') -> <<"nistp521">>. %%-------------------------------------------------------------------- -spec ssh_hostkey_fingerprint(public_key()) -> string(). --spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string() - ; ([digest_type()], public_key()) -> [string()] - . ssh_hostkey_fingerprint(Key) -> sshfp_string(md5, public_key:ssh_encode(Key,ssh2_pubkey) ). + +-spec ssh_hostkey_fingerprint( digest_type(), public_key()) -> string() + ; ([digest_type()], public_key()) -> [string()] + . ssh_hostkey_fingerprint(HashAlgs, Key) when is_list(HashAlgs) -> EncKey = public_key:ssh_encode(Key, ssh2_pubkey), [sshfp_full_string(HashAlg,EncKey) || HashAlg <- HashAlgs]; @@ -1071,8 +1178,7 @@ fp_fmt(b64, Bin) -> [lists:nth(C+1,B64Chars) || <> <= <> ]. %%-------------------------------------------------------------------- --spec short_name_hash({rdnSequence, [#'AttributeTypeAndValue'{}]}) -> - string(). +-spec short_name_hash(Name) -> string() when Name :: issuer_name() . %% Description: Generates OpenSSL-style hash of a name. %%-------------------------------------------------------------------- @@ -1103,10 +1209,11 @@ pkix_test_data(#{} = Chain) -> pubkey_cert:gen_test_certs(maps:merge(Default, Chain)). %%-------------------------------------------------------------------- --spec pkix_test_root_cert( - Name :: string(), Opts :: [pubkey_cert:cert_opt()]) -> - pubkey_cert:test_root_cert(). - +-spec pkix_test_root_cert(Name, Options) -> + RootCert + when Name :: string(), + Options :: [{atom(),term()}], %[cert_opt()], + RootCert :: pubkey_cert:test_root_cert(). %% Description: Generates a root cert suitable for pkix_test_data/1 %%-------------------------------------------------------------------- @@ -1152,14 +1259,6 @@ do_pem_entry_decode({Asn1Type,_, _} = PemEntry, Password) -> Der = pubkey_pem:decipher(PemEntry, Password), der_decode(Asn1Type, Der). -encrypt_public(PlainText, N, E, Options)-> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:public_encrypt(rsa, PlainText, [E,N], Padding). - -decrypt_public(CipherText, N,E, Options) -> - Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding), - crypto:public_decrypt(rsa, CipherText,[E, N], Padding). - path_validation([], #path_validation_state{working_public_key_algorithm = Algorithm, working_public_key = -- cgit v1.2.3 From 0cdaea5199c49c1511700db3b4b0ff59f4c7396d Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Mon, 3 Sep 2018 15:15:47 +0200 Subject: public_key: Generate refman from types and specs --- lib/public_key/doc/src/public_key.xml | 684 ++++++++++++---------------------- 1 file changed, 240 insertions(+), 444 deletions(-) diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml index c0a67c25b8..a4d7e4a734 100644 --- a/lib/public_key/doc/src/public_key.xml +++ b/lib/public_key/doc/src/public_key.xml @@ -41,7 +41,7 @@
- DATA TYPES + Common Records and ASN.1 Types

All records used in this Reference Manual @@ -54,193 +54,132 @@ records and constant macros described here and in the User's Guide:

-include_lib("public_key/include/public_key.hrl"). +
+ + + + + +

Object identifier, a tuple of integers as generated by the ASN.1 compiler.

+
+
+ + + + + + + + + + + + + + + + +

ASN.1 type present in the Public Key applications ASN.1 specifications.

+
+
+ + + + + + + + + + Cipher = "RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC" +

Salt could be generated with + crypto:strong_rand_bytes(8).

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
-

The following data types are used in the functions for public_key:

- - - oid() -

Object identifier, a tuple of integers as generated by the ASN.1 compiler.

- - boolean() = -

true | false

- - string() = -

[bytes()]

- - der_encoded() = -

binary()

- - pki_asn1_type() = - -

'Certificate'

-

| 'RSAPrivateKey'

-

| 'RSAPublicKey'

-

| 'DSAPrivateKey'

-

| 'DSAPublicKey'

-

| 'DHParameter'

-

| 'SubjectPublicKeyInfo'

-

| 'PrivateKeyInfo'

-

| 'CertificationRequest'

-

| 'CertificateList'

-

| 'ECPrivateKey'

-

| 'EcpkParameters'

-
- - pem_entry () = -

{pki_asn1_type(), binary(), %% DER or encrypted DER

-

not_encrypted | cipher_info()}

- - cipher_info() = -

{"RC2-CBC" | "DES-CBC" | "DES-EDE3-CBC", crypto:strong_rand_bytes(8)

-

| {#'PBEParameter{}, digest_type()} | #'PBES2-params'{}}

-
- - - public_key() = -

rsa_public_key() | dsa_public_key() | ec_public_key()

- - - private_key() = -

rsa_private_key() | dsa_private_key() | ec_private_key()

- - rsa_public_key() = -

#'RSAPublicKey'{}

- - rsa_private_key() = -

#'RSAPrivateKey'{}

- - dsa_public_key() = -

{integer(), #'Dss-Parms'{}}

- - dsa_private_key() = -

#'DSAPrivateKey'{}

- - ec_public_key() -

= {#'ECPoint'{}, #'ECParameters'{} | {namedCurve, oid()}}

- - ec_private_key() = -

#'ECPrivateKey'{}

- - key_params() = -

#'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} - | {rsa, Size::integer(), PubExp::integer()}

- - public_crypt_options() = -

[{rsa_pad, rsa_padding()}]

- - rsa_padding() = - -

'rsa_pkcs1_padding'

-

| 'rsa_pkcs1_oaep_padding'

-

| 'rsa_no_padding'

-
- - public_sign_options() = -

[{rsa_pad, rsa_sign_padding()} | {rsa_pss_saltlen, integer()}]

- - rsa_sign_padding() = - -

'rsa_pkcs1_padding'

-

| 'rsa_pkcs1_pss_padding'

-
- - digest_type() = -

Union of rsa_digest_type(), dss_digest_type(), - and ecdsa_digest_type().

- - rsa_digest_type() = -

'md5' | 'ripemd160' | 'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'

- - dss_digest_type() = -

'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'

-

Note that the actual supported dss_digest_type depends on the underlying crypto library. - In OpenSSL version >= 1.0.1 the listed digest are supported, while in 1.0.0 only - sha, sha224 and sha256 are supported. In version 0.9.8 only sha is supported.

-
- - ecdsa_digest_type() = -

'sha' | 'sha224' | 'sha256' | 'sha384' | 'sha512'

- - crl_reason() = - -

unspecified

-

| keyCompromise

-

| cACompromise

-

| affiliationChanged

-

| superseded

-

| cessationOfOperation

-

| certificateHold

-

| privilegeWithdrawn

-

| aACompromise

-
- - issuer_name() = -

{rdnSequence,[#'AttributeTypeAndValue'{}]}

-
- - ssh_file() = - -

openssh_public_key

-

| rfc4716_public_key

-

| known_hosts

-

| auth_keys

-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - compute_key(OthersKey, MyKey)-> - compute_key(OthersKey, MyKey, Params)-> + + Computes shared secret. + +

Computes shared secret.

+
+
+ + + Computes shared secret. - - OthersKey = #'ECPoint'{} | binary(), MyKey = #'ECPrivateKey'{} | binary() - Params = #'DHParameter'{} -

Computes shared secret.

- decrypt_private(CipherText, Key) -> binary() - decrypt_private(CipherText, Key, Options) -> binary() + + Public-key decryption. - - CipherText = binary() - Key = rsa_private_key() - Options = public_crypt_options() -

Public-key decryption using the private key. See also crypto:private_decrypt/4

@@ -248,14 +187,9 @@
- decrypt_public(CipherText, Key) - > binary() - decrypt_public(CipherText, Key, Options) - > binary() + + Public-key decryption. - - CipherText = binary() - Key = rsa_public_key() - Options = public_crypt_options() -

Public-key decryption using the public key. See also crypto:public_decrypt/4

@@ -263,47 +197,24 @@
- der_decode(Asn1type, Der) -> term() + Decodes a public-key ASN.1 DER encoded entity. - - Asn1Type = atom() - ASN.1 type present in the Public Key applications - ASN.1 specifications. - Der = der_encoded() - - +

Decodes a public-key ASN.1 DER encoded entity.

- + - der_encode(Asn1Type, Entity) -> der_encoded() + Encodes a public-key entity with ASN.1 DER encoding. - - Asn1Type = atom() - ASN.1 type present in the Public Key applications - ASN.1 specifications. - Entity = term() - Erlang representation of Asn1Type -

Encodes a public-key entity with ASN.1 DER encoding.

- dh_gex_group(MinSize, SuggestedSize, MaxSize, Groups) -> {ok, {Size,Group}} | {error,Error} + Selects a group for Diffie-Hellman key exchange - - MinSize = positive_integer() - SuggestedSize = positive_integer() - MaxSize = positive_integer() - Groups = undefined | [{Size,[{G,P}]}] - Size = positive_integer() - Group = {G,P} - G = positive_integer() - P = positive_integer() -

Selects a group for Diffie-Hellman key exchange with the key size in the range MinSize...MaxSize and as close to SuggestedSize as possible. If Groups == undefined a default set will be @@ -322,13 +233,10 @@ - - encrypt_private(PlainText, Key) -> binary() + + + Public-key encryption using the private key. - - PlainText = binary() - Key = rsa_private_key() -

Public-key encryption using the private key. See also - encrypt_public(PlainText, Key) -> binary() + + Public-key encryption using the public key. - - PlainText = binary() - Key = rsa_public_key() -

Public-key encryption using the public key. See also crypto:public_encrypt/4.

@@ -350,11 +255,8 @@
- generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} | #'RSAPrivateKey'{} + Generates a new keypair. - - Params = key_params() -

Generates a new keypair. Note that except for Diffie-Hellman the public key is included in the private key structure. See also @@ -364,38 +266,27 @@ - pem_decode(PemBin) -> [pem_entry()] + Decodes PEM binary data and returns entries as ASN.1 DER encoded entities. - - PemBin = binary() - Example {ok, PemBin} = file:read_file("cert.pem"). - -

Decodes PEM binary data and returns - entries as ASN.1 DER encoded entities.

+

Decodes PEM binary data and returns entries as ASN.1 DER encoded entities.

+

Example {ok, PemBin} = file:read_file("cert.pem").

- - pem_encode(PemEntries) -> binary() + + Creates a PEM binary. - - PemEntries = [pem_entry()] - - -

Creates a PEM binary.

-
+ +

Creates a PEM binary.

+
- - pem_entry_decode(PemEntry) -> term() - pem_entry_decode(PemEntry, Password) -> term() + + + Decodes a PEM entry. - - PemEntry = pem_entry() - Password = string() -

Decodes a PEM entry. pem_decode/1 returns a list of PEM entries. Notice that if the PEM entry is of type @@ -404,51 +295,36 @@ - - pem_entry_encode(Asn1Type, Entity) -> pem_entry() - pem_entry_encode(Asn1Type, Entity, {CipherInfo, Password}) -> pem_entry() + + + Creates a PEM entry that can be fed to pem_encode/1. - - Asn1Type = pki_asn1_type() - Entity = term() - Erlang representation of - Asn1Type. If Asn1Type is 'SubjectPublicKeyInfo', + +

Creates a PEM entry that can be feed to pem_encode/1.

+

If Asn1Type is 'SubjectPublicKeyInfo', Entity must be either an rsa_public_key(), dsa_public_key() or an ec_public_key() and this function creates the appropriate - 'SubjectPublicKeyInfo' entry. - - CipherInfo = cipher_info() - Password = string() - - -

Creates a PEM entry that can be feed to pem_encode/1.

-
+ 'SubjectPublicKeyInfo' entry. +

+
- + - pkix_decode_cert(Cert, otp|plain) -> #'Certificate'{} | #'OTPCertificate'{} + Decodes an ASN.1 DER-encoded PKIX x509 certificate. - - Cert = der_encoded() - - -

Decodes an ASN.1 DER-encoded PKIX certificate. Option otp - uses the customized ASN.1 specification OTP-PKIX.asn1 for - decoding and also recursively decode most of the standard - parts.

-
+ +

Decodes an ASN.1 DER-encoded PKIX certificate. Option otp + uses the customized ASN.1 specification OTP-PKIX.asn1 for + decoding and also recursively decode most of the standard + parts.

+
- pkix_encode(Asn1Type, Entity, otp | plain) -> der_encoded() + DER encodes a PKIX x509 certificate or part of such a certificate. - - Asn1Type = atom() - The ASN.1 type can be 'Certificate', 'OTPCertificate' or a subtype of either. - Entity = #'Certificate'{} | #'OTPCertificate'{} | a valid subtype -

DER encodes a PKIX x509 certificate or part of such a certificate. This function must be used for encoding certificates or parts of certificates @@ -458,69 +334,47 @@ - pkix_is_issuer(Cert, IssuerCert) -> boolean() - Checks if IssuerCert issued Cert. - - Cert = der_encoded() | #'OTPCertificate'{} | #'CertificateList'{} - IssuerCert = der_encoded() | #'OTPCertificate'{} - - -

Checks if IssuerCert issued Cert.

-
-
+ + Checks if IssuerCert issued Cert. + +

Checks if IssuerCert issued Cert.

+
+
- - pkix_is_fixed_dh_cert(Cert) -> boolean() - Checks if a certificate is a fixed Diffie-Hellman certificate. - - Cert = der_encoded() | #'OTPCertificate'{} - - -

Checks if a certificate is a fixed Diffie-Hellman certificate.

-
-
+ + + Checks if a certificate is a fixed Diffie-Hellman certificate. + +

Checks if a certificate is a fixed Diffie-Hellman certificate.

+
+
- - pkix_is_self_signed(Cert) -> boolean() - Checks if a certificate is self-signed. - - Cert = der_encoded() | #'OTPCertificate'{} - - -

Checks if a certificate is self-signed.

-
-
+ + + Checks if a certificate is self-signed. + +

Checks if a certificate is self-signed.

+
+
- - pkix_issuer_id(Cert, IssuedBy) -> {ok, IssuerID} | {error, Reason} - Returns the issuer id. - - Cert = der_encoded() | #'OTPCertificate'{} - IssuedBy = self | other - IssuerID = {integer(), issuer_name()} - The issuer id consists of the serial number and the issuers name. - Reason = term() - - -

Returns the issuer id.

-
-
- + + + Returns the issuer id. + +

Returns the issuer id.

+
+
- - pkix_normalize_name(Issuer) -> Normalized - Normalizes an issuer name so that it can be easily - compared to another issuer name. - - Issuer = issuer_name() - Normalized = issuer_name() - - -

Normalizes an issuer name so that it can be easily - compared to another issuer name.

-
-
- + + + Normalizes an issuer name so that it can be easily + compared to another issuer name. + +

Normalizes an issuer name so that it can be easily + compared to another issuer name.

+
+
+ pkix_path_validation(TrustedCert, CertChain, Options) -> {ok, {PublicKeyInfo, PolicyTree}} | {error, {bad_cert, Reason}} Performs a basic path validation according to RFC 5280. @@ -622,26 +476,16 @@ fun(OtpCert :: #'OTPCertificate'{}, - pkix_crl_issuer(CRL) -> issuer_name() + Returns the issuer of the CRL. - - CRL = der_encoded() | #'CertificateList'{} -

Returns the issuer of the CRL.

- pkix_crls_validate(OTPCertificate, DPAndCRLs, Options) -> CRLStatus() + Performs CRL validation. - - OTPCertificate = #'OTPCertificate'{} - DPAndCRLs = [{DP::#'DistributionPoint'{}, {DerCRL::der_encoded(), CRL::#'CertificateList'{}}}] - Options = proplists:proplist() - CRLStatus() = valid | {bad_cert, revocation_status_undetermined} | {bad_cert, {revocation_status_undetermined, - {bad_crls, Details::term()}}} | {bad_cert, {revoked, crl_reason()}} -

Performs CRL validation. It is intended to be called from the verify fun of pkix_path_validation/3 @@ -692,24 +536,16 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, - pkix_crl_verify(CRL, Cert) -> boolean() + Verify that Cert is the CRL signer. - - CRL = der_encoded() | #'CertificateList'{} - Cert = der_encoded() | #'OTPCertificate'{} -

Verify that Cert is the CRL signer.

- pkix_dist_point(Cert) -> DistPoint + Creates a distribution point for CRLs issued by the same issuer as Cert. - - Cert = der_encoded() | #'OTPCertificate'{} - DistPoint = #'DistributionPoint'{} -

Creates a distribution point for CRLs issued by the same issuer as Cert. Can be used as input to - pkix_dist_points(Cert) -> DistPoints + Extracts distribution points from the certificates extensions. - - Cert = der_encoded() | #'OTPCertificate'{} - DistPoints = [#'DistributionPoint'{}] -

Extracts distribution points from the certificates extensions.

- pkix_match_dist_point(CRL, DistPoint) -> boolean() + Checks whether the given distribution point matches the Issuing Distribution Point of the CRL. - - - CRL = der_encoded() | #'CertificateList'{} - DistPoint = #'DistributionPoint'{} -

Checks whether the given distribution point matches the Issuing Distribution Point of the CRL, as described in RFC 5280. @@ -748,11 +575,8 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, - pkix_sign(#'OTPTBSCertificate'{}, Key) -> der_encoded() + Signs certificate. - - Key = rsa_private_key() | dsa_private_key() -

Signs an 'OTPTBSCertificate'. Returns the corresponding DER-encoded certificate.

@@ -760,17 +584,12 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
- pkix_sign_types(AlgorithmId) -> {DigestType, SignatureType} + Translates signature algorithm OID to Erlang digest and signature algorithm types. - - AlgorithmId = oid() - Signature OID from a certificate or a certificate revocation list. - DigestType = rsa_digest_type() | dss_digest_type() - SignatureType = rsa | dsa | ecdsa -

Translates signature algorithm OID to Erlang digest and signature types.

+

The AlgorithmId is the signature OID from a certificate or a certificate revocation list.

@@ -938,12 +757,8 @@ fun(#'DistributionPoint'{}, #'CertificateList'{}, - pkix_verify(Cert, Key) -> boolean() + Verifies PKIX x.509 certificate signature. - - Cert = der_encoded() - Key = rsa_public_key() | dsa_public_key() | ec_public_key() -

Verifies PKIX x.509 certificate signature.

@@ -1059,41 +874,30 @@ end - sign(Msg, DigestType, Key) -> binary() - sign(Msg, DigestType, Key, Options) -> binary() + + Creates a digital signature. - - Msg = binary() | {digest,binary()} - The Msg is either the binary "plain text" data to be - signed or it is the hashed value of "plain text", that is, the - digest. - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Key = rsa_private_key() | dsa_private_key() | ec_private_key() - Options = public_sign_options() -

Creates a digital signature.

+

The Msg is either the binary "plain text" data to be + signed or it is the hashed value of "plain text", that is, the + digest.

- ssh_decode(SshBin, Type) -> [{public_key(), Attributes::list()}] + Decodes an SSH file-binary. - - SshBin = binary() - Example {ok, SshBin} = file:read_file("known_hosts"). - Type = public_key | ssh_file() - If Type is public_key the binary can be either - an RFC4716 public key or an OpenSSH public key. - - -

Decodes an SSH file-binary. In the case of known_hosts or - auth_keys, the binary can include one or more lines of the - file. Returns a list of public keys and their attributes, possible - attribute values depends on the file type represented by the - binary. -

- + +

Decodes an SSH file-binary. In the case of known_hosts or + auth_keys, the binary can include one or more lines of the + file. Returns a list of public keys and their attributes, possible + attribute values depends on the file type represented by the + binary. +

+

If the Type is ssh2_pubkey, the result will be + Decoded_ssh2_pubkey. Otherwise it will be Decoded_OtherType. +

RFC4716 attributes - see RFC 4716.

{headers, [{string(), utf8_string()}]}

@@ -1106,23 +910,25 @@ end {comment, string()}

{bits, integer()} - In SSH version 1 files.

- +

Example: {ok, SshBin} = file:read_file("known_hosts"). +

+

If Type is public_key the binary can be either + an RFC4716 public key or an OpenSSH public key.

- ssh_encode([{Key, Attributes}], Type) -> binary() + Encodes a list of SSH file entries to a binary. - - Key = public_key() - Attributes = list() - Type = ssh_file() - - -

Encodes a list of SSH file entries (public keys and attributes) to a binary. Possible - attributes depend on the file type, see ssh_decode/2 .

-
+ +

Encodes a list of SSH file entries (public keys and attributes) to a binary. Possible + attributes depend on the file type, see + ssh_decode/2 . +

+

If the Type is ssh2_pubkey, the InData shall be + InData_ssh2_pubkey. Otherwise it shall be OtherInData. +

+
@@ -1131,8 +937,8 @@ end ssh_hostkey_fingerprint([DigestType], HostKey) -> [string()] Calculates a ssh fingerprint for a hostkey. - Key = public_key() - DigestType = digest_type() + HostKey = public_key() + DigestType = digest_type()

Calculates a ssh fingerprint from a public host key as openssh does.

@@ -1161,29 +967,19 @@ end
- verify(Msg, DigestType, Signature, Key) -> boolean() - verify(Msg, DigestType, Signature, Key, Options) -> boolean() + + Verifies a digital signature. - - Msg = binary() | {digest,binary()} - The Msg is either the binary "plain text" data - or it is the hashed value of "plain text", that is, the digest. - DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() - Signature = binary() - Key = rsa_public_key() | dsa_public_key() | ec_public_key() - Options = public_sign_options() -

Verifies a digital signature.

+

The Msg is either the binary "plain text" data + or it is the hashed value of "plain text", that is, the digest.

- short_name_hash(Name) -> string() + Generates a short hash of an issuer name. - - Name = issuer_name() -

Generates a short hash of an issuer name. The hash is returned as a string containing eight hexadecimal digits.

-- cgit v1.2.3 From df39504bc6f9b106a20959b969b258db327261a5 Mon Sep 17 00:00:00 2001 From: Hans Nilsson Date: Wed, 29 Aug 2018 14:18:41 +0200 Subject: ssh: Use exported crypto types --- lib/ssh/src/ssh.hrl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/lib/ssh/src/ssh.hrl b/lib/ssh/src/ssh.hrl index 66dbf0b144..94b9f3a196 100644 --- a/lib/ssh/src/ssh.hrl +++ b/lib/ssh/src/ssh.hrl @@ -260,13 +260,7 @@ | accept_callback() | {HashAlgoSpec::fp_digest_alg(), accept_callback()}. --type fp_digest_alg() :: 'md5' | - 'sha' | - 'sha224' | - 'sha256' | - 'sha384' | - 'sha512' - . +-type fp_digest_alg() :: 'md5' | crypto:sha1() | crypto:sha2() . -type accept_callback() :: fun((PeerName::string(), fingerprint() ) -> boolean()) . -type fingerprint() :: string() | [string()]. -- cgit v1.2.3