]> source.dussan.org Git - rspamd.git/commitdiff
[Test] Start provide support for OpenSSL 3.0
authorLeftTry <lerest.go@gmail.com>
Wed, 24 Jul 2024 08:35:30 +0000 (13:35 +0500)
committerLeftTry <lerest.go@gmail.com>
Wed, 24 Jul 2024 08:35:30 +0000 (13:35 +0500)
src/libcryptobox/cryptobox.h
src/libserver/dkim.c

index 8382c8f683d49fed93b2eeb2137c080915548071..54ef48c9a3095a809c43377744bcc6557d249048 100644 (file)
@@ -1,22 +1,23 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2024 Vsevolod Stakhov
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 #ifndef CRYPTOBOX_H_
 #define CRYPTOBOX_H_
 
 #include "config.h"
+#include "openssl/evp.h"
 
 #include <sodium.h>
 
@@ -25,13 +26,13 @@ extern "C" {
 #endif
 
 struct rspamd_cryptobox_segment {
-       unsigned char *data;
-       gsize len;
+   unsigned char *data;
+   gsize len;
 };
 
 #if defined(__GNUC__) &&                                                                                 \
-       ((defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 8))) || \
-        ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) || (__GNUC__ > 4)))
+   ((defined(__clang__) && (__clang_major__ >= 4 || (__clang_major__ >= 3 && __clang_minor__ >= 8))) || \
+       ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8) || (__GNUC__ > 4)))
 #define RSPAMD_HAS_TARGET_ATTR 1
 #endif
 
@@ -68,366 +69,379 @@ typedef unsigned char rspamd_sig_pk_t[rspamd_cryptobox_MAX_SIGPKBYTES];
 typedef unsigned char rspamd_sig_sk_t[rspamd_cryptobox_MAX_SIGSKBYTES];
 
 enum rspamd_cryptobox_mode {
-       RSPAMD_CRYPTOBOX_MODE_25519 = 0,
-       RSPAMD_CRYPTOBOX_MODE_NIST
+   RSPAMD_CRYPTOBOX_MODE_25519 = 0,
+   RSPAMD_CRYPTOBOX_MODE_NIST
 };
 
 struct rspamd_cryptobox_library_ctx {
-       char *cpu_extensions;
-       const char *chacha20_impl;
-       const char *base64_impl;
-       unsigned long cpu_config;
+   char *cpu_extensions;
+   const char *chacha20_impl;
+   const char *base64_impl;
+   unsigned long cpu_config;
 };
 
 /**
- * Init cryptobox library
- */
+* Init cryptobox library
+*/
 struct rspamd_cryptobox_library_ctx *rspamd_cryptobox_init(void);
 
 void rspamd_cryptobox_deinit(struct rspamd_cryptobox_library_ctx *);
 /**
- * Generate new keypair
- * @param pk public key buffer
- * @param sk secret key buffer
- */
+* Generate new keypair
+* @param pk public key buffer
+* @param sk secret key buffer
+*/
 void rspamd_cryptobox_keypair(rspamd_pk_t pk, rspamd_sk_t sk,
-                                                         enum rspamd_cryptobox_mode mode);
+                                                        enum rspamd_cryptobox_mode mode);
 
 /**
- * Generate new keypair for signing
- * @param pk public key buffer
- * @param sk secret key buffer
- */
+* Generate new keypair for signing
+* @param pk public key buffer
+* @param sk secret key buffer
+*/
 void rspamd_cryptobox_keypair_sig(rspamd_sig_pk_t pk, rspamd_sig_sk_t sk,
-                                                                 enum rspamd_cryptobox_mode mode);
+                                                                enum rspamd_cryptobox_mode mode);
 
 /**
- * Encrypt data inplace adding signature to sig afterwards
- * @param data input buffer
- * @param pk remote pubkey
- * @param sk local secret key
- * @param sig output signature
- */
+* Encrypt data inplace adding signature to sig afterwards
+* @param data input buffer
+* @param pk remote pubkey
+* @param sk local secret key
+* @param sig output signature
+*/
 void rspamd_cryptobox_encrypt_inplace(unsigned char *data, gsize len,
+                                                                        const rspamd_nonce_t nonce,
+                                                                        const rspamd_pk_t pk, const rspamd_sk_t sk, rspamd_mac_t sig,
+                                                                        enum rspamd_cryptobox_mode mode);
+
+/**
+* Encrypt segments of data inplace adding signature to sig afterwards
+* @param segments segments of data
+* @param cnt count of segments
+* @param pk remote pubkey
+* @param sk local secret key
+* @param sig output signature
+*/
+void rspamd_cryptobox_encryptv_inplace(struct rspamd_cryptobox_segment *segments,
+                                                                         gsize cnt,
                                                                          const rspamd_nonce_t nonce,
                                                                          const rspamd_pk_t pk, const rspamd_sk_t sk, rspamd_mac_t sig,
                                                                          enum rspamd_cryptobox_mode mode);
 
-/**
- * Encrypt segments of data inplace adding signature to sig afterwards
- * @param segments segments of data
- * @param cnt count of segments
- * @param pk remote pubkey
- * @param sk local secret key
- * @param sig output signature
- */
-void rspamd_cryptobox_encryptv_inplace(struct rspamd_cryptobox_segment *segments,
-                                                                          gsize cnt,
-                                                                          const rspamd_nonce_t nonce,
-                                                                          const rspamd_pk_t pk, const rspamd_sk_t sk, rspamd_mac_t sig,
-                                                                          enum rspamd_cryptobox_mode mode);
-
 
 /**
- * Decrypt and verify data chunk inplace
- * @param data data to decrypt
- * @param len length of data
- * @param pk remote pubkey
- * @param sk local privkey
- * @param sig signature input
- * @return TRUE if input has been verified successfully
- */
+* Decrypt and verify data chunk inplace
+* @param data data to decrypt
+* @param len length of data
+* @param pk remote pubkey
+* @param sk local privkey
+* @param sig signature input
+* @return TRUE if input has been verified successfully
+*/
 gboolean rspamd_cryptobox_decrypt_inplace(unsigned char *data, gsize len,
-                                                                                 const rspamd_nonce_t nonce,
-                                                                                 const rspamd_pk_t pk, const rspamd_sk_t sk, const rspamd_mac_t sig,
-                                                                                 enum rspamd_cryptobox_mode mode);
-
-/**
- * Encrypt segments of data inplace adding signature to sig afterwards
- * @param segments segments of data
- * @param cnt count of segments
- * @param pk remote pubkey
- * @param sk local secret key
- * @param sig output signature
- */
-void rspamd_cryptobox_encrypt_nm_inplace(unsigned char *data, gsize len,
                                                                                 const rspamd_nonce_t nonce,
-                                                                                const rspamd_nm_t nm, rspamd_mac_t sig,
+                                                                                const rspamd_pk_t pk, const rspamd_sk_t sk, const rspamd_mac_t sig,
                                                                                 enum rspamd_cryptobox_mode mode);
 
 /**
- * Encrypt segments of data inplace adding signature to sig afterwards
- * @param segments segments of data
- * @param cnt count of segments
- * @param pk remote pubkey
- * @param sk local secret key
- * @param sig output signature
- */
+* Encrypt segments of data inplace adding signature to sig afterwards
+* @param segments segments of data
+* @param cnt count of segments
+* @param pk remote pubkey
+* @param sk local secret key
+* @param sig output signature
+*/
+void rspamd_cryptobox_encrypt_nm_inplace(unsigned char *data, gsize len,
+                                                                               const rspamd_nonce_t nonce,
+                                                                               const rspamd_nm_t nm, rspamd_mac_t sig,
+                                                                               enum rspamd_cryptobox_mode mode);
+
+/**
+* Encrypt segments of data inplace adding signature to sig afterwards
+* @param segments segments of data
+* @param cnt count of segments
+* @param pk remote pubkey
+* @param sk local secret key
+* @param sig output signature
+*/
 void rspamd_cryptobox_encryptv_nm_inplace(struct rspamd_cryptobox_segment *segments,
-                                                                                 gsize cnt,
-                                                                                 const rspamd_nonce_t nonce,
-                                                                                 const rspamd_nm_t nm, rspamd_mac_t sig,
-                                                                                 enum rspamd_cryptobox_mode mode);
+                                                                                gsize cnt,
+                                                                                const rspamd_nonce_t nonce,
+                                                                                const rspamd_nm_t nm, rspamd_mac_t sig,
+                                                                                enum rspamd_cryptobox_mode mode);
 
 
 /**
- * Decrypt and verify data chunk inplace
- * @param data data to decrypt
- * @param len length of data
- * @param pk remote pubkey
- * @param sk local privkey
- * @param sig signature input
- * @return TRUE if input has been verified successfully
- */
+* Decrypt and verify data chunk inplace
+* @param data data to decrypt
+* @param len length of data
+* @param pk remote pubkey
+* @param sk local privkey
+* @param sig signature input
+* @return TRUE if input has been verified successfully
+*/
 gboolean rspamd_cryptobox_decrypt_nm_inplace(unsigned char *data, gsize len,
-                                                                                        const rspamd_nonce_t nonce,
-                                                                                        const rspamd_nm_t nm, const rspamd_mac_t sig,
-                                                                                        enum rspamd_cryptobox_mode mode);
+                                                                                       const rspamd_nonce_t nonce,
+                                                                                       const rspamd_nm_t nm, const rspamd_mac_t sig,
+                                                                                       enum rspamd_cryptobox_mode mode);
 
 /**
- * Generate shared secret from local sk and remote pk
- * @param nm shared secret
- * @param pk remote pubkey
- * @param sk local privkey
- */
+* Generate shared secret from local sk and remote pk
+* @param nm shared secret
+* @param pk remote pubkey
+* @param sk local privkey
+*/
 void rspamd_cryptobox_nm(rspamd_nm_t nm, const rspamd_pk_t pk,
-                                                const rspamd_sk_t sk, enum rspamd_cryptobox_mode mode);
+                                               const rspamd_sk_t sk, enum rspamd_cryptobox_mode mode);
 
 /**
- * Create digital signature for the specified message and place result in `sig`
- * @param sig signature target
- * @param siglen_p pointer to signature length (might be NULL)
- * @param m input message
- * @param mlen input length
- * @param sk secret key
- */
+* Create digital signature for the specified message and place result in `sig`
+* @param sig signature target
+* @param siglen_p pointer to signature length (might be NULL)
+* @param m input message
+* @param mlen input length
+* @param sk secret key
+*/
 void rspamd_cryptobox_sign(unsigned char *sig, unsigned long long *siglen_p,
-                                                  const unsigned char *m, gsize mlen,
-                                                  const rspamd_sk_t sk,
-                                                  enum rspamd_cryptobox_mode mode);
-
-/**
- * Verifies digital signature for the specified message using the specified
- * pubkey
- * @param sig signature source
- * @param m input message
- * @param mlen message length
- * @param pk public key for verification
- * @return true if signature is valid, false otherwise
- */
+                                                 const unsigned char *m, gsize mlen,
+                                                 const rspamd_sk_t sk,
+                                                 enum rspamd_cryptobox_mode mode);
+
+void rspamd_cryptobox_sign_compat(int nid, unsigned char *sig, unsigned long long *siglen_p,
+                                                                const unsigned char *m, gsize mlen,
+                                                                struct evp_pkey_st *sec_key,
+                                                                enum rspamd_cryptobox_mode mode);
+
+/**
+* Verifies digital signature for the specified message using the specified
+* pubkey
+* @param sig signature source
+* @param m input message
+* @param mlen message length
+* @param pk public key for verification
+* @return true if signature is valid, false otherwise
+*/
 bool rspamd_cryptobox_verify(const unsigned char *sig,
-                                                        gsize siglen,
-                                                        const unsigned char *m,
-                                                        gsize mlen,
-                                                        const rspamd_pk_t pk,
-                                                        enum rspamd_cryptobox_mode mode);
-
-/**
- * Securely clear the buffer specified
- * @param buf buffer to zero
- * @param buflen length of buffer
- */
+                                                       gsize siglen,
+                                                       const unsigned char *m,
+                                                       gsize mlen,
+                                                       const rspamd_pk_t pk,
+                                                       enum rspamd_cryptobox_mode mode);
+
+bool rspamd_cryptobox_verify_compat(int nid,
+                                                                  const unsigned char *sig,
+                                                                  gsize siglen,
+                                                                  const unsigned char *m,
+                                                                  gsize mlen,
+                                                                  struct evp_pkey_st *pub_key,
+                                                                  enum rspamd_cryptobox_mode mode);
+
+/**
+* Securely clear the buffer specified
+* @param buf buffer to zero
+* @param buflen length of buffer
+*/
 
 #define rspamd_explicit_memzero sodium_memzero
 
 /**
- * Constant time memcmp
- * @param b1_
- * @param b2_
- * @param len
- * @return
- */
+* Constant time memcmp
+* @param b1_
+* @param b2_
+* @param len
+* @return
+*/
 #define rspamd_cryptobox_memcmp sodium_memcmp
 
 /**
- * Calculates siphash-2-4 for a message
- * @param out (8 bytes output)
- * @param in
- * @param inlen
- * @param k key (must be 16 bytes)
- */
+* Calculates siphash-2-4 for a message
+* @param out (8 bytes output)
+* @param in
+* @param inlen
+* @param k key (must be 16 bytes)
+*/
 void rspamd_cryptobox_siphash(unsigned char *out, const unsigned char *in,
-                                                         unsigned long long inlen,
-                                                         const rspamd_sipkey_t k);
+                                                        unsigned long long inlen,
+                                                        const rspamd_sipkey_t k);
 
 enum rspamd_cryptobox_pbkdf_type {
-       RSPAMD_CRYPTOBOX_PBKDF2 = 0,
-       RSPAMD_CRYPTOBOX_CATENA
+   RSPAMD_CRYPTOBOX_PBKDF2 = 0,
+   RSPAMD_CRYPTOBOX_CATENA
 };
 
 
 /**
- * Derive key from password using the specified algorithm
- * @param pass input password
- * @param pass_len length of the password
- * @param salt input salt
- * @param salt_len length of salt
- * @param key output key
- * @param key_len size of the key
- * @param complexity empiric number of complexity (rounds for pbkdf2 and garlic for catena)
- * @return TRUE in case of success and FALSE if failed
- */
+* Derive key from password using the specified algorithm
+* @param pass input password
+* @param pass_len length of the password
+* @param salt input salt
+* @param salt_len length of salt
+* @param key output key
+* @param key_len size of the key
+* @param complexity empiric number of complexity (rounds for pbkdf2 and garlic for catena)
+* @return TRUE in case of success and FALSE if failed
+*/
 gboolean rspamd_cryptobox_pbkdf(const char *pass, gsize pass_len,
-                                                               const uint8_t *salt, gsize salt_len,
-                                                               uint8_t *key, gsize key_len,
-                                                               unsigned int complexity,
-                                                               enum rspamd_cryptobox_pbkdf_type type);
+                                                          const uint8_t *salt, gsize salt_len,
+                                                          uint8_t *key, gsize key_len,
+                                                          unsigned int complexity,
+                                                          enum rspamd_cryptobox_pbkdf_type type);
 
 
 /**
- * Real size of rspamd cryptobox public key
- */
+* Real size of rspamd cryptobox public key
+*/
 unsigned int rspamd_cryptobox_pk_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox signing public key
