* See https://www.openssl.org/source/license.html for details
*/
-#include "e_gost_err.h"
#include "gost_lcl.h"
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/obj_mac.h>
#include <openssl/ec.h>
#include <openssl/bn.h>
+#include <openssl/store.h>
+#include <openssl/engine.h>
#include <string.h>
#include <stdlib.h>
-#define T(e) ({ if (!(e)) { \
- ERR_print_errors_fp(stderr); \
- OpenSSLDie(__FILE__, __LINE__, #e); \
- } \
- })
-#define TE(e) ({ if (!(e)) { \
- ERR_print_errors_fp(stderr); \
- fprintf(stderr, "Error at %s:%d %s\n", __FILE__, __LINE__, #e); \
- return -1; \
- } \
- })
+#define T(e) \
+ if (!(e)) { \
+ ERR_print_errors_fp(stderr); \
+ OpenSSLDie(__FILE__, __LINE__, #e); \
+ }
+#define TE(e) \
+ if (!(e)) { \
+ ERR_print_errors_fp(stderr); \
+ fprintf(stderr, "Error at %s:%d %s\n", __FILE__, __LINE__, #e); \
+ return -1; \
+ }
#define cRED "\033[1;31m"
#define cDRED "\033[0;31m"
#define cDGREEN "\033[0;32m"
#define cBLUE "\033[1;34m"
#define cDBLUE "\033[0;34m"
+#define cCYAN "\033[1;36m"
#define cNORM "\033[m"
#define TEST_ASSERT(e) {if ((test = (e))) \
- printf(cRED " Test FAILED\n" cNORM); \
+ printf(cRED " Test FAILED" cNORM "\n"); \
else \
- printf(cGREEN " Test passed\n" cNORM);}
+ printf(cGREEN " Test passed" cNORM "\n");}
struct test_sign {
const char *name;
- unsigned int nid;
+ int nid;
size_t bits;
const char *paramset;
};
static void print_test_tf(int err, int val, const char *t, const char *f)
{
if (err == 1)
- printf(cGREEN "%s\n" cNORM, t);
+ printf(cGREEN "%s" cNORM "\n", t);
else
- printf(cRED "%s [%d]\n" cNORM, f, val);
+ printf(cRED "%s [%d]" cNORM "\n", f, val);
}
static void print_test_result(int err)
{
if (err == 1)
- printf(cGREEN "success\n" cNORM);
+ printf(cGREEN "success" cNORM "\n");
else if (err == 0)
- printf(cRED "failure\n" cNORM);
+ printf(cRED "failure" cNORM "\n");
else
ERR_print_errors_fp(stderr);
}
int ret = 0, err;
size_t len = t->bits / 8;
- printf(cBLUE "Test %s:\n" cNORM, t->name);
+ printf(cBLUE "Test %s:" cNORM "\n", t->name);
/* Signature type from size. */
int type = 0;
if (err != 1)
return -1;
+ /* Convert to PEM and back. */
+ BIO *bp;
+ T(bp = BIO_new(BIO_s_secmem()));
+ T(PEM_write_bio_PrivateKey(bp, priv_key, NULL, NULL, 0, NULL, NULL));
+ pkey = NULL;
+ T(PEM_read_bio_PrivateKey(bp, &pkey, NULL, NULL));
+ printf("\tPEM_read_bio_PrivateKey:");
+ /* Yes, it compares only public part. */
+ err = !EVP_PKEY_cmp(priv_key, pkey);
+ print_test_result(!err);
+ ret |= err;
+ EVP_PKEY_free(pkey);
+
+ /* Convert to DER and back, using _PrivateKey_bio API. */
+ T(BIO_reset(bp));
+ T(i2d_PrivateKey_bio(bp, priv_key));
+ T(d2i_PrivateKey_bio(bp, &pkey));
+ printf("\td2i_PrivateKey_bio:\t");
+ err = !EVP_PKEY_cmp(priv_key, pkey);
+ print_test_result(!err);
+ ret |= err;
+ EVP_PKEY_free(pkey);
+
+#if OPENSSL_VERSION_MAJOR >= 3
+ /* Try d2i_PrivateKey_ex_bio, added in 3.0. */
+ T(BIO_reset(bp));
+ T(i2d_PrivateKey_bio(bp, priv_key));
+ T(d2i_PrivateKey_ex_bio(bp, &pkey, NULL, NULL));
+ printf("\td2i_PrivateKey_ex_bio:\t");
+ err = !EVP_PKEY_cmp(priv_key, pkey);
+ print_test_result(!err);
+ ret |= err;
+ EVP_PKEY_free(pkey);
+#endif
+
+ /* Convert to DER and back, using OSSL_STORE API. */
+ T(BIO_reset(bp));
+ T(i2d_PrivateKey_bio(bp, priv_key));
+ printf("\tOSSL_STORE_attach:\t");
+ fflush(stdout);
+ pkey = NULL;
+ OSSL_STORE_CTX *cts;
+ T(cts = OSSL_STORE_attach(bp, "file", NULL, NULL, NULL, NULL, NULL, NULL, NULL));
+ for (;;) {
+ OSSL_STORE_INFO *info = OSSL_STORE_load(cts);
+ if (!info) {
+ ERR_print_errors_fp(stderr);
+ T(OSSL_STORE_eof(cts));
+ break;
+ }
+ if (OSSL_STORE_INFO_get_type(info) == OSSL_STORE_INFO_PKEY) {
+ T((pkey = OSSL_STORE_INFO_get1_PKEY(info)));
+ }
+ OSSL_STORE_INFO_free(info);
+ }
+ OSSL_STORE_close(cts);
+ if (pkey) {
+ err = !EVP_PKEY_cmp(priv_key, pkey);
+ print_test_result(!err);
+ ret |= err;
+ EVP_PKEY_free(pkey);
+ } else
+ printf(cCYAN "skipped" cNORM "\n");
+ BIO_free(bp);
+
+ /* Convert to DER and back, using memory API. */
+ unsigned char *kptr = NULL;
+ int klen;
+ T(klen = i2d_PrivateKey(priv_key, &kptr));
+ const unsigned char *tptr = kptr; /* will be moved by d2i_PrivateKey */
+ pkey = NULL;
+ T(d2i_PrivateKey(type, &pkey, &tptr, klen));
+ printf("\td2i_PrivateKey:\t\t");
+ err = !EVP_PKEY_cmp(priv_key, pkey);
+ print_test_result(!err);
+ ret |= err;
+ EVP_PKEY_free(pkey);
+ OPENSSL_free(kptr);
+
/* Create another key using string interface. */
EVP_PKEY *key1;
T(key1 = EVP_PKEY_new());
err = EVP_PKEY_keygen(ctx1, &key2);
printf("\tEVP_PKEY_*_str:\t\t");
print_test_result(err);
+ ret |= !err;
/* Check if key type and curve_name match expected values. */
int id = EVP_PKEY_id(key2);
{
int ret = 0;
- setenv("OPENSSL_CONF", "../example.conf", 0);
OPENSSL_add_all_algorithms_conf();
- ERR_load_crypto_strings();
struct test_sign *sp;
for (sp = test_signs; sp->name; sp++)
ret |= test_sign(sp);
if (ret)
- printf(cDRED "= Some tests FAILED!\n" cNORM);
+ printf(cDRED "= Some tests FAILED!" cNORM "\n");
else
- printf(cDGREEN "= All tests passed!\n" cNORM);
+ printf(cDGREEN "= All tests passed!" cNORM "\n");
return ret;
}