00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #include <config.h>
00022 
00023 #include <atf-c.h>
00024 
00025 #include <stdio.h>
00026 #include <string.h>
00027 
00028 #include <isc/util.h>
00029 #include <isc/string.h>
00030 
00031 #include "dnstest.h"
00032 
00033 #ifdef HAVE_OPENSSL_GOST
00034 #include "../dst_gost.h"
00035 #include <openssl/err.h>
00036 #include <openssl/objects.h>
00037 #include <openssl/rsa.h>
00038 #include <openssl/engine.h>
00039 #endif
00040 
00041 #ifdef HAVE_PKCS11_GOST
00042 #include "../dst_gost.h"
00043 #include <pk11/internal.h>
00044 #define WANT_GOST_PARAMS
00045 #include <pk11/constants.h>
00046 #include <pkcs11/pkcs11.h>
00047 #endif
00048 
00049 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00050 
00051 
00052 
00053 
00054 unsigned char digest[ISC_GOST_DIGESTLENGTH];
00055 unsigned char buffer[1024];
00056 const char *s;
00057 char str[2 * ISC_GOST_DIGESTLENGTH + 1];
00058 int i = 0;
00059 
00060 isc_result_t
00061 tohexstr(unsigned char *d, unsigned int len, char *out);
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 isc_result_t
00074 tohexstr(unsigned char *d, unsigned int len, char *out) {
00075 
00076         out[0]='\0';
00077         char c_ret[] = "AA";
00078         unsigned int j;
00079         strcat(out, "0x");
00080         for (j = 0; j < len; j++) {
00081                 sprintf(c_ret, "%02X", d[j]);
00082                 strcat(out, c_ret);
00083         }
00084         strcat(out, "\0");
00085         return (ISC_R_SUCCESS);
00086 }
00087 
00088 
00089 #define TEST_INPUT(x) (x), sizeof(x)-1
00090 
00091 typedef struct hash_testcase {
00092         const char *input;
00093         size_t input_len;
00094         const char *result;
00095         int repeats;
00096 } hash_testcase_t;
00097 
00098 ATF_TC(isc_gost_md);
00099 ATF_TC_HEAD(isc_gost_md, tc) {
00100         atf_tc_set_md_var(tc, "descr",
00101                           "GOST R 34.11-94 examples from Wikipedia");
00102 }
00103 ATF_TC_BODY(isc_gost_md, tc) {
00104         isc_gost_t gost;
00105         isc_result_t result;
00106 
00107         UNUSED(tc);
00108 
00109         
00110 
00111 
00112 
00113 
00114         hash_testcase_t testcases[] = {
00115                 
00116                 {
00117                         TEST_INPUT(""),
00118                         "0x981E5F3CA30C841487830F84FB433E1"
00119                         "3AC1101569B9C13584AC483234CD656C0",
00120                         1
00121                 },
00122                 
00123                 {
00124                         TEST_INPUT("a"),
00125                         "0xE74C52DD282183BF37AF0079C9F7805"
00126                         "5715A103F17E3133CEFF1AACF2F403011",
00127                         1
00128                 },
00129                 
00130                 {
00131                         TEST_INPUT("abc"),
00132                         "0xB285056DBF18D7392D7677369524DD1"
00133                         "4747459ED8143997E163B2986F92FD42C",
00134                         1
00135                 },
00136                 
00137                 {
00138                         TEST_INPUT("message digest"),
00139                         "0xBC6041DD2AA401EBFA6E9886734174F"
00140                         "EBDB4729AA972D60F549AC39B29721BA0",
00141                         1
00142                 },
00143                 
00144                 {
00145                         TEST_INPUT("The quick brown fox jumps "
00146                                    "over the lazy dog"),
00147                         "0x9004294A361A508C586FE53D1F1B027"
00148                         "46765E71B765472786E4770D565830A76",
00149                         1
00150                 },
00151 
00152                 
00153                 {
00154                         TEST_INPUT("ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"
00155                                    "fghijklmnopqrstuvwxyz0123456789"),
00156                         "0x73B70A39497DE53A6E08C67B6D4DB85"
00157                         "3540F03E9389299D9B0156EF7E85D0F61",
00158                         1
00159                 },
00160                 
00161                 {
00162                         TEST_INPUT("1234567890123456789012345678901"
00163                                    "2345678901234567890123456789012"
00164                                    "345678901234567890"),
00165                         "0x6BC7B38989B28CF93AE8842BF9D7529"
00166                         "05910A7528A61E5BCE0782DE43E610C90",
00167                         1
00168                 },
00169                 
00170                 {
00171                         TEST_INPUT("This is message, length=32 bytes"),
00172                         "0x2CEFC2F7B7BDC514E18EA57FA74FF35"
00173                         "7E7FA17D652C75F69CB1BE7893EDE48EB",
00174                         1
00175                 },
00176                 
00177                 {
00178                         TEST_INPUT("Suppose the original message "
00179                                    "has length = 50 bytes"),
00180                         "0xC3730C5CBCCACF915AC292676F21E8B"
00181                         "D4EF75331D9405E5F1A61DC3130A65011",
00182                         1
00183                 },
00184                 
00185                 {
00186                         TEST_INPUT("U") ,
00187                         "0x1C4AC7614691BBF427FA2316216BE8F"
00188                         "10D92EDFD37CD1027514C1008F649C4E8",
00189                         128
00190                 },
00191                 
00192                 {
00193                         TEST_INPUT("a") ,
00194                         "0x8693287AA62F9478F7CB312EC0866B6"
00195                         "C4E4A0F11160441E8F4FFCD2715DD554F",
00196                         1000000
00197                 },
00198                 { NULL, 0, NULL, 1 }
00199         };
00200 
00201         result = dns_test_begin(NULL, ISC_FALSE);
00202         ATF_REQUIRE(result == ISC_R_SUCCESS);
00203 
00204         hash_testcase_t *testcase = testcases;
00205 
00206         while (testcase->input != NULL && testcase->result != NULL) {
00207                 result = isc_gost_init(&gost);
00208                 ATF_REQUIRE(result == ISC_R_SUCCESS);
00209                 for(i = 0; i < testcase->repeats; i++) {
00210                         result = isc_gost_update(&gost,
00211                                         (const isc_uint8_t *) testcase->input,
00212                                         testcase->input_len);
00213                         ATF_REQUIRE(result == ISC_R_SUCCESS);
00214                 }
00215                 result = isc_gost_final(&gost, digest);
00216                 ATF_REQUIRE(result == ISC_R_SUCCESS);
00217                 tohexstr(digest, ISC_GOST_DIGESTLENGTH, str);
00218                 ATF_CHECK_STREQ(str, testcase->result);
00219 
00220                 testcase++;
00221         }
00222 
00223         dns_test_end();
00224 }
00225 
00226 ATF_TC(isc_gost_private);
00227 ATF_TC_HEAD(isc_gost_private, tc) {
00228   atf_tc_set_md_var(tc, "descr", "GOST R 34.10-2001 private key");
00229 }
00230 ATF_TC_BODY(isc_gost_private, tc) {
00231         isc_result_t result;
00232         unsigned char privraw[31] = {
00233                 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
00234                 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
00235                 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
00236                 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
00237         };
00238 #ifdef HAVE_OPENSSL_GOST
00239         unsigned char rbuf[32];
00240         unsigned char privasn1[70] = {
00241                 0x30, 0x44, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
00242                 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
00243                 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
00244                 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
00245                 0x02, 0x1e, 0x01, 0x04, 0x21, 0x02, 0x1f, 0x01,
00246                 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
00247                 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11,
00248                 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
00249                 0x1a, 0x1b, 0x1c, 0x1d, 0x1e
00250         };
00251         unsigned char abuf[71];
00252         unsigned char gost_dummy_key[71] = {
00253                 0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06,
00254                 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30,
00255                 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02,
00256                 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02,
00257                 0x02, 0x1e, 0x01, 0x04, 0x22, 0x02, 0x20, 0x1b,
00258                 0x3f, 0x94, 0xf7, 0x1a, 0x5f, 0x2f, 0xe7, 0xe5,
00259                 0x74, 0x0b, 0x8c, 0xd4, 0xb7, 0x18, 0xdd, 0x65,
00260                 0x68, 0x26, 0xd1, 0x54, 0xfb, 0x77, 0xba, 0x63,
00261                 0x72, 0xd9, 0xf0, 0x63, 0x87, 0xe0, 0xd6
00262         };
00263         EVP_PKEY *pkey;
00264         EC_KEY *eckey;
00265         BIGNUM *privkey;
00266         const BIGNUM *privkey1;
00267         const unsigned char *p;
00268         int len;
00269         unsigned char *q;
00270 
00271         result = dns_test_begin(NULL, ISC_FALSE);
00272         ATF_REQUIRE(result == ISC_R_SUCCESS);
00273 
00274         
00275         privkey = BN_bin2bn(privraw, (int) sizeof(privraw), NULL);
00276         ATF_REQUIRE(privkey != NULL);
00277         p = gost_dummy_key;
00278         pkey = NULL;
00279         ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00280                                    (long) sizeof(gost_dummy_key)) != NULL);
00281         ATF_REQUIRE(pkey != NULL);
00282         ATF_REQUIRE(EVP_PKEY_bits(pkey) == 256);
00283         eckey = EVP_PKEY_get0(pkey);
00284         ATF_REQUIRE(eckey != NULL);
00285         ATF_REQUIRE(EC_KEY_set_private_key(eckey, privkey) == 1);
00286         BN_clear_free(privkey);
00287 
00288         
00289         len = i2d_PrivateKey(pkey, NULL);
00290         ATF_REQUIRE(len == 70);
00291         q = abuf;
00292         ATF_REQUIRE(i2d_PrivateKey(pkey, &q) == len);
00293         ATF_REQUIRE(memcmp(abuf, privasn1, len) == 0);
00294         EVP_PKEY_free(pkey);
00295 
00296         
00297         p = privasn1;
00298         pkey = NULL;
00299         ATF_REQUIRE(d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
00300                                    (long) len) != NULL);
00301         ATF_REQUIRE(pkey != NULL);
00302         eckey = EVP_PKEY_get0(pkey);
00303         ATF_REQUIRE(eckey != NULL);
00304         privkey1 = EC_KEY_get0_private_key(eckey);
00305         len = BN_num_bytes(privkey1);
00306         ATF_REQUIRE(len == 31);
00307         ATF_REQUIRE(BN_bn2bin(privkey1, rbuf) == len);
00308         ATF_REQUIRE(memcmp(rbuf, privraw, len) == 0);
00309 
00310         dns_test_end();
00311 #else
00312         CK_BBOOL truevalue = TRUE;
00313         CK_BBOOL falsevalue = FALSE;
00314         CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
00315         CK_KEY_TYPE keyType = CKK_GOSTR3410;
00316         CK_ATTRIBUTE keyTemplate[] =
00317         {
00318                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00319                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00320                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00321                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00322                 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00323                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00324                 { CKA_VALUE, privraw, sizeof(privraw) },
00325                 { CKA_GOSTR3410_PARAMS, pk11_gost_a_paramset,
00326                   (CK_ULONG) sizeof(pk11_gost_a_paramset) },
00327                 { CKA_GOSTR3411_PARAMS, pk11_gost_paramset,
00328                   (CK_ULONG) sizeof(pk11_gost_paramset) }
00329         };
00330         CK_MECHANISM mech = { CKM_GOSTR3410_WITH_GOSTR3411, NULL, 0 };
00331         CK_BYTE sig[64];
00332         CK_ULONG siglen;
00333         pk11_context_t pk11_ctx;
00334 
00335         result = dns_test_begin(NULL, ISC_FALSE);
00336         ATF_REQUIRE(result == ISC_R_SUCCESS);
00337 
00338         
00339         memset(&pk11_ctx, 0, sizeof(pk11_ctx));
00340         ATF_REQUIRE(pk11_get_session(&pk11_ctx, OP_GOST, ISC_TRUE,
00341                                      ISC_FALSE, ISC_FALSE, NULL,
00342                                      pk11_get_best_token(OP_GOST)) ==
00343                     ISC_R_SUCCESS);
00344         pk11_ctx.object = CK_INVALID_HANDLE;
00345         pk11_ctx.ontoken = ISC_FALSE;
00346         ATF_REQUIRE(pkcs_C_CreateObject(pk11_ctx.session, keyTemplate,
00347                                         (CK_ULONG) 9, &pk11_ctx.object) ==
00348                     CKR_OK);
00349         ATF_REQUIRE(pk11_ctx.object != CK_INVALID_HANDLE);
00350 
00351         
00352         ATF_REQUIRE(pkcs_C_SignInit(pk11_ctx.session, &mech,
00353                                     pk11_ctx.object) == CKR_OK);
00354         siglen = 0;
00355         ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
00356                                 NULL, &siglen) == CKR_OK);
00357         ATF_REQUIRE(siglen == 64);
00358         ATF_REQUIRE(pkcs_C_Sign(pk11_ctx.session, sig, 64,
00359                                 sig, &siglen) == CKR_OK);
00360         ATF_REQUIRE(siglen == 64);
00361 
00362         dns_test_end();
00363 #endif
00364 };
00365 #else
00366 ATF_TC(untested);
00367 ATF_TC_HEAD(untested, tc) {
00368         atf_tc_set_md_var(tc, "descr", "skipping gost test");
00369 }
00370 ATF_TC_BODY(untested, tc) {
00371         UNUSED(tc);
00372         atf_tc_skip("GOST not available");
00373 }
00374 #endif
00375 
00376 
00377 
00378 ATF_TP_ADD_TCS(tp) {
00379 #if defined(HAVE_OPENSSL_GOST) || defined(HAVE_PKCS11_GOST)
00380         ATF_TP_ADD_TC(tp, isc_gost_md);
00381         ATF_TP_ADD_TC(tp, isc_gost_private);
00382 #else
00383         ATF_TP_ADD_TC(tp, untested);
00384 #endif
00385         return (atf_no_error());
00386 }
00387