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