- */
+* Real size of rspamd cryptobox signing public key
+*/
 unsigned int rspamd_cryptobox_pk_sig_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of crypto nonce
- */
+* Real size of crypto nonce
+*/
 unsigned int rspamd_cryptobox_nonce_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox secret key
- */
+* Real size of rspamd cryptobox secret key
+*/
 unsigned int rspamd_cryptobox_sk_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox signing secret key
- */
+* Real size of rspamd cryptobox signing secret key
+*/
 unsigned int rspamd_cryptobox_sk_sig_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox shared key
- */
+* Real size of rspamd cryptobox shared key
+*/
 unsigned int rspamd_cryptobox_nm_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox MAC signature
- */
+* Real size of rspamd cryptobox MAC signature
+*/
 unsigned int rspamd_cryptobox_mac_bytes(enum rspamd_cryptobox_mode mode);
 
 /**
- * Real size of rspamd cryptobox digital signature
- */
+* Real size of rspamd cryptobox digital signature
+*/
 unsigned int rspamd_cryptobox_signature_bytes(enum rspamd_cryptobox_mode mode);
 
 /* Hash IUF interface */
 typedef crypto_generichash_blake2b_state rspamd_cryptobox_hash_state_t;
 
 /**
- * Init cryptobox hash state using key if needed, `st` must point to the buffer
- * with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
- * non-keyed hash is generated
- */
+* Init cryptobox hash state using key if needed, `st` must point to the buffer
+* with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
+* non-keyed hash is generated
+*/
 void rspamd_cryptobox_hash_init(rspamd_cryptobox_hash_state_t *st,
-                                                               const unsigned char *key, gsize keylen);
+                                                          const unsigned char *key, gsize keylen);
 
 /**
- * Update hash with data portion
- */
+* Update hash with data portion
+*/
 void rspamd_cryptobox_hash_update(rspamd_cryptobox_hash_state_t *st,
-                                                                 const unsigned char *data, gsize len);
+                                                                const unsigned char *data, gsize len);
 
 /**
- * Output hash to the buffer of rspamd_cryptobox_HASHBYTES length
- */
+* Output hash to the buffer of rspamd_cryptobox_HASHBYTES length
+*/
 void rspamd_cryptobox_hash_final(rspamd_cryptobox_hash_state_t *st, unsigned char *out);
 
 /**
- * One in all function
- */
+* One in all function
+*/
 void rspamd_cryptobox_hash(unsigned char *out,
-                                                  const unsigned char *data,
-                                                  gsize len,
-                                                  const unsigned char *key,
-                                                  gsize keylen);
+                                                 const unsigned char *data,
+                                                 gsize len,
+                                                 const unsigned char *key,
+                                                 gsize keylen);
 
 enum rspamd_cryptobox_fast_hash_type {
-       RSPAMD_CRYPTOBOX_XXHASH64 = 0,
-       RSPAMD_CRYPTOBOX_XXHASH32,
-       RSPAMD_CRYPTOBOX_XXHASH3,
-       RSPAMD_CRYPTOBOX_MUMHASH,
-       RSPAMD_CRYPTOBOX_T1HA,
-       RSPAMD_CRYPTOBOX_HASHFAST,
-       RSPAMD_CRYPTOBOX_HASHFAST_INDEPENDENT
+   RSPAMD_CRYPTOBOX_XXHASH64 = 0,
+   RSPAMD_CRYPTOBOX_XXHASH32,
+   RSPAMD_CRYPTOBOX_XXHASH3,
+   RSPAMD_CRYPTOBOX_MUMHASH,
+   RSPAMD_CRYPTOBOX_T1HA,
+   RSPAMD_CRYPTOBOX_HASHFAST,
+   RSPAMD_CRYPTOBOX_HASHFAST_INDEPENDENT
 };
 
 /* Non crypto hash IUF interface */
 typedef struct CRYPTO_ALIGN(64) rspamd_cryptobox_fast_hash_state_s {
-       unsigned char opaque[576]; /* Required for xxhash3 */
-       enum rspamd_cryptobox_fast_hash_type type;
+   unsigned char opaque[576]; /* Required for xxhash3 */
+   enum rspamd_cryptobox_fast_hash_type type;
 } rspamd_cryptobox_fast_hash_state_t;
 
 
 /**
- * Creates a new cryptobox state properly aligned
- * @return
- */
+* Creates a new cryptobox state properly aligned
+* @return
+*/
 rspamd_cryptobox_fast_hash_state_t *rspamd_cryptobox_fast_hash_new(void);
 void rspamd_cryptobox_fast_hash_free(rspamd_cryptobox_fast_hash_state_t *st);
 
 /**
- * Init cryptobox hash state using key if needed, `st` must point to the buffer
- * with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
- * non-keyed hash is generated
- */
+* Init cryptobox hash state using key if needed, `st` must point to the buffer
+* with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
+* non-keyed hash is generated
+*/
 void rspamd_cryptobox_fast_hash_init(rspamd_cryptobox_fast_hash_state_t *st,
-                                                                        uint64_t seed);
+                                                                       uint64_t seed);
 
 /**
- * Init cryptobox hash state using key if needed, `st` must point to the buffer
- * with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
- * non-keyed hash is generated
- */
+* Init cryptobox hash state using key if needed, `st` must point to the buffer
+* with at least rspamd_cryptobox_HASHSTATEBYTES bytes length. If keylen == 0, then
+* non-keyed hash is generated
+*/
 void rspamd_cryptobox_fast_hash_init_specific(rspamd_cryptobox_fast_hash_state_t *st,
-                                                                                         enum rspamd_cryptobox_fast_hash_type type,
-                                                                                         uint64_t seed);
+                                                                                        enum rspamd_cryptobox_fast_hash_type type,
+                                                                                        uint64_t seed);
 
 /**
- * Update hash with data portion
- */
+* Update hash with data portion
+*/
 void rspamd_cryptobox_fast_hash_update(rspamd_cryptobox_fast_hash_state_t *st,
-                                                                          const void *data, gsize len);
+                                                                         const void *data, gsize len);
 
 /**
- * Output hash to the buffer of rspamd_cryptobox_HASHBYTES length
- */
+* Output hash to the buffer of rspamd_cryptobox_HASHBYTES length
+*/
 uint64_t rspamd_cryptobox_fast_hash_final(rspamd_cryptobox_fast_hash_state_t *st);
 
 /**
- * One in all function
- */
+* One in all function
+*/
 uint64_t rspamd_cryptobox_fast_hash(const void *data,
-                                                                       gsize len, uint64_t seed);
+                                                                  gsize len, uint64_t seed);
 
 /**
- * Platform independent version
- */
+* Platform independent version
+*/
 uint64_t rspamd_cryptobox_fast_hash_specific(
-       enum rspamd_cryptobox_fast_hash_type type,
-       const void *data,
-       gsize len, uint64_t seed);
-
-/**
- * Decode base64 using platform optimized code
- * @param in
- * @param inlen
- * @param out
- * @param outlen
- * @return
- */
+   enum rspamd_cryptobox_fast_hash_type type,
+   const void *data,
+   gsize len, uint64_t seed);
+
+/**
+* Decode base64 using platform optimized code
+* @param in
+* @param inlen
+* @param out
+* @param outlen
+* @return
+*/
 gboolean rspamd_cryptobox_base64_decode(const char *in, gsize inlen,
-                                                                               unsigned char *out, gsize *outlen);
+                                                                          unsigned char *out, gsize *outlen);
 
 /**
- * Returns TRUE if data looks like a valid base64 string
- * @param in
- * @param inlen
- * @return
- */
+* Returns TRUE if data looks like a valid base64 string
+* @param in
+* @param inlen
+* @return
+*/
 gboolean rspamd_cryptobox_base64_is_valid(const char *in, gsize inlen);
 
 #ifdef __cplusplus
index 742e4db8b1fa1dcfea3ef23efc220557d4f18501..3d974c0c4e3d738c48c2b03b6bafddf3f698fd4e 100644 (file)
@@ -1,18 +1,18 @@
 /*
- * Copyright 2024 Vsevolod Stakhov
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2024 Vsevolod Stakhov
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*    http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 #include "config.h"
 #include "rspamd.h"
 #include "message.h"
@@ -67,25 +67,25 @@ enum rspamd_dkim_param_type {
 #define RSPAMD_DKIM_MAX_ARC_IDX 10
 
 #define msg_err_dkim(...) rspamd_default_log_function(G_LOG_LEVEL_CRITICAL,       \
+                                                                                                        "dkim", ctx->pool->tag.uid, \
+                                                                                                        RSPAMD_LOG_FUNC,            \
+                                                                                                        __VA_ARGS__)
+#define msg_warn_dkim(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,        \
                                                                                                          "dkim", ctx->pool->tag.uid, \
                                                                                                          RSPAMD_LOG_FUNC,            \
                                                                                                          __VA_ARGS__)
-#define msg_warn_dkim(...) rspamd_default_log_function(G_LOG_LEVEL_WARNING,        \
-                                                                                                          "dkim", ctx->pool->tag.uid, \
-                                                                                                          RSPAMD_LOG_FUNC,            \
-                                                                                                          __VA_ARGS__)
 #define msg_info_dkim(...) rspamd_default_log_function(G_LOG_LEVEL_INFO,           \
-                                                                                                          "dkim", ctx->pool->tag.uid, \
-                                                                                                          RSPAMD_LOG_FUNC,            \
-                                                                                                          __VA_ARGS__)
+                                                                                                         "dkim", ctx->pool->tag.uid, \
+                                                                                                         RSPAMD_LOG_FUNC,            \
+                                                                                                         __VA_ARGS__)
 #define msg_debug_dkim(...) rspamd_conditional_debug_fast(NULL, NULL,                                     \
-                                                                                                                 rspamd_dkim_log_id, "dkim", ctx->pool->tag.uid, \
-                                                                                                                 RSPAMD_LOG_FUNC,                                \
-                                                                                                                 __VA_ARGS__)
+                                                                                                                rspamd_dkim_log_id, "dkim", ctx->pool->tag.uid, \
+                                                                                                                RSPAMD_LOG_FUNC,                                \
+                                                                                                                __VA_ARGS__)
 #define msg_debug_dkim_taskless(...) rspamd_conditional_debug_fast(NULL, NULL,                     \
-                                                                                                                                  rspamd_dkim_log_id, "dkim", "", \
-                                                                                                                                  RSPAMD_LOG_FUNC,                \
-                                                                                                                                  __VA_ARGS__)
+                                                                                                                                 rspamd_dkim_log_id, "dkim", "", \
+                                                                                                                                 RSPAMD_LOG_FUNC,                \
+                                                                                                                                 __VA_ARGS__)
 
 INIT_LOG_MODULE(dkim)
 
@@ -790,12 +790,12 @@ rspamd_dkim_add_arc_seal_headers(rspamd_mempool_t *pool,
 }
 
 /**
- * Create new dkim context from signature
- * @param sig message's signature
- * @param pool pool to allocate memory from
- * @param err pointer to error object
- * @return new context or NULL
- */
+* Create new dkim context from signature
+* @param sig message's signature
+* @param pool pool to allocate memory from
+* @param err pointer to error object
+* @return new context or NULL
+*/
 rspamd_dkim_context_t *
 rspamd_create_dkim_context(const char *sig,
                                                   rspamd_mempool_t *pool,
@@ -1097,9 +1097,9 @@ rspamd_create_dkim_context(const char *sig,
 
                                if (state == DKIM_STATE_ERROR) {
                                        /*
-                                        * We need to return from here as state machine won't
-                                        * do any more steps after p == end
-                                        */
+                                       * We need to return from here as state machine won't
+                                       * do any more steps after p == end
+                                       */
                                        if (err) {
                                                msg_info_dkim("dkim parse failed: %e", *err);
                                        }
@@ -1430,8 +1430,8 @@ rspamd_dkim_make_key(const char *keydata,
 
                        return NULL;
                }
-
                if (type == RSPAMD_DKIM_KEY_RSA) {
+#if OPENSSL_VERSION_MAJOR < 3
                        key->key.key_rsa = EVP_PKEY_get1_RSA(key->key_evp);
 
                        if (key->key.key_rsa == NULL) {
@@ -1443,8 +1443,10 @@ rspamd_dkim_make_key(const char *keydata,
 
                                return NULL;
                        }
+#endif
                }
                else {
+#if OPENSSL_VERSION_MAJOR < 3
                        key->key.key_ecdsa = EVP_PKEY_get1_EC_KEY(key->key_evp);
 
                        if (key->key.key_ecdsa == NULL) {
@@ -1456,7 +1458,9 @@ rspamd_dkim_make_key(const char *keydata,
 
                                return NULL;
                        }
+#endif
                }
+
        }
 
        return key;
@@ -1473,15 +1477,16 @@ rspamd_dkim_key_id(rspamd_dkim_key_t *key)
 }
 
 /**
- * Free DKIM key
- * @param key
- */
+* Free DKIM key
+* @param key
+*/
 void rspamd_dkim_key_free(rspamd_dkim_key_t *key)
 {
        if (key->key_evp) {
                EVP_PKEY_free(key->key_evp);
        }
 
+#if OPENSSL_VERSION_MAJOR < 3
        if (key->type == RSPAMD_DKIM_KEY_RSA) {
                if (key->key.key_rsa) {
                        RSA_free(key->key.key_rsa);
@@ -1492,6 +1497,7 @@ void rspamd_dkim_key_free(rspamd_dkim_key_t *key)
                        EC_KEY_free(key->key.key_ecdsa);
                }
        }
+#endif
        /* Nothing in case of eddsa key */
        if (key->key_bio) {
                BIO_free(key->key_bio);
@@ -1507,11 +1513,13 @@ void rspamd_dkim_sign_key_free(rspamd_dkim_sign_key_t *key)
        if (key->key_evp) {
                EVP_PKEY_free(key->key_evp);
        }
+#if OPENSSL_VERSION_MAJOR < 3
        if (key->type == RSPAMD_DKIM_KEY_RSA) {
                if (key->key.key_rsa) {
                        RSA_free(key->key.key_rsa);
                }
        }
+#endif
        if (key->key_bio) {
                BIO_free(key->key_bio);
        }
@@ -1570,9 +1578,9 @@ rspamd_dkim_parse_key(const char *txt, gsize *keylen, GError **err)
                        break;
                case read_tag_before_eqsign:
                        /* Input: spaces before eqsign
-                        * Output: either read a next tag (previous had no value), or read value
-                        * p is moved forward
-                        */
+                       * Output: either read a next tag (previous had no value), or read value
+                       * p is moved forward
+                       */
                        if (*p == '=') {
                                state = read_eqsign;
                        }
@@ -1759,12 +1767,12 @@ rspamd_dkim_dns_cb(struct rdns_reply *reply, gpointer arg)
 }
 
 /**
- * Make DNS request for specified context and obtain and parse key
- * @param ctx dkim context from signature
- * @param resolver dns resolver object
- * @param s async session to make request
- * @return
- */
+* Make DNS request for specified context and obtain and parse key
+* @param ctx dkim context from signature
+* @param resolver dns resolver object
+* @param s async session to make request
+* @return
+*/
 gboolean
 rspamd_get_dkim_key(rspamd_dkim_context_t *ctx,
                                        struct rspamd_task *task,
@@ -2187,8 +2195,8 @@ rspamd_dkim_canonize_body(struct rspamd_task *task,
                                        ;
 
                                /*
-                                * If we have l= tag then we cannot add crlf...
-                                */
+                               * If we have l= tag then we cannot add crlf...
+                               */
                                if (need_crlf) {
                                        /* l is evil... */
                                        if (ctx->len == 0) {
@@ -2461,9 +2469,9 @@ rspamd_dkim_canonize_header(struct rspamd_dkim_common_ctx *ctx,
        bool use_idx = false, is_sign = ctx->is_sign;
 
        /*
-        * TODO:
-        * Temporary hack to prevent linked list being misused until refactored
-        */
+       * TODO:
+       * Temporary hack to prevent linked list being misused until refactored
+       */
        const unsigned int max_list_iters = 1000;
 
        if (count < 0) {
@@ -2509,17 +2517,17 @@ rspamd_dkim_canonize_header(struct rspamd_dkim_common_ctx *ctx,
 
                                if (hdr_cnt <= count) {
                                        /*
-                                        * If DKIM has less headers requested than there are in a
-                                        * message, then it's fine, it allows adding extra headers
-                                        */
+                                       * If DKIM has less headers requested than there are in a
+                                       * message, then it's fine, it allows adding extra headers
+                                       */
                                        return TRUE;
                                }
                        }
                        else {
                                /*
-                                * This branch is used for ARC headers, and it orders them based on
-                                * i=<number> string and not their real order in the list of headers
-                                */
+                               * This branch is used for ARC headers, and it orders them based on
+                               * i=<number> string and not their real order in the list of headers
+                               */
                                char idx_buf[16];
                                int id_len, i;
 
@@ -2692,12 +2700,12 @@ rspamd_dkim_type_to_string(enum rspamd_dkim_type t)
 }
 
 /**
- * Check task for dkim context using dkim key
- * @param ctx dkim verify context
- * @param key dkim key (from cache or from dns request)
- * @param task task to check
- * @return
- */
+* Check task for dkim context using dkim key
+* @param ctx dkim verify context
+* @param key dkim key (from cache or from dns request)
+* @param task task to check
+* @return
+*/
 struct rspamd_dkim_check_result *
 rspamd_dkim_check(rspamd_dkim_context_t *ctx,
                                  rspamd_dkim_key_t *key,
@@ -2916,6 +2924,7 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
 
        switch (key->type) {
        case RSPAMD_DKIM_KEY_RSA:
+#if OPENSSL_VERSION_MAJOR < 3
                if (RSA_verify(nid, raw_digest, dlen, ctx->b, ctx->blen,
                                           key->key.key_rsa) != 1) {
                        msg_debug_dkim("headers rsa verify failed");
@@ -2933,8 +2942,28 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
                                RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
                                ctx->dkim_header);
                }
+#else
+               if (rspamd_cryptobox_verify_compat(nid, ctx->b, ctx->blen, raw_digest, dlen,
+                                                                                  key->key_evp, RSPAMD_CRYPTOBOX_MODE_NIST) != 1) {
+                       msg_debug_dkim("headers rsa verify failed");
+                       ERR_clear_error();
+                       res->rcode = DKIM_REJECT;
+                       res->fail_reason = "headers rsa verify failed";
+
+                       msg_info_dkim(
+                               "%s: headers RSA verification failure; "
+                               "body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",
+                               rspamd_dkim_type_to_string(ctx->common.type),
+                               (int) (body_end - body_start), ctx->common.body_canonicalised,
+                               ctx->common.headers_canonicalised,
+                               ctx->domain, ctx->selector,
+                               RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
+                               ctx->dkim_header);
+               }
+#endif
                break;
        case RSPAMD_DKIM_KEY_ECDSA:
+#if OPENSSL_VERSION_MAJOR < 3
                if (ECDSA_verify(nid, raw_digest, dlen, ctx->b, ctx->blen,
                                                 key->key.key_ecdsa) != 1) {
                        msg_info_dkim(
@@ -2951,7 +2980,26 @@ rspamd_dkim_check(rspamd_dkim_context_t *ctx,
                        res->rcode = DKIM_REJECT;
                        res->fail_reason = "headers ecdsa verify failed";
                }
+#else
+               if (rspamd_cryptobox_verify_compat(nid, ctx->b, ctx->blen, raw_digest, dlen,
+                                                                                  key->key_evp, RSPAMD_CRYPTOBOX_MODE_NIST) != 1) {
+                       msg_info_dkim(
+                               "%s: headers ECDSA verification failure; "
+                               "body length %d->%d; headers length %d; d=%s; s=%s; key_md5=%*xs; orig header: %s",
+                               rspamd_dkim_type_to_string(ctx->common.type),
+                               (int) (body_end - body_start), ctx->common.body_canonicalised,
+                               ctx->common.headers_canonicalised,
+                               ctx->domain, ctx->selector,
+                               RSPAMD_DKIM_KEY_ID_LEN, rspamd_dkim_key_id(key),
+                               ctx->dkim_header);
+                       msg_debug_dkim("headers ecdsa verify failed");
+                       ERR_clear_error();
+                       res->rcode = DKIM_REJECT;
+                       res->fail_reason = "headers ecdsa verify failed";
+               }
+#endif
                break;
+
        case RSPAMD_DKIM_KEY_EDDSA:
                if (!rspamd_cryptobox_verify(ctx->b, ctx->blen, raw_digest, dlen,
                                                                         key->key.key_eddsa, RSPAMD_CRYPTOBOX_MODE_25519)) {
@@ -3200,6 +3248,7 @@ rspamd_dkim_sign_key_load(const char *key, gsize len,
                                goto end;
                        }
                }
+#if OPENSSL_VERSION_MAJOR < 3
                nkey->key.key_rsa = EVP_PKEY_get1_RSA(nkey->key_evp);
                if (nkey->key.key_rsa == NULL) {
                        g_set_error(err,
@@ -3212,6 +3261,7 @@ rspamd_dkim_sign_key_load(const char *key, gsize len,
                        goto end;
                }
                nkey->type = RSPAMD_DKIM_KEY_RSA;
+#endif
        }
 
        REF_INIT_RETAIN(nkey, rspamd_dkim_sign_key_free);
@@ -3536,7 +3586,9 @@ rspamd_dkim_sign(struct rspamd_task *task, const char *selector,
 
        dlen = EVP_MD_CTX_size(ctx->common.headers_hash);
        EVP_DigestFinal_ex(ctx->common.headers_hash, raw_digest, NULL);
+
        if (ctx->key->type == RSPAMD_DKIM_KEY_RSA) {
+#if OPENSSL_VERSION_MAJOR < 3
                sig_len = RSA_size(ctx->key->key.key_rsa);
                sig_buf = g_alloca(sig_len);
 
@@ -3548,6 +3600,13 @@ rspamd_dkim_sign(struct rspamd_task *task, const char *selector,
 
                        return NULL;
                }
+#else
+               sig_len = EVP_PKEY_get_size(ctx->key->key_evp);
+               sig_buf = g_alloca(sig_len);
+               rspamd_cryptobox_sign_compat(NID_sha256, sig_buf, NULL, raw_digest, dlen,
+                                                                        ctx->key->key_evp, RSPAMD_CRYPTOBOX_MODE_NIST);
+               msg_debug("signed RSA");
+#endif
        }
        else if (ctx->key->type == RSPAMD_DKIM_KEY_EDDSA) {
                sig_len = rspamd_cryptobox_signature_bytes(RSPAMD_CRYPTOBOX_MODE_25519);
@@ -3601,11 +3660,19 @@ rspamd_dkim_match_keys(rspamd_dkim_key_t *pk,
                        return FALSE;
                }
        }
+#if OPENSSL_VERSION_MAJOR >= 3
+       else if (EVP_PKEY_eq(pk->key_evp, sk->key_evp) != 1) {
+               g_set_error(err, dkim_error_quark(), DKIM_SIGERROR_KEYHASHMISMATCH,
+                                       "pubkey does not match private key");
+               return FALSE;
+       }
+#else
        else if (EVP_PKEY_cmp(pk->key_evp, sk->key_evp) != 1) {
                g_set_error(err, dkim_error_quark(), DKIM_SIGERROR_KEYHASHMISMATCH,
                                        "pubkey does not match private key");
                return FALSE;
        }
+#endif
 
        return TRUE;
 }