pkcs11dsa_link.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 #ifdef PKCS11CRYPTO
00020 
00021 #include <config.h>
00022 
00023 #include <string.h>
00024 
00025 #include <isc/entropy.h>
00026 #include <isc/mem.h>
00027 #include <isc/sha1.h>
00028 #include <isc/util.h>
00029 
00030 #include <dst/result.h>
00031 
00032 #include "dst_internal.h"
00033 #include "dst_parse.h"
00034 #include "dst_pkcs11.h"
00035 
00036 #include <pk11/internal.h>
00037 
00038 /*
00039  * FIPS 186-2 DSA keys:
00040  *  mechanisms:
00041  *    CKM_DSA_SHA1,
00042  *    CKM_DSA_KEY_PAIR_GEN,
00043  *    CKM_DSA_PARAMETER_GEN
00044  *  domain parameters:
00045  *    object class CKO_DOMAIN_PARAMETERS
00046  *    key type CKK_DSA
00047  *    attribute CKA_PRIME (prime p)
00048  *    attribute CKA_SUBPRIME (subprime q)
00049  *    attribute CKA_BASE (base g)
00050  *    optional attribute CKA_PRIME_BITS (p length in bits)
00051  *  public keys:
00052  *    object class CKO_PUBLIC_KEY
00053  *    key type CKK_DSA
00054  *    attribute CKA_PRIME (prime p)
00055  *    attribute CKA_SUBPRIME (subprime q)
00056  *    attribute CKA_BASE (base g)
00057  *    attribute CKA_VALUE (public value y)
00058  *  private keys:
00059  *    object class CKO_PRIVATE_KEY
00060  *    key type CKK_DSA
00061  *    attribute CKA_PRIME (prime p)
00062  *    attribute CKA_SUBPRIME (subprime q)
00063  *    attribute CKA_BASE (base g)
00064  *    attribute CKA_VALUE (private value x)
00065  *  reuse CKA_PRIVATE_EXPONENT for key pair private value
00066  */
00067 
00068 #define CKA_VALUE2      CKA_PRIVATE_EXPONENT
00069 
00070 #define DST_RET(a) {ret = a; goto err;}
00071 
00072 static CK_BBOOL truevalue = TRUE;
00073 static CK_BBOOL falsevalue = FALSE;
00074 
00075 static isc_result_t pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data);
00076 static void pkcs11dsa_destroy(dst_key_t *key);
00077 
00078 static isc_result_t
00079 pkcs11dsa_createctx_sign(dst_key_t *key, dst_context_t *dctx) {
00080         CK_RV rv;
00081         CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 };
00082         CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
00083         CK_KEY_TYPE keyType = CKK_DSA;
00084         CK_ATTRIBUTE keyTemplate[] =
00085         {
00086                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00087                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00088                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00089                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00090                 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00091                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00092                 { CKA_PRIME, NULL, 0 },
00093                 { CKA_SUBPRIME, NULL, 0 },
00094                 { CKA_BASE, NULL, 0 },
00095                 { CKA_VALUE, NULL, 0 }
00096         };
00097         CK_ATTRIBUTE *attr;
00098         pk11_object_t *dsa;
00099         pk11_context_t *pk11_ctx;
00100         isc_result_t ret;
00101         unsigned int i;
00102 
00103         pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
00104                                                   sizeof(*pk11_ctx));
00105         if (pk11_ctx == NULL)
00106                 return (ISC_R_NOMEMORY);
00107         ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
00108                                ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
00109         if (ret != ISC_R_SUCCESS)
00110                 goto err;
00111 
00112         dsa = key->keydata.pkey;
00113         if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) {
00114                 pk11_ctx->ontoken = dsa->ontoken;
00115                 pk11_ctx->object = dsa->object;
00116                 goto token_key;
00117         }
00118 
00119         for (attr = pk11_attribute_first(dsa);
00120              attr != NULL;
00121              attr = pk11_attribute_next(dsa, attr))
00122                 switch (attr->type) {
00123                 case CKA_PRIME:
00124                         INSIST(keyTemplate[6].type == attr->type);
00125                         keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
00126                                                             attr->ulValueLen);
00127                         if (keyTemplate[6].pValue == NULL)
00128                                 DST_RET(ISC_R_NOMEMORY);
00129                         memmove(keyTemplate[6].pValue, attr->pValue,
00130                                 attr->ulValueLen);
00131                         keyTemplate[6].ulValueLen = attr->ulValueLen;
00132                         break;
00133                 case CKA_SUBPRIME:
00134                         INSIST(keyTemplate[7].type == attr->type);
00135                         keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
00136                                                             attr->ulValueLen);
00137                         if (keyTemplate[7].pValue == NULL)
00138                                 DST_RET(ISC_R_NOMEMORY);
00139                         memmove(keyTemplate[7].pValue, attr->pValue,
00140                                 attr->ulValueLen);
00141                         keyTemplate[7].ulValueLen = attr->ulValueLen;
00142                         break;
00143                 case CKA_BASE:
00144                         INSIST(keyTemplate[8].type == attr->type);
00145                         keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
00146                                                             attr->ulValueLen);
00147                         if (keyTemplate[8].pValue == NULL)
00148                                 DST_RET(ISC_R_NOMEMORY);
00149                         memmove(keyTemplate[8].pValue, attr->pValue,
00150                                 attr->ulValueLen);
00151                         keyTemplate[8].ulValueLen = attr->ulValueLen;
00152                         break;
00153                 case CKA_VALUE2:
00154                         INSIST(keyTemplate[9].type == CKA_VALUE);
00155                         keyTemplate[9].pValue = isc_mem_get(dctx->mctx,
00156                                                             attr->ulValueLen);
00157                         if (keyTemplate[9].pValue == NULL)
00158                                 DST_RET(ISC_R_NOMEMORY);
00159                         memmove(keyTemplate[9].pValue, attr->pValue,
00160                                 attr->ulValueLen);
00161                         keyTemplate[9].ulValueLen = attr->ulValueLen;
00162                         break;
00163                 }
00164         pk11_ctx->object = CK_INVALID_HANDLE;
00165         pk11_ctx->ontoken = ISC_FALSE;
00166         PK11_RET(pkcs_C_CreateObject,
00167                  (pk11_ctx->session,
00168                   keyTemplate, (CK_ULONG) 10,
00169                   &pk11_ctx->object),
00170                  ISC_R_FAILURE);
00171 
00172     token_key:
00173 
00174         PK11_RET(pkcs_C_SignInit,
00175                  (pk11_ctx->session, &mech, pk11_ctx->object),
00176                  ISC_R_FAILURE);
00177 
00178         dctx->ctxdata.pk11_ctx = pk11_ctx;
00179 
00180         for (i = 6; i <= 9; i++)
00181                 if (keyTemplate[i].pValue != NULL) {
00182                         memset(keyTemplate[i].pValue, 0,
00183                                keyTemplate[i].ulValueLen);
00184                         isc_mem_put(dctx->mctx,
00185                                     keyTemplate[i].pValue,
00186                                     keyTemplate[i].ulValueLen);
00187                 }
00188 
00189         return (ISC_R_SUCCESS);
00190 
00191     err:
00192         if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
00193                 (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object);
00194         for (i = 6; i <= 9; i++)
00195                 if (keyTemplate[i].pValue != NULL) {
00196                         memset(keyTemplate[i].pValue, 0,
00197                                keyTemplate[i].ulValueLen);
00198                         isc_mem_put(dctx->mctx,
00199                                     keyTemplate[i].pValue,
00200                                     keyTemplate[i].ulValueLen);
00201                 }
00202         pk11_return_session(pk11_ctx);
00203         memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00204         isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00205 
00206         return (ret);
00207 }
00208 
00209 static isc_result_t
00210 pkcs11dsa_createctx_verify(dst_key_t *key, dst_context_t *dctx) {
00211         CK_RV rv;
00212         CK_MECHANISM mech = { CKM_DSA_SHA1, NULL, 0 };
00213         CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
00214         CK_KEY_TYPE keyType = CKK_DSA;
00215         CK_ATTRIBUTE keyTemplate[] =
00216         {
00217                 { CKA_CLASS, &keyClass, (CK_ULONG) sizeof(keyClass) },
00218                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00219                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00220                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00221                 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
00222                 { CKA_PRIME, NULL, 0 },
00223                 { CKA_SUBPRIME, NULL, 0 },
00224                 { CKA_BASE, NULL, 0 },
00225                 { CKA_VALUE, NULL, 0 }
00226         };
00227         CK_ATTRIBUTE *attr;
00228         pk11_object_t *dsa;
00229         pk11_context_t *pk11_ctx;
00230         isc_result_t ret;
00231         unsigned int i;
00232 
00233         pk11_ctx = (pk11_context_t *) isc_mem_get(dctx->mctx,
00234                                                   sizeof(*pk11_ctx));
00235         if (pk11_ctx == NULL)
00236                 return (ISC_R_NOMEMORY);
00237         ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
00238                                ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
00239         if (ret != ISC_R_SUCCESS)
00240                 goto err;
00241 
00242         dsa = key->keydata.pkey;
00243         if (dsa->ontoken && (dsa->object != CK_INVALID_HANDLE)) {
00244                 pk11_ctx->ontoken = dsa->ontoken;
00245                 pk11_ctx->object = dsa->object;
00246                 goto token_key;
00247         }
00248 
00249         for (attr = pk11_attribute_first(dsa);
00250              attr != NULL;
00251              attr = pk11_attribute_next(dsa, attr))
00252                 switch (attr->type) {
00253                 case CKA_PRIME:
00254                         INSIST(keyTemplate[5].type == attr->type);
00255                         keyTemplate[5].pValue = isc_mem_get(dctx->mctx,
00256                                                             attr->ulValueLen);
00257                         if (keyTemplate[5].pValue == NULL)
00258                                 DST_RET(ISC_R_NOMEMORY);
00259                         memmove(keyTemplate[5].pValue, attr->pValue,
00260                                 attr->ulValueLen);
00261                         keyTemplate[5].ulValueLen = attr->ulValueLen;
00262                         break;
00263                 case CKA_SUBPRIME:
00264                         INSIST(keyTemplate[6].type == attr->type);
00265                         keyTemplate[6].pValue = isc_mem_get(dctx->mctx,
00266                                                             attr->ulValueLen);
00267                         if (keyTemplate[6].pValue == NULL)
00268                                 DST_RET(ISC_R_NOMEMORY);
00269                         memmove(keyTemplate[6].pValue, attr->pValue,
00270                                 attr->ulValueLen);
00271                         keyTemplate[6].ulValueLen = attr->ulValueLen;
00272                         break;
00273                 case CKA_BASE:
00274                         INSIST(keyTemplate[7].type == attr->type);
00275                         keyTemplate[7].pValue = isc_mem_get(dctx->mctx,
00276                                                             attr->ulValueLen);
00277                         if (keyTemplate[7].pValue == NULL)
00278                                 DST_RET(ISC_R_NOMEMORY);
00279                         memmove(keyTemplate[7].pValue, attr->pValue,
00280                                 attr->ulValueLen);
00281                         keyTemplate[7].ulValueLen = attr->ulValueLen;
00282                         break;
00283                 case CKA_VALUE:
00284                         INSIST(keyTemplate[8].type == attr->type);
00285                         keyTemplate[8].pValue = isc_mem_get(dctx->mctx,
00286                                                             attr->ulValueLen);
00287                         if (keyTemplate[8].pValue == NULL)
00288                                 DST_RET(ISC_R_NOMEMORY);
00289                         memmove(keyTemplate[8].pValue, attr->pValue,
00290                                 attr->ulValueLen);
00291                         keyTemplate[8].ulValueLen = attr->ulValueLen;
00292                         break;
00293                 }
00294         pk11_ctx->object = CK_INVALID_HANDLE;
00295         pk11_ctx->ontoken = ISC_FALSE;
00296         PK11_RET(pkcs_C_CreateObject,
00297                  (pk11_ctx->session,
00298                   keyTemplate, (CK_ULONG) 9,
00299                   &pk11_ctx->object),
00300                  ISC_R_FAILURE);
00301 
00302     token_key:
00303 
00304         PK11_RET(pkcs_C_VerifyInit,
00305                  (pk11_ctx->session, &mech, pk11_ctx->object),
00306                  ISC_R_FAILURE);
00307 
00308         dctx->ctxdata.pk11_ctx = pk11_ctx;
00309 
00310         for (i = 5; i <= 8; i++)
00311                 if (keyTemplate[i].pValue != NULL) {
00312                         memset(keyTemplate[i].pValue, 0,
00313                                keyTemplate[i].ulValueLen);
00314                         isc_mem_put(dctx->mctx,
00315                                     keyTemplate[i].pValue,
00316                                     keyTemplate[i].ulValueLen);
00317                 }
00318 
00319         return (ISC_R_SUCCESS);
00320 
00321     err:
00322         if (!pk11_ctx->ontoken && (pk11_ctx->object != CK_INVALID_HANDLE))
00323                 (void) pkcs_C_DestroyObject(pk11_ctx->session, pk11_ctx->object);
00324         for (i = 5; i <= 8; i++)
00325                 if (keyTemplate[i].pValue != NULL) {
00326                         memset(keyTemplate[i].pValue, 0,
00327                                keyTemplate[i].ulValueLen);
00328                         isc_mem_put(dctx->mctx,
00329                                     keyTemplate[i].pValue,
00330                                     keyTemplate[i].ulValueLen);
00331                 }
00332         pk11_return_session(pk11_ctx);
00333         memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00334         isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00335 
00336         return (ret);
00337 }
00338 
00339 static isc_result_t
00340 pkcs11dsa_createctx(dst_key_t *key, dst_context_t *dctx) {
00341         if (dctx->use == DO_SIGN)
00342                 return (pkcs11dsa_createctx_sign(key, dctx));
00343         else
00344                 return (pkcs11dsa_createctx_verify(key, dctx));
00345 }
00346 
00347 static void
00348 pkcs11dsa_destroyctx(dst_context_t *dctx) {
00349         pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00350 
00351         if (pk11_ctx != NULL) {
00352                 if (!pk11_ctx->ontoken &&
00353                     (pk11_ctx->object != CK_INVALID_HANDLE))
00354                         (void) pkcs_C_DestroyObject(pk11_ctx->session,
00355                                                pk11_ctx->object);
00356                 pk11_return_session(pk11_ctx);
00357                 memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00358                 isc_mem_put(dctx->mctx, pk11_ctx, sizeof(*pk11_ctx));
00359                 dctx->ctxdata.pk11_ctx = NULL;
00360         }
00361 }
00362 
00363 static isc_result_t
00364 pkcs11dsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
00365         CK_RV rv;
00366         pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00367         isc_result_t ret = ISC_R_SUCCESS;
00368 
00369         if (dctx->use == DO_SIGN)
00370                 PK11_CALL(pkcs_C_SignUpdate,
00371                           (pk11_ctx->session,
00372                            (CK_BYTE_PTR) data->base,
00373                            (CK_ULONG) data->length),
00374                           ISC_R_FAILURE);
00375         else
00376                 PK11_CALL(pkcs_C_VerifyUpdate,
00377                           (pk11_ctx->session,
00378                            (CK_BYTE_PTR) data->base,
00379                            (CK_ULONG) data->length),
00380                           ISC_R_FAILURE);
00381         return (ret);
00382 }
00383 
00384 static isc_result_t
00385 pkcs11dsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
00386         CK_RV rv;
00387         CK_ULONG siglen = ISC_SHA1_DIGESTLENGTH * 2;
00388         isc_region_t r;
00389         pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00390         isc_result_t ret = ISC_R_SUCCESS;
00391 
00392         isc_buffer_availableregion(sig, &r);
00393         if (r.length < ISC_SHA1_DIGESTLENGTH * 2 + 1)
00394                 return (ISC_R_NOSPACE);
00395 
00396         PK11_RET(pkcs_C_SignFinal,
00397                  (pk11_ctx->session, (CK_BYTE_PTR) r.base + 1, &siglen),
00398                  DST_R_SIGNFAILURE);
00399         if (siglen != ISC_SHA1_DIGESTLENGTH * 2)
00400                 return (DST_R_SIGNFAILURE);
00401 
00402         *r.base = (dctx->key->key_size - 512)/64;
00403         isc_buffer_add(sig, ISC_SHA1_DIGESTLENGTH * 2 + 1);
00404 
00405     err:
00406         return (ret);
00407 }
00408 
00409 static isc_result_t
00410 pkcs11dsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
00411         CK_RV rv;
00412         pk11_context_t *pk11_ctx = dctx->ctxdata.pk11_ctx;
00413         isc_result_t ret = ISC_R_SUCCESS;
00414 
00415         PK11_CALL(pkcs_C_VerifyFinal,
00416                   (pk11_ctx->session,
00417                    (CK_BYTE_PTR) sig->base + 1,
00418                    (CK_ULONG) sig->length - 1),
00419                   DST_R_VERIFYFAILURE);
00420         return (ret);
00421 }
00422 
00423 static isc_boolean_t
00424 pkcs11dsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
00425         pk11_object_t *dsa1, *dsa2;
00426         CK_ATTRIBUTE *attr1, *attr2;
00427 
00428         dsa1 = key1->keydata.pkey;
00429         dsa2 = key2->keydata.pkey;
00430 
00431         if ((dsa1 == NULL) && (dsa2 == NULL))
00432                 return (ISC_TRUE);
00433         else if ((dsa1 == NULL) || (dsa2 == NULL))
00434                 return (ISC_FALSE);
00435 
00436         attr1 = pk11_attribute_bytype(dsa1, CKA_PRIME);
00437         attr2 = pk11_attribute_bytype(dsa2, CKA_PRIME);
00438         if ((attr1 == NULL) && (attr2 == NULL))
00439                 return (ISC_TRUE);
00440         else if ((attr1 == NULL) || (attr2 == NULL) ||
00441                  (attr1->ulValueLen != attr2->ulValueLen) ||
00442                  memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00443                 return (ISC_FALSE);
00444 
00445         attr1 = pk11_attribute_bytype(dsa1, CKA_SUBPRIME);
00446         attr2 = pk11_attribute_bytype(dsa2, CKA_SUBPRIME);
00447         if ((attr1 == NULL) && (attr2 == NULL))
00448                 return (ISC_TRUE);
00449         else if ((attr1 == NULL) || (attr2 == NULL) ||
00450                  (attr1->ulValueLen != attr2->ulValueLen) ||
00451                  memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00452                 return (ISC_FALSE);
00453 
00454         attr1 = pk11_attribute_bytype(dsa1, CKA_BASE);
00455         attr2 = pk11_attribute_bytype(dsa2, CKA_BASE);
00456         if ((attr1 == NULL) && (attr2 == NULL))
00457                 return (ISC_TRUE);
00458         else if ((attr1 == NULL) || (attr2 == NULL) ||
00459                  (attr1->ulValueLen != attr2->ulValueLen) ||
00460                  memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00461                 return (ISC_FALSE);
00462 
00463         attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE);
00464         attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE);
00465         if ((attr1 == NULL) && (attr2 == NULL))
00466                 return (ISC_TRUE);
00467         else if ((attr1 == NULL) || (attr2 == NULL) ||
00468                  (attr1->ulValueLen != attr2->ulValueLen) ||
00469                  memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen))
00470                 return (ISC_FALSE);
00471 
00472         attr1 = pk11_attribute_bytype(dsa1, CKA_VALUE2);
00473         attr2 = pk11_attribute_bytype(dsa2, CKA_VALUE2);
00474         if (((attr1 != NULL) || (attr2 != NULL)) &&
00475             ((attr1 == NULL) || (attr2 == NULL) ||
00476              (attr1->ulValueLen != attr2->ulValueLen) ||
00477              memcmp(attr1->pValue, attr2->pValue, attr1->ulValueLen)))
00478                 return (ISC_FALSE);
00479 
00480         if (!dsa1->ontoken && !dsa2->ontoken)
00481                 return (ISC_TRUE);
00482         else if (dsa1->ontoken || dsa2->ontoken ||
00483                  (dsa1->object != dsa2->object))
00484                 return (ISC_FALSE);
00485 
00486         return (ISC_TRUE);
00487 }
00488 
00489 static isc_result_t
00490 pkcs11dsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
00491         CK_RV rv;
00492         CK_MECHANISM mech = { CKM_DSA_PARAMETER_GEN, NULL, 0 };
00493         CK_OBJECT_HANDLE dp = CK_INVALID_HANDLE;
00494         CK_OBJECT_CLASS dpClass = CKO_DOMAIN_PARAMETERS;
00495         CK_KEY_TYPE  keyType = CKK_DSA;
00496         CK_ULONG bits = 0;
00497         CK_ATTRIBUTE dpTemplate[] =
00498         {
00499                 { CKA_CLASS, &dpClass, (CK_ULONG) sizeof(dpClass) },
00500                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00501                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00502                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00503                 { CKA_PRIME_BITS, &bits, (CK_ULONG) sizeof(bits) },
00504         };
00505         CK_OBJECT_HANDLE pub = CK_INVALID_HANDLE;
00506         CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
00507         CK_ATTRIBUTE pubTemplate[] =
00508         {
00509                 { CKA_CLASS, &pubClass, (CK_ULONG) sizeof(pubClass) },
00510                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00511                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00512                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00513                 { CKA_VERIFY, &truevalue, (CK_ULONG) sizeof(truevalue) },
00514                 { CKA_PRIME, NULL, 0 },
00515                 { CKA_SUBPRIME, NULL, 0 },
00516                 { CKA_BASE, NULL, 0 }
00517         };
00518         CK_OBJECT_HANDLE priv = CK_INVALID_HANDLE;
00519         CK_OBJECT_HANDLE privClass = CKO_PRIVATE_KEY;
00520         CK_ATTRIBUTE privTemplate[] =
00521         {
00522                 { CKA_CLASS, &privClass, (CK_ULONG) sizeof(privClass) },
00523                 { CKA_KEY_TYPE, &keyType, (CK_ULONG) sizeof(keyType) },
00524                 { CKA_TOKEN, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00525                 { CKA_PRIVATE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00526                 { CKA_SENSITIVE, &falsevalue, (CK_ULONG) sizeof(falsevalue) },
00527                 { CKA_EXTRACTABLE, &truevalue, (CK_ULONG) sizeof(truevalue) },
00528                 { CKA_SIGN, &truevalue, (CK_ULONG) sizeof(truevalue) },
00529         };
00530         CK_ATTRIBUTE *attr;
00531         pk11_object_t *dsa;
00532         pk11_context_t *pk11_ctx;
00533         isc_result_t ret;
00534         unsigned int i;
00535 
00536         UNUSED(unused);
00537         UNUSED(callback);
00538 
00539         pk11_ctx = (pk11_context_t *) isc_mem_get(key->mctx,
00540                                                   sizeof(*pk11_ctx));
00541         if (pk11_ctx == NULL)
00542                 return (ISC_R_NOMEMORY);
00543         ret = pk11_get_session(pk11_ctx, OP_DSA, ISC_TRUE, ISC_FALSE,
00544                                ISC_FALSE, NULL, pk11_get_best_token(OP_DSA));
00545         if (ret != ISC_R_SUCCESS)
00546                 goto err;
00547 
00548         bits = key->key_size;
00549         PK11_RET(pkcs_C_GenerateKey,
00550                  (pk11_ctx->session, &mech, dpTemplate, (CK_ULONG) 5, &dp),
00551                  DST_R_CRYPTOFAILURE);
00552 
00553         dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
00554         if (dsa == NULL)
00555                 DST_RET(ISC_R_NOMEMORY);
00556         memset(dsa, 0, sizeof(*dsa));
00557         key->keydata.pkey = dsa;
00558         dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5);
00559         if (dsa->repr == NULL)
00560                 DST_RET(ISC_R_NOMEMORY);
00561         memset(dsa->repr, 0, sizeof(*attr) * 5);
00562         dsa->attrcnt = 5;
00563 
00564         attr = dsa->repr;
00565         attr[0].type = CKA_PRIME;
00566         attr[1].type = CKA_SUBPRIME;
00567         attr[2].type = CKA_BASE;
00568         attr[3].type = CKA_VALUE;
00569         attr[4].type = CKA_VALUE2;
00570 
00571         PK11_RET(pkcs_C_GetAttributeValue,
00572                  (pk11_ctx->session, dp, attr, 3),
00573                  DST_R_CRYPTOFAILURE);
00574 
00575         for (i = 0; i <= 2; i++) {
00576                 attr[i].pValue = isc_mem_get(key->mctx, attr[i].ulValueLen);
00577                 if (attr[i].pValue == NULL)
00578                         DST_RET(ISC_R_NOMEMORY);
00579                 memset(attr[i].pValue, 0, attr[i].ulValueLen);
00580         }
00581         PK11_RET(pkcs_C_GetAttributeValue,
00582                  (pk11_ctx->session, dp, attr, 3),
00583                  DST_R_CRYPTOFAILURE);
00584         pubTemplate[5].pValue = attr[0].pValue;
00585         pubTemplate[5].ulValueLen = attr[0].ulValueLen;
00586         pubTemplate[6].pValue = attr[1].pValue;
00587         pubTemplate[6].ulValueLen = attr[1].ulValueLen;
00588         pubTemplate[7].pValue = attr[2].pValue;
00589         pubTemplate[7].ulValueLen = attr[2].ulValueLen;
00590 
00591         mech.mechanism = CKM_DSA_KEY_PAIR_GEN;
00592         PK11_RET(pkcs_C_GenerateKeyPair,
00593                  (pk11_ctx->session, &mech,
00594                   pubTemplate, (CK_ULONG) 8,
00595                   privTemplate, (CK_ULONG) 7,
00596                   &pub, &priv),
00597                  DST_R_CRYPTOFAILURE);
00598 
00599         attr = dsa->repr;
00600         attr += 3;
00601         PK11_RET(pkcs_C_GetAttributeValue,
00602                  (pk11_ctx->session, pub, attr, 1),
00603                  DST_R_CRYPTOFAILURE);
00604         attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
00605         if (attr->pValue == NULL)
00606                 DST_RET(ISC_R_NOMEMORY);
00607         memset(attr->pValue, 0, attr->ulValueLen);
00608         PK11_RET(pkcs_C_GetAttributeValue,
00609                  (pk11_ctx->session, pub, attr, 1),
00610                  DST_R_CRYPTOFAILURE);
00611 
00612         attr++;
00613         attr->type = CKA_VALUE;
00614         PK11_RET(pkcs_C_GetAttributeValue,
00615                  (pk11_ctx->session, priv, attr, 1),
00616                  DST_R_CRYPTOFAILURE);
00617         attr->pValue = isc_mem_get(key->mctx, attr->ulValueLen);
00618         if (attr->pValue == NULL)
00619                 DST_RET(ISC_R_NOMEMORY);
00620         memset(attr->pValue, 0, attr->ulValueLen);
00621         PK11_RET(pkcs_C_GetAttributeValue,
00622                  (pk11_ctx->session, priv, attr, 1),
00623                  DST_R_CRYPTOFAILURE);
00624         attr->type = CKA_VALUE2;
00625 
00626         (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
00627         (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
00628         (void) pkcs_C_DestroyObject(pk11_ctx->session, dp);
00629         pk11_return_session(pk11_ctx);
00630         memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00631         isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
00632 
00633         return (ISC_R_SUCCESS);
00634 
00635     err:
00636         pkcs11dsa_destroy(key);
00637         if (priv != CK_INVALID_HANDLE)
00638                 (void) pkcs_C_DestroyObject(pk11_ctx->session, priv);
00639         if (pub != CK_INVALID_HANDLE)
00640                 (void) pkcs_C_DestroyObject(pk11_ctx->session, pub);
00641         if (dp != CK_INVALID_HANDLE)
00642                 (void) pkcs_C_DestroyObject(pk11_ctx->session, dp);
00643         pk11_return_session(pk11_ctx);
00644         memset(pk11_ctx, 0, sizeof(*pk11_ctx));
00645         isc_mem_put(key->mctx, pk11_ctx, sizeof(*pk11_ctx));
00646 
00647         return (ret);
00648 }
00649 
00650 static isc_boolean_t
00651 pkcs11dsa_isprivate(const dst_key_t *key) {
00652         pk11_object_t *dsa = key->keydata.pkey;
00653         CK_ATTRIBUTE *attr;
00654 
00655         if (dsa == NULL)
00656                 return (ISC_FALSE);
00657         attr = pk11_attribute_bytype(dsa, CKA_VALUE2);
00658         return (ISC_TF((attr != NULL) || dsa->ontoken));
00659 }
00660 
00661 static void
00662 pkcs11dsa_destroy(dst_key_t *key) {
00663         pk11_object_t *dsa = key->keydata.pkey;
00664         CK_ATTRIBUTE *attr;
00665 
00666         if (dsa == NULL)
00667                 return;
00668 
00669         INSIST((dsa->object == CK_INVALID_HANDLE) || dsa->ontoken);
00670 
00671         for (attr = pk11_attribute_first(dsa);
00672              attr != NULL;
00673              attr = pk11_attribute_next(dsa, attr))
00674                 switch (attr->type) {
00675                 case CKA_PRIME:
00676                 case CKA_SUBPRIME:
00677                 case CKA_BASE:
00678                 case CKA_VALUE:
00679                 case CKA_VALUE2:
00680                         if (attr->pValue != NULL) {
00681                                 memset(attr->pValue, 0, attr->ulValueLen);
00682                                 isc_mem_put(key->mctx,
00683                                             attr->pValue,
00684                                             attr->ulValueLen);
00685                         }
00686                         break;
00687                 }
00688         if (dsa->repr != NULL) {
00689                 memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr));
00690                 isc_mem_put(key->mctx,
00691                             dsa->repr,
00692                             dsa->attrcnt * sizeof(*attr));
00693         }
00694         memset(dsa, 0, sizeof(*dsa));
00695         isc_mem_put(key->mctx, dsa, sizeof(*dsa));
00696         key->keydata.pkey = NULL;
00697 }
00698 
00699 
00700 static isc_result_t
00701 pkcs11dsa_todns(const dst_key_t *key, isc_buffer_t *data) {
00702         pk11_object_t *dsa;
00703         CK_ATTRIBUTE *attr;
00704         isc_region_t r;
00705         int dnslen;
00706         unsigned int t, p_bytes;
00707         CK_ATTRIBUTE *prime = NULL, *subprime = NULL;
00708         CK_ATTRIBUTE *base = NULL, *pub_key = NULL;
00709         CK_BYTE *cp;
00710 
00711         REQUIRE(key->keydata.pkey != NULL);
00712 
00713         dsa = key->keydata.pkey;
00714 
00715         for (attr = pk11_attribute_first(dsa);
00716              attr != NULL;
00717              attr = pk11_attribute_next(dsa, attr))
00718                 switch (attr->type) {
00719                 case CKA_PRIME:
00720                         prime = attr;
00721                         break;
00722                 case CKA_SUBPRIME:
00723                         subprime = attr;
00724                         break;
00725                 case CKA_BASE:
00726                         base = attr;
00727                         break;
00728                 case CKA_VALUE:
00729                         pub_key = attr;
00730                         break;
00731                 }
00732         REQUIRE((prime != NULL) && (subprime != NULL) &&
00733                 (base != NULL) && (pub_key != NULL));
00734 
00735         isc_buffer_availableregion(data, &r);
00736 
00737         t = (prime->ulValueLen - 64) / 8;
00738         if (t > 8)
00739                 return (DST_R_INVALIDPUBLICKEY);
00740         p_bytes = 64 + 8 * t;
00741 
00742         dnslen = 1 + (key->key_size * 3)/8 + ISC_SHA1_DIGESTLENGTH;
00743         if (r.length < (unsigned int) dnslen)
00744                 return (ISC_R_NOSPACE);
00745 
00746         memset(r.base, 0, dnslen);
00747         *r.base++ = t;
00748         cp = (CK_BYTE *) subprime->pValue;
00749         memmove(r.base + ISC_SHA1_DIGESTLENGTH - subprime->ulValueLen,
00750                 cp, subprime->ulValueLen);
00751         r.base += ISC_SHA1_DIGESTLENGTH;
00752         cp = (CK_BYTE *) prime->pValue;
00753         memmove(r.base + key->key_size/8 - prime->ulValueLen,
00754                 cp, prime->ulValueLen);
00755         r.base += p_bytes;
00756         cp = (CK_BYTE *) base->pValue;
00757         memmove(r.base + key->key_size/8 - base->ulValueLen,
00758                 cp, base->ulValueLen);
00759         r.base += p_bytes;
00760         cp = (CK_BYTE *) pub_key->pValue;
00761         memmove(r.base + key->key_size/8 - pub_key->ulValueLen,
00762                 cp, pub_key->ulValueLen);
00763         r.base += p_bytes;
00764 
00765         isc_buffer_add(data, dnslen);
00766 
00767         return (ISC_R_SUCCESS);
00768 }
00769 
00770 static isc_result_t
00771 pkcs11dsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
00772         pk11_object_t *dsa;
00773         isc_region_t r;
00774         unsigned int t, p_bytes;
00775         CK_BYTE *prime, *subprime, *base, *pub_key;
00776         CK_ATTRIBUTE *attr;
00777 
00778         isc_buffer_remainingregion(data, &r);
00779         if (r.length == 0)
00780                 return (ISC_R_SUCCESS);
00781 
00782         dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
00783         if (dsa == NULL)
00784                 return (ISC_R_NOMEMORY);
00785         memset(dsa, 0, sizeof(*dsa));
00786 
00787         t = (unsigned int) *r.base++;
00788         if (t > 8) {
00789                 memset(dsa, 0, sizeof(*dsa));
00790                 isc_mem_put(key->mctx, dsa, sizeof(*dsa));
00791                 return (DST_R_INVALIDPUBLICKEY);
00792         }
00793         p_bytes = 64 + 8 * t;
00794 
00795         if (r.length < 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes) {
00796                 memset(dsa, 0, sizeof(*dsa));
00797                 isc_mem_put(key->mctx, dsa, sizeof(*dsa));
00798                 return (DST_R_INVALIDPUBLICKEY);
00799         }
00800 
00801         subprime = r.base;
00802         r.base += ISC_SHA1_DIGESTLENGTH;
00803 
00804         prime = r.base;
00805         r.base += p_bytes;
00806 
00807         base = r.base;
00808         r.base += p_bytes;
00809 
00810         pub_key = r.base;
00811         r.base += p_bytes;
00812 
00813         key->key_size = p_bytes * 8;
00814 
00815         isc_buffer_forward(data, 1 + ISC_SHA1_DIGESTLENGTH + 3 * p_bytes);
00816 
00817         dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 4);
00818         if (dsa->repr == NULL)
00819                 goto nomemory;
00820         memset(dsa->repr, 0, sizeof(*attr) * 4);
00821         dsa->attrcnt = 4;
00822 
00823         attr = dsa->repr;
00824         attr[0].type = CKA_PRIME;
00825         attr[0].pValue = isc_mem_get(key->mctx, p_bytes);
00826         if (attr[0].pValue == NULL)
00827                 goto nomemory;
00828         memmove(attr[0].pValue, prime, p_bytes);
00829         attr[0].ulValueLen = p_bytes;
00830 
00831         attr[1].type = CKA_SUBPRIME;
00832         attr[1].pValue = isc_mem_get(key->mctx, ISC_SHA1_DIGESTLENGTH);
00833         if (attr[1].pValue == NULL)
00834                 goto nomemory;
00835         memmove(attr[1].pValue, subprime, ISC_SHA1_DIGESTLENGTH);
00836         attr[1].ulValueLen = ISC_SHA1_DIGESTLENGTH;
00837 
00838         attr[2].type = CKA_BASE;
00839         attr[2].pValue = isc_mem_get(key->mctx, p_bytes);
00840         if (attr[2].pValue == NULL)
00841                 goto nomemory;
00842         memmove(attr[2].pValue, base, p_bytes);
00843         attr[2].ulValueLen = p_bytes;
00844 
00845         attr[3].type = CKA_VALUE;
00846         attr[3].pValue = isc_mem_get(key->mctx, p_bytes);
00847         if (attr[3].pValue == NULL)
00848                 goto nomemory;
00849         memmove(attr[3].pValue, pub_key, p_bytes);
00850         attr[3].ulValueLen = p_bytes;
00851 
00852         key->keydata.pkey = dsa;
00853 
00854         return (ISC_R_SUCCESS);
00855 
00856     nomemory:
00857         for (attr = pk11_attribute_first(dsa);
00858              attr != NULL;
00859              attr = pk11_attribute_next(dsa, attr))
00860                 switch (attr->type) {
00861                 case CKA_PRIME:
00862                 case CKA_SUBPRIME:
00863                 case CKA_BASE:
00864                 case CKA_VALUE:
00865                         if (attr->pValue != NULL) {
00866                                 memset(attr->pValue, 0, attr->ulValueLen);
00867                                 isc_mem_put(key->mctx,
00868                                             attr->pValue,
00869                                             attr->ulValueLen);
00870                         }
00871                         break;
00872                 }
00873         if (dsa->repr != NULL) {
00874                 memset(dsa->repr, 0, dsa->attrcnt * sizeof(*attr));
00875                 isc_mem_put(key->mctx,
00876                             dsa->repr,
00877                             dsa->attrcnt * sizeof(*attr));
00878         }
00879         memset(dsa, 0, sizeof(*dsa));
00880         isc_mem_put(key->mctx, dsa, sizeof(*dsa));
00881         return (ISC_R_NOMEMORY);
00882 }
00883 
00884 static isc_result_t
00885 pkcs11dsa_tofile(const dst_key_t *key, const char *directory) {
00886         int cnt = 0;
00887         pk11_object_t *dsa;
00888         CK_ATTRIBUTE *attr;
00889         CK_ATTRIBUTE *prime = NULL, *subprime = NULL, *base = NULL;
00890         CK_ATTRIBUTE *pub_key = NULL, *priv_key = NULL;
00891         dst_private_t priv;
00892         unsigned char bufs[5][128];
00893 
00894         if (key->keydata.pkey == NULL)
00895                 return (DST_R_NULLKEY);
00896 
00897         if (key->external) {
00898                 priv.nelements = 0;
00899                 return (dst__privstruct_writefile(key, &priv, directory));
00900         }
00901 
00902         dsa = key->keydata.pkey;
00903 
00904         for (attr = pk11_attribute_first(dsa);
00905              attr != NULL;
00906              attr = pk11_attribute_next(dsa, attr))
00907                 switch (attr->type) {
00908                 case CKA_PRIME:
00909                         prime = attr;
00910                         break;
00911                 case CKA_SUBPRIME:
00912                         subprime = attr;
00913                         break;
00914                 case CKA_BASE:
00915                         base = attr;
00916                         break;
00917                 case CKA_VALUE:
00918                         pub_key = attr;
00919                         break;
00920                 case CKA_VALUE2:
00921                         priv_key = attr;
00922                         break;
00923                 }
00924         if ((prime == NULL) || (subprime == NULL) || (base == NULL) ||
00925             (pub_key == NULL) || (priv_key ==NULL))
00926                 return (DST_R_NULLKEY);
00927 
00928         priv.elements[cnt].tag = TAG_DSA_PRIME;
00929         priv.elements[cnt].length = (unsigned short) prime->ulValueLen;
00930         memmove(bufs[cnt], prime->pValue, prime->ulValueLen);
00931         priv.elements[cnt].data = bufs[cnt];
00932         cnt++;
00933 
00934         priv.elements[cnt].tag = TAG_DSA_SUBPRIME;
00935         priv.elements[cnt].length = (unsigned short) subprime->ulValueLen;
00936         memmove(bufs[cnt], subprime->pValue, subprime->ulValueLen);
00937         priv.elements[cnt].data = bufs[cnt];
00938         cnt++;
00939 
00940         priv.elements[cnt].tag = TAG_DSA_BASE;
00941         priv.elements[cnt].length = (unsigned short) base->ulValueLen;
00942         memmove(bufs[cnt], base->pValue, base->ulValueLen);
00943         priv.elements[cnt].data = bufs[cnt];
00944         cnt++;
00945 
00946         priv.elements[cnt].tag = TAG_DSA_PRIVATE;
00947         priv.elements[cnt].length = (unsigned short) priv_key->ulValueLen;
00948         memmove(bufs[cnt], priv_key->pValue, priv_key->ulValueLen);
00949         priv.elements[cnt].data = bufs[cnt];
00950         cnt++;
00951 
00952         priv.elements[cnt].tag = TAG_DSA_PUBLIC;
00953         priv.elements[cnt].length = (unsigned short) pub_key->ulValueLen;
00954         memmove(bufs[cnt], pub_key->pValue, pub_key->ulValueLen);
00955         priv.elements[cnt].data = bufs[cnt];
00956         cnt++;
00957 
00958         priv.nelements = cnt;
00959         return (dst__privstruct_writefile(key, &priv, directory));
00960 }
00961 
00962 static isc_result_t
00963 pkcs11dsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
00964         dst_private_t priv;
00965         isc_result_t ret;
00966         int i;
00967         pk11_object_t *dsa = NULL;
00968         CK_ATTRIBUTE *attr;
00969         isc_mem_t *mctx = key->mctx;
00970 
00971         /* read private key file */
00972         ret = dst__privstruct_parse(key, DST_ALG_DSA, lexer, mctx, &priv);
00973         if (ret != ISC_R_SUCCESS)
00974                 return (ret);
00975 
00976         if (key->external) {
00977                 if (priv.nelements != 0)
00978                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00979                 if (pub == NULL)
00980                         DST_RET(DST_R_INVALIDPRIVATEKEY);
00981 
00982                 key->keydata.pkey = pub->keydata.pkey;
00983                 pub->keydata.pkey = NULL;
00984                 key->key_size = pub->key_size;
00985 
00986                 dst__privstruct_free(&priv, mctx);
00987                 memset(&priv, 0, sizeof(priv));
00988 
00989                 return (ISC_R_SUCCESS);
00990         }
00991 
00992         dsa = (pk11_object_t *) isc_mem_get(key->mctx, sizeof(*dsa));
00993         if (dsa == NULL)
00994                 DST_RET(ISC_R_NOMEMORY);
00995         memset(dsa, 0, sizeof(*dsa));
00996         key->keydata.pkey = dsa;
00997 
00998         dsa->repr = (CK_ATTRIBUTE *) isc_mem_get(key->mctx, sizeof(*attr) * 5);
00999         if (dsa->repr == NULL)
01000                 DST_RET(ISC_R_NOMEMORY);
01001         memset(dsa->repr, 0, sizeof(*attr) * 5);
01002         dsa->attrcnt = 5;
01003         attr = dsa->repr;
01004         attr[0].type = CKA_PRIME;
01005         attr[1].type = CKA_SUBPRIME;
01006         attr[2].type = CKA_BASE;
01007         attr[3].type = CKA_VALUE;
01008         attr[4].type = CKA_VALUE2;
01009 
01010         for (i = 0; i < priv.nelements; i++) {
01011                 CK_BYTE *bn;
01012 
01013                 bn = isc_mem_get(key->mctx, priv.elements[i].length);
01014                 if (bn == NULL)
01015                         DST_RET(ISC_R_NOMEMORY);
01016                 memmove(bn, priv.elements[i].data, priv.elements[i].length);
01017 
01018                 switch (priv.elements[i].tag) {
01019                         case TAG_DSA_PRIME:
01020                                 attr = pk11_attribute_bytype(dsa, CKA_PRIME);
01021                                 INSIST(attr != NULL);
01022                                 attr->pValue = bn;
01023                                 attr->ulValueLen = priv.elements[i].length;
01024                                 break;
01025                         case TAG_DSA_SUBPRIME:
01026                                 attr = pk11_attribute_bytype(dsa,
01027                                                              CKA_SUBPRIME);
01028                                 INSIST(attr != NULL);
01029                                 attr->pValue = bn;
01030                                 attr->ulValueLen = priv.elements[i].length;
01031                                 break;
01032                         case TAG_DSA_BASE:
01033                                 attr = pk11_attribute_bytype(dsa, CKA_BASE);
01034                                 INSIST(attr != NULL);
01035                                 attr->pValue = bn;
01036                                 attr->ulValueLen = priv.elements[i].length;
01037                                 break;
01038                         case TAG_DSA_PRIVATE:
01039                                 attr = pk11_attribute_bytype(dsa, CKA_VALUE2);
01040                                 INSIST(attr != NULL);
01041                                 attr->pValue = bn;
01042                                 attr->ulValueLen = priv.elements[i].length;
01043                                 break;
01044                         case TAG_DSA_PUBLIC:
01045                                 attr = pk11_attribute_bytype(dsa, CKA_VALUE);
01046                                 INSIST(attr != NULL);
01047                                 attr->pValue = bn;
01048                                 attr->ulValueLen = priv.elements[i].length;
01049                                 break;
01050                 }
01051         }
01052         dst__privstruct_free(&priv, mctx);
01053 
01054         attr = pk11_attribute_bytype(dsa, CKA_PRIME);
01055         INSIST(attr != NULL);
01056         key->key_size = pk11_numbits(attr->pValue, attr->ulValueLen);
01057 
01058         return (ISC_R_SUCCESS);
01059 
01060  err:
01061         pkcs11dsa_destroy(key);
01062         dst__privstruct_free(&priv, mctx);
01063         memset(&priv, 0, sizeof(priv));
01064         return (ret);
01065 }
01066 
01067 static dst_func_t pkcs11dsa_functions = {
01068         pkcs11dsa_createctx,
01069         NULL, /*%< createctx2 */
01070         pkcs11dsa_destroyctx,
01071         pkcs11dsa_adddata,
01072         pkcs11dsa_sign,
01073         pkcs11dsa_verify,
01074         NULL, /*%< verify2 */
01075         NULL, /*%< computesecret */
01076         pkcs11dsa_compare,
01077         NULL, /*%< paramcompare */
01078         pkcs11dsa_generate,
01079         pkcs11dsa_isprivate,
01080         pkcs11dsa_destroy,
01081         pkcs11dsa_todns,
01082         pkcs11dsa_fromdns,
01083         pkcs11dsa_tofile,
01084         pkcs11dsa_parse,
01085         NULL, /*%< cleanup */
01086         NULL, /*%< fromlabel */
01087         NULL, /*%< dump */
01088         NULL, /*%< restore */
01089 };
01090 
01091 isc_result_t
01092 dst__pkcs11dsa_init(dst_func_t **funcp) {
01093         REQUIRE(funcp != NULL);
01094         if (*funcp == NULL)
01095                 *funcp = &pkcs11dsa_functions;
01096         return (ISC_R_SUCCESS);
01097 }
01098 
01099 #else /* PKCS11CRYPTO */
01100 
01101 #include <isc/util.h>
01102 
01103 EMPTY_TRANSLATION_UNIT
01104 
01105 #endif /* PKCS11CRYPTO */
01106 /*! \file */

Generated on Tue Apr 28 17:40:58 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha