Print this page
    
9642 PKCS#11 softtoken should use explicit_bzero
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
          +++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softASN1.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  
    | 
      ↓ open down ↓ | 
    14 lines elided | 
    
      ↑ open up ↑ | 
  
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   * Copyright 2012 Milan Jurik. All rights reserved.
       25 + * Copyright (c) 2018, Joyent. Inc.
  25   26   */
  26   27  
  27   28  #include <stdlib.h>
  28   29  #include <string.h>
  29   30  #include <strings.h>
  30   31  #include <lber.h>
  31   32  #include <security/cryptoki.h>
  32   33  #include "softDSA.h"
  33   34  #include "softDH.h"
  34   35  #include "softRSA.h"
  35   36  #include "softObject.h"
  36   37  #include "softASN1.h"
  37   38  
  38   39  #define OID_TAG                 0x06
  39   40  
  40   41  #define MAX_DH_KEY      MAX_DH_KEYLENGTH_IN_BYTES       /* bytes in DH key */
  41   42  static uchar_t  DH_OID[] = {
  42   43          /* DH key agreement OID:  1 . 2 . 840 . 113549 . 1 . 3 . 1 */
  43   44          0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01
  44   45  };
  45   46  
  46   47  #define MAX_DH942_KEY   MAX_DH_KEYLENGTH_IN_BYTES /* bytes in DH X9.42 key */
  47   48  static uchar_t  DH942_OID[] = {
  48   49          /* DH X9.42 OID:  1 . 2 . 840 . 10046 . 1  */
  49   50          0x2A, 0x86, 0x48, 0xCE, 0x3E, 0x01
  50   51  };
  51   52  
  52   53  #define MAX_DSA_KEY     MAX_DSA_KEY_LEN         /* bytes in DSA key */
  53   54  static uchar_t  DSA_OID[] = {
  54   55          /* DSA algorithm OID:  1 . 2 . 840 . 10040 . 4 . 1  */
  55   56          0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01
  56   57  };
  57   58  
  58   59  #define MAX_RSA_KEY     MAX_RSA_KEYLENGTH_IN_BYTES      /* bytes in RSA key */
  59   60  static uchar_t  RSA_OID[] = {
  60   61          /* RSA algorithm OID:  1 . 2 . 840 . 113549 . 1 . 1 . 1 */
  61   62          0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
  62   63  };
  63   64  
  64   65  
  65   66  /*
  66   67   * If the first bit of big integer is non-zero (i.e, first byte is
  67   68   * 0x80 or greater), it may be interpreted as an ASN.1 negative number.
  68   69   * Add one leading byte of zero-padding only in these cases to ensure
  69   70   * it is treated as an unsigned integer.
  70   71   */
  71   72  static CK_RV
  72   73  pad_bigint_attr(biginteger_t *src, biginteger_t *dst)
  73   74  {
  74   75          int     padding;
  75   76  
  76   77          /* Src and dst must already by previously allocated. */
  77   78          if (src == NULL || dst == NULL)
  78   79                  return (CKR_HOST_MEMORY);
  79   80  
  
    | 
      ↓ open down ↓ | 
    45 lines elided | 
    
      ↑ open up ↑ | 
  
  80   81          if (src->big_value_len == 0) {
  81   82                  dst->big_value = NULL;
  82   83                  dst->big_value_len = 0;
  83   84                  return (CKR_OK);
  84   85          }
  85   86          /*
  86   87           * Realloc() may free() or shrink previous memory location, so
  87   88           * clear out potentially sensitive data before that happens.
  88   89           */
  89   90          if (dst->big_value != NULL)
  90      -                (void) memset(dst->big_value, 0x0, dst->big_value_len);
       91 +                explicit_bzero(dst->big_value, dst->big_value_len);
  91   92  
  92   93          padding = (src->big_value[0] < 0x80) ? 0 : 1;
  93   94          dst->big_value_len = src->big_value_len + padding;
  94   95  
  95   96          dst->big_value = realloc(dst->big_value, dst->big_value_len);
  96   97          if (dst->big_value == NULL)
  97   98                  return (CKR_HOST_MEMORY);
  98   99  
  99  100          /* Set zero-pad at first byte, then append actual big_value. */
 100  101          dst->big_value[0] = 0x0;
 101  102          (void) memcpy(&(dst->big_value[padding]), src->big_value,
 102  103              src->big_value_len);
 103  104          return (CKR_OK);
 104  105  }
 105  106  
 106  107  /*
 107  108   * Sometimes there is one bytes of zero-padding, if a big integer may
 108  109   * be interpreted as an ASN.1 negative number (i.e, the first bit is
 109  110   * non-zero, the first byte is 0x80 or greater).  Remove first byte
 110  111   * of zero-padding in those cases from the decoded octet strings.
 111  112   */
 112  113  static CK_RV
 113  114  unpad_bigint_attr(biginteger_t src, biginteger_t *dst)
 114  115  {
 115  116          int     offset;
 116  117  
 117  118          if (dst == NULL)
 118  119                  return (CKR_HOST_MEMORY);
 119  120  
 120  121          if (src.big_value_len == 0) {
 121  122                  dst->big_value = NULL;
 122  123                  dst->big_value_len = 0;
 123  124                  return (CKR_OK);
 124  125          }
 125  126  
 126  127          offset = (src.big_value[0] == 0x00) ? 1 : 0;
 127  128          dst->big_value_len = src.big_value_len - offset;
 128  129  
 129  130          /*
 130  131           * Must allocate memory here because subsequent calls to
 131  132           * copy_bigint_attr() just redirect pointer; it doesn't
 132  133           * really copy the bigint like the function name implies.
 133  134           */
 134  135          dst->big_value = malloc(dst->big_value_len);
 135  136          if (dst->big_value == NULL)
 136  137                  return (CKR_HOST_MEMORY);
 137  138  
 138  139          (void) memcpy(dst->big_value, &(src.big_value[offset]),
 139  140              dst->big_value_len);
 140  141          return (CKR_OK);
 141  142  }
 142  143  
 143  144  
 144  145  /* Encode RSA private key in ASN.1 BER syntax. */
 145  146  static CK_RV
 146  147  rsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 147  148  {
 148  149          CK_RV           rv = CKR_OK;
 149  150          BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 150  151          BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 151  152          int             version = SOFT_ASN_VERSION;
 152  153          biginteger_t    tmp_pad = { NULL, 0 };
 153  154  
 154  155          /*
 155  156           * The ASN.1 syntax for an RSA private key is:
 156  157           *
 157  158           * PKCS#8       \* PrivateKeyInfo *\
 158  159           * ---------------------------------
 159  160           * Sequence {
 160  161           *      version         INTEGER;
 161  162           *      Sequence {      \* PrivateKeyAlgorithm *\
 162  163           *              OID     0x06,   \* RSA algorithm OID *\
 163  164           *              param(NULL)
 164  165           *      }
 165  166           *      RSAPrivateKey   OCTETSTRING =
 166  167           *              PKCS#1  \* RSAPrivateKey *\
 167  168           *              ---------------------------
 168  169           *              Sequence {
 169  170           *                      version         INTEGER,
 170  171           *                      modulus         INTEGER,
 171  172           *                      publicExponent  INTEGER,
 172  173           *                      privateExponent INTEGER,
 173  174           *                      prime1          INTEGER,
 174  175           *                      prime2          INTEGER,
 175  176           *                      exponent1       INTEGER,
 176  177           *                      exponent2       INTEGER,
 177  178           *                      coefficient     INTEGER
 178  179           *              }
 179  180           * }
 180  181           *
 181  182           * The code below starts building the innermost octets
 182  183           * RSAPrivateKey, and then builds the PrivateKeyInfo
 183  184           * sequence around that octet string.  The BER syntax
 184  185           * used in this function is (others may be possible):
 185  186           *      { i { to n } { i to  to  to  to  to  to  to  to } }
 186  187           * where "i" is for integers with fixed size
 187  188           * where "to" is for integers that vary in size (length + value)
 188  189           * where "n" is for nulls
 189  190           * where "{}" delimit sequences
 190  191           */
 191  192  
 192  193          /* RSAPrivateKey ... */
 193  194          if ((key_asn = ber_alloc()) == NULLBER)
 194  195                  return (CKR_HOST_MEMORY);
 195  196  
 196  197          /* ... begin-sequence { version, */
 197  198          if (ber_printf(key_asn, "{i", version) == -1) {
 198  199                  rv = CKR_GENERAL_ERROR;
 199  200                  goto cleanup_rsapri2asn;
 200  201          }
 201  202  
 202  203          /* ... modulus, */
 203  204          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_MOD(objp), &tmp_pad)) != CKR_OK)
 204  205                  goto cleanup_rsapri2asn;
 205  206          if (ber_printf(key_asn, "to", LBER_INTEGER,
 206  207              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 207  208                  rv = CKR_GENERAL_ERROR;
 208  209                  goto cleanup_rsapri2asn;
 209  210          }
 210  211  
 211  212          /* ... public exponent, */
 212  213          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PUBEXPO(objp), &tmp_pad)) !=
 213  214              CKR_OK)
 214  215                  goto cleanup_rsapri2asn;
 215  216  
 216  217          else if (ber_printf(key_asn, "to", LBER_INTEGER, tmp_pad.big_value,
 217  218              tmp_pad.big_value_len) == -1) {
 218  219                  rv = CKR_GENERAL_ERROR;
 219  220                  goto cleanup_rsapri2asn;
 220  221          }
 221  222  
 222  223          /* ... private exponent, */
 223  224          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIEXPO(objp), &tmp_pad)) !=
 224  225              CKR_OK)
 225  226                  goto cleanup_rsapri2asn;
 226  227          if (ber_printf(key_asn, "to", LBER_INTEGER,
 227  228              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 228  229                  rv = CKR_GENERAL_ERROR;
 229  230                  goto cleanup_rsapri2asn;
 230  231          }
 231  232  
 232  233          /* ... prime 1, */
 233  234          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME1(objp), &tmp_pad)) !=
 234  235              CKR_OK)
 235  236                  goto cleanup_rsapri2asn;
 236  237          else if (ber_printf(key_asn, "to", LBER_INTEGER,
 237  238              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 238  239                  rv = CKR_GENERAL_ERROR;
 239  240                  goto cleanup_rsapri2asn;
 240  241          }
 241  242  
 242  243          /* ... prime 2, */
 243  244          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME2(objp), &tmp_pad)) !=
 244  245              CKR_OK)
 245  246                  goto cleanup_rsapri2asn;
 246  247          else if (ber_printf(key_asn, "to", LBER_INTEGER,
 247  248              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 248  249                  rv = CKR_GENERAL_ERROR;
 249  250                  goto cleanup_rsapri2asn;
 250  251          }
 251  252  
 252  253          /* ... exponent 1, */
 253  254          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO1(objp), &tmp_pad)) != CKR_OK)
 254  255                  goto cleanup_rsapri2asn;
 255  256          else if (ber_printf(key_asn, "to", LBER_INTEGER,
 256  257              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 257  258                  rv = CKR_GENERAL_ERROR;
 258  259                  goto cleanup_rsapri2asn;
 259  260          }
 260  261  
 261  262          /* ... exponent 2, */
 262  263          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO2(objp), &tmp_pad)) != CKR_OK)
 263  264                  goto cleanup_rsapri2asn;
 264  265          else if (ber_printf(key_asn, "to", LBER_INTEGER,
 265  266              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 266  267                  rv = CKR_GENERAL_ERROR;
 267  268                  goto cleanup_rsapri2asn;
 268  269          }
 269  270  
 270  271          /* ... coefficient } end-sequence */
 271  272          if ((rv = pad_bigint_attr(OBJ_PRI_RSA_COEF(objp), &tmp_pad)) != CKR_OK)
 272  273                  goto cleanup_rsapri2asn;
 273  274          else if (ber_printf(key_asn, "to}", LBER_INTEGER,
 274  275              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 275  276                  rv = CKR_GENERAL_ERROR;
 276  277                  goto cleanup_rsapri2asn;
 277  278          }
 278  279  
 279  280          /* Convert key ASN.1 to octet string. */
 280  281          if (ber_flatten(key_asn, &key_octs) == -1) {
 281  282                  rv = CKR_GENERAL_ERROR;
 282  283                  goto cleanup_rsapri2asn;
 283  284          }
 284  285  
 285  286          /* PKCS#8 PrivateKeyInfo ... */
 286  287          if ((p8obj_asn = ber_alloc()) == NULLBER) {
 287  288                  rv = CKR_HOST_MEMORY;
 288  289                  goto cleanup_rsapri2asn;
 289  290          }
 290  291  
 291  292          /*
 292  293           * Embed key octet string into PKCS#8 object ASN.1:
 293  294           * begin-sequence {
 294  295           *      version
 295  296           *      begin-sequence {
 296  297           *              OID,
 297  298           *              NULL
 298  299           *      } end-sequence
 299  300           *      RSAPrivateKey
 300  301           * } end-sequence
 301  302           */
 302  303          if (ber_printf(p8obj_asn, "{i{ton}o}", version,
 303  304              OID_TAG, RSA_OID, sizeof (RSA_OID), /* NULL parameter, */
 304  305              key_octs->bv_val, key_octs->bv_len) == -1) {
 305  306                  rv = CKR_GENERAL_ERROR;
 306  307                  goto cleanup_rsapri2asn;
 307  308          }
 308  309  
 309  310          /* Convert PKCS#8 object ASN.1 to octet string. */
 310  311          if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 311  312                  rv = CKR_GENERAL_ERROR;
 312  313                  goto cleanup_rsapri2asn;
 313  314          }
 314  315  
 315  316          /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 316  317          /*
 317  318           * If the user passes in a null buf, then buf_len is set.
 318  319           * If the user passes in a value with buf_len, then it can
 319  320           * be checked to see if the accompanying buf is big enough.
 320  321           * If it is, the octet string is copied into a pre-malloc'd
 321  322           * buf; otherwise the user must resize buf and call again.
 322  323           * In either case, buf_len is reset to the corrected size.
 323  324           * See PKCS#11 section 11.2.
 324  325           */
 325  326  #ifdef _LP64
 326  327          /* LINTED E_CAST_INT_TO_SMALL_INT */
 327  328          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 328  329  #else
 329  330          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 330  331  #endif
  
    | 
      ↓ open down ↓ | 
    230 lines elided | 
    
      ↑ open up ↑ | 
  
 331  332                  *buf_len = p8obj_octs->bv_len;
 332  333                  rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 333  334                  goto cleanup_rsapri2asn;
 334  335          }
 335  336  
 336  337          *buf_len = p8obj_octs->bv_len;
 337  338          (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 338  339  
 339  340  cleanup_rsapri2asn:
 340  341  
 341      -        if (tmp_pad.big_value != NULL) {
 342      -                (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
 343      -                free(tmp_pad.big_value);
 344      -        }
      342 +        freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 345  343  
 346  344          if (key_asn != NULLBER)
 347  345                  ber_free(key_asn, 1);
 348  346  
 349  347          if (key_octs != NULL)
 350  348                  ber_bvfree(key_octs);
 351  349  
 352  350          if (p8obj_asn != NULLBER)
 353  351                  ber_free(p8obj_asn, 1);
 354  352  
 355  353          if (p8obj_octs != NULL)
 356  354                  ber_bvfree(p8obj_octs);
 357  355  
 358  356          return (rv);
 359  357  }
 360  358  
 361  359  /* Encode DSA private key in ASN.1 BER syntax. */
 362  360  static CK_RV
 363  361  dsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 364  362  {
 365  363          CK_RV           rv = CKR_OK;
 366  364          BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 367  365          BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 368  366          int             version = SOFT_ASN_VERSION;
 369  367          biginteger_t    tmp_pad = { NULL, 0 };
 370  368  
 371  369          /*
 372  370           * The ASN.1 syntax for a DSA private key is:
 373  371           *
 374  372           * PKCS#8       \* PrivateKeyInfo *\
 375  373           * ---------------------------------
 376  374           * Sequence {
 377  375           *      version         INTEGER;
 378  376           *      Sequence {      \* PrivateKeyAlgorithm *\
 379  377           *              OID     0x06,   \* DSA algorithm OID *\
 380  378           *              param(DSS-params)       OCTETSTRING =
 381  379           *                      PKCS#?  \* DSSParameter *\
 382  380           *                      ----------------------------------
 383  381           *                      Sequence {
 384  382           *                              prime   INTEGER,
 385  383           *                              subprime INTEGER,
 386  384           *                              base    INTEGER,
 387  385           *              }
 388  386           *      }
 389  387           *      DSAPrivateKey   OCTETSTRING =
 390  388           *              PKCS#1  \* DSAPrivateKey *\
 391  389           *              ---------------------------
 392  390           *              value           INTEGER
 393  391           * }
 394  392           *
 395  393           * The code below starts building the innermost octets
 396  394           * DSAPrivateKey, and then builds the PrivateKeyInfo
 397  395           * sequence around that octet string.  The BER syntax
 398  396           * used in this function is (others may be possible):
 399  397           *      { i { to { to to to } } to }
 400  398           * where "i" is for integers with fixed size
 401  399           * where "to" is for integers that vary in size (length + value)
 402  400           * where "{}" delimit sequences
 403  401           */
 404  402  
 405  403          /* DSAPrivateKey ... */
 406  404          if ((key_asn = ber_alloc()) == NULLBER)
 407  405                  return (CKR_HOST_MEMORY);
 408  406  
 409  407          /* ... value */
 410  408          if ((rv = pad_bigint_attr(OBJ_PRI_DSA_VALUE(objp), &tmp_pad)) != CKR_OK)
 411  409                  goto cleanup_dsapri2asn;
 412  410          if (ber_printf(key_asn, "to", LBER_INTEGER,
 413  411              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 414  412                  rv = CKR_GENERAL_ERROR;
 415  413                  goto cleanup_dsapri2asn;
 416  414          }
 417  415  
 418  416          /* Convert key ASN.1 to octet string. */
 419  417          if (ber_flatten(key_asn, &key_octs) == -1) {
 420  418                  rv = CKR_GENERAL_ERROR;
 421  419                  goto cleanup_dsapri2asn;
 422  420          }
 423  421  
 424  422          /* PKCS#8 PrivateKeyInfo ... */
 425  423          if ((p8obj_asn = ber_alloc()) == NULLBER) {
 426  424                  rv = CKR_HOST_MEMORY;
 427  425                  goto cleanup_dsapri2asn;
 428  426          }
 429  427  
 430  428          /*
 431  429           * Start off the PKCS#8 object ASN.1:
 432  430           * begin-sequence {
 433  431           *      version
 434  432           *      begin-sequence {
 435  433           *              OID,
 436  434           * ...
 437  435           */
 438  436          if (ber_printf(p8obj_asn, "{i{to", version,
 439  437              OID_TAG, DSA_OID, sizeof (DSA_OID)) == -1) {
 440  438                  rv = CKR_GENERAL_ERROR;
 441  439                  goto cleanup_dsapri2asn;
 442  440          }
 443  441  
 444  442          /*
 445  443           * Add DSS parameters:
 446  444           * ...
 447  445           *              begin-sequence {
 448  446           *                      prime,
 449  447           * ...
 450  448           */
 451  449          if ((rv = pad_bigint_attr(OBJ_PRI_DSA_PRIME(objp), &tmp_pad)) != CKR_OK)
 452  450                  goto cleanup_dsapri2asn;
 453  451          if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 454  452              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 455  453                  rv = CKR_GENERAL_ERROR;
 456  454                  goto cleanup_dsapri2asn;
 457  455          }
 458  456  
 459  457          /*
 460  458           * ...
 461  459           *                      subprime,
 462  460           * ...
 463  461           */
 464  462          if ((rv = pad_bigint_attr(OBJ_PRI_DSA_SUBPRIME(objp), &tmp_pad)) !=
 465  463              CKR_OK)
 466  464                  goto cleanup_dsapri2asn;
 467  465          if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
 468  466              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 469  467                  rv = CKR_GENERAL_ERROR;
 470  468                  goto cleanup_dsapri2asn;
 471  469          }
 472  470  
 473  471          /*
 474  472           * ...
 475  473           *                      base
 476  474           *              } end-sequence
 477  475           */
 478  476          if ((rv = pad_bigint_attr(OBJ_PRI_DSA_BASE(objp), &tmp_pad)) != CKR_OK)
 479  477                  goto cleanup_dsapri2asn;
 480  478          if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 481  479              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 482  480                  rv = CKR_GENERAL_ERROR;
 483  481                  goto cleanup_dsapri2asn;
 484  482          }
 485  483  
 486  484          /*
 487  485           * Add the key octet string:
 488  486           *      } end-sequence
 489  487           *      DSAPrivateKey
 490  488           * } end-sequence
 491  489           */
 492  490          if (ber_printf(p8obj_asn, "}o}",
 493  491              key_octs->bv_val, key_octs->bv_len) == -1) {
 494  492                  rv = CKR_GENERAL_ERROR;
 495  493                  goto cleanup_dsapri2asn;
 496  494          }
 497  495  
 498  496          /* Convert PKCS#8 object ASN.1 to octet string. */
 499  497          if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 500  498                  rv = CKR_GENERAL_ERROR;
 501  499                  goto cleanup_dsapri2asn;
 502  500          }
 503  501  
 504  502          /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 505  503          /*
 506  504           * If the user passes in a null buf, then buf_len is set.
 507  505           * If the user passes in a value with buf_len, then it can
 508  506           * be checked to see if the accompanying buf is big enough.
 509  507           * If it is, the octet string is copied into a pre-malloc'd
 510  508           * buf; otherwise the user must resize buf and call again.
 511  509           * In either case, buf_len is reset to the corrected size.
 512  510           * See PKCS#11 section 11.2.
 513  511           */
 514  512  #ifdef _LP64
 515  513          /* LINTED E_CAST_INT_TO_SMALL_INT */
 516  514          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 517  515  #else
 518  516          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 519  517  #endif
  
    | 
      ↓ open down ↓ | 
    165 lines elided | 
    
      ↑ open up ↑ | 
  
 520  518                  *buf_len = p8obj_octs->bv_len;
 521  519                  rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 522  520                  goto cleanup_dsapri2asn;
 523  521          }
 524  522  
 525  523          *buf_len = p8obj_octs->bv_len;
 526  524          (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 527  525  
 528  526  cleanup_dsapri2asn:
 529  527  
 530      -        if (tmp_pad.big_value != NULL) {
 531      -                (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
 532      -                free(tmp_pad.big_value);
 533      -        }
      528 +        freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 534  529  
 535  530          if (key_asn != NULLBER)
 536  531                  ber_free(key_asn, 1);
 537  532  
 538  533          if (key_octs != NULL)
 539  534                  ber_bvfree(key_octs);
 540  535  
 541  536          if (p8obj_asn != NULLBER)
 542  537                  ber_free(p8obj_asn, 1);
 543  538  
 544  539          if (p8obj_octs != NULL)
 545  540                  ber_bvfree(p8obj_octs);
 546  541  
 547  542          return (rv);
 548  543  }
 549  544  
 550  545  /* Encode DH private key in ASN.1 BER syntax. */
 551  546  static CK_RV
 552  547  dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 553  548  {
 554  549          CK_RV           rv = CKR_OK;
 555  550          BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 556  551          BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 557  552          int             version = SOFT_ASN_VERSION;
 558  553          biginteger_t    tmp_pad = { NULL, 0 };
 559  554  
 560  555          /*
 561  556           * The ASN.1 syntax for a DH private key is:
 562  557           *
 563  558           * PKCS#8       \* PrivateKeyInfo *\
 564  559           * ---------------------------------
 565  560           * Sequence {
 566  561           *      version         INTEGER;
 567  562           *      Sequence {      \* PrivateKeyAlgorithm *\
 568  563           *              OID     0x06,   \* DH algorithm OID *\
 569  564           *              param(DH-params) OCTETSTRING =
 570  565           *                      PKCS#3  \* DHParameter *\
 571  566           *                      -------------------------
 572  567           *                      Sequence {
 573  568           *                              prime   INTEGER,
 574  569           *                              base    INTEGER
 575  570           *                      }
 576  571           *      }
 577  572           *      DHPrivateKey    OCTETSTRING =
 578  573           *              PKCS#1  \* DHPrivateKey *\
 579  574           *              --------------------------
 580  575           *              value           INTEGER
 581  576           * }
 582  577           *
 583  578           * The code below starts building the innermost octets
 584  579           * DHPrivateKey, and then builds the PrivateKeyInfo
 585  580           * sequence around that octet string.  The BER syntax
 586  581           * used in this function is (others may be possible):
 587  582           *      { i { to { to to } } to }
 588  583           * where "i" is for integers with fixed size
 589  584           * where "to" is for integers that vary in size (length + value)
 590  585           * where "{}" delimit sequences
 591  586           */
 592  587  
 593  588          /* DHPrivateKey ... */
 594  589          if ((key_asn = ber_alloc()) == NULLBER)
 595  590                  return (CKR_HOST_MEMORY);
 596  591  
 597  592          /* ... value */
 598  593          if ((rv = pad_bigint_attr(OBJ_PRI_DH_VALUE(objp), &tmp_pad)) != CKR_OK)
 599  594                  goto cleanup_dhpri2asn;
 600  595          if (ber_printf(key_asn, "to", LBER_INTEGER,
 601  596              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 602  597                  rv = CKR_GENERAL_ERROR;
 603  598                  goto cleanup_dhpri2asn;
 604  599          }
 605  600  
 606  601          /* Convert key ASN.1 to octet string. */
 607  602          if (ber_flatten(key_asn, &key_octs) == -1) {
 608  603                  rv = CKR_GENERAL_ERROR;
 609  604                  goto cleanup_dhpri2asn;
 610  605          }
 611  606  
 612  607          /* PKCS#8 PrivateKeyInfo ... */
 613  608          if ((p8obj_asn = ber_alloc()) == NULLBER) {
 614  609                  rv = CKR_HOST_MEMORY;
 615  610                  goto cleanup_dhpri2asn;
 616  611          }
 617  612  
 618  613          /*
 619  614           * Start off the PKCS#8 object ASN.1:
 620  615           * begin-sequence {
 621  616           *      version
 622  617           *      begin-sequence {
 623  618           *              OID,
 624  619           * ...
 625  620           */
 626  621          if (ber_printf(p8obj_asn, "{i{to", version,
 627  622              OID_TAG, DH_OID, sizeof (DH_OID)) == -1) {
 628  623                  rv = CKR_GENERAL_ERROR;
 629  624                  goto cleanup_dhpri2asn;
 630  625          }
 631  626  
 632  627          /*
 633  628           * Add DH parameters:
 634  629           * ...
 635  630           *              begin-sequence {
 636  631           *                      prime,
 637  632           * ...
 638  633           */
 639  634          if ((rv = pad_bigint_attr(OBJ_PRI_DH_PRIME(objp), &tmp_pad)) != CKR_OK)
 640  635                  goto cleanup_dhpri2asn;
 641  636          if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 642  637              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 643  638                  rv = CKR_GENERAL_ERROR;
 644  639                  goto cleanup_dhpri2asn;
 645  640          }
 646  641  
 647  642          /*
 648  643           * ...
 649  644           *                      base
 650  645           *              } end-sequence
 651  646           */
 652  647          if ((rv = pad_bigint_attr(OBJ_PRI_DH_BASE(objp), &tmp_pad)) != CKR_OK)
 653  648                  goto cleanup_dhpri2asn;
 654  649          if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 655  650              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 656  651                  rv = CKR_GENERAL_ERROR;
 657  652                  goto cleanup_dhpri2asn;
 658  653          }
 659  654  
 660  655          /*
 661  656           * Add the key octet string:
 662  657           *      } end-sequence
 663  658           *      DSAPrivateKey
 664  659           * } end-sequence
 665  660           */
 666  661          if (ber_printf(p8obj_asn, "}o}",
 667  662              key_octs->bv_val, key_octs->bv_len) == -1) {
 668  663                  rv = CKR_GENERAL_ERROR;
 669  664                  goto cleanup_dhpri2asn;
 670  665          }
 671  666  
 672  667          /* Convert PKCS#8 object ASN.1 to octet string. */
 673  668          if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 674  669                  rv = CKR_GENERAL_ERROR;
 675  670                  goto cleanup_dhpri2asn;
 676  671          }
 677  672  
 678  673          /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 679  674          /*
 680  675           * If the user passes in a null buf, then buf_len is set.
 681  676           * If the user passes in a value with buf_len, then it can
 682  677           * be checked to see if the accompanying buf is big enough.
 683  678           * If it is, the octet string is copied into a pre-malloc'd
 684  679           * buf; otherwise the user must resize buf and call again.
 685  680           * In either case, buf_len is reset to the corrected size.
 686  681           * See PKCS#11 section 11.2.
 687  682           */
 688  683  #ifdef _LP64
 689  684          /* LINTED E_CAST_INT_TO_SMALL_INT */
 690  685          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 691  686  #else
 692  687          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 693  688  #endif
  
    | 
      ↓ open down ↓ | 
    150 lines elided | 
    
      ↑ open up ↑ | 
  
 694  689                  *buf_len = p8obj_octs->bv_len;
 695  690                  rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 696  691                  goto cleanup_dhpri2asn;
 697  692          }
 698  693  
 699  694          *buf_len = p8obj_octs->bv_len;
 700  695          (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 701  696  
 702  697  cleanup_dhpri2asn:
 703  698  
 704      -        if (tmp_pad.big_value != NULL) {
 705      -                (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
 706      -                free(tmp_pad.big_value);
 707      -        }
      699 +        freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 708  700  
 709  701          if (key_asn != NULLBER)
 710  702                  ber_free(key_asn, 1);
 711  703  
 712  704          if (key_octs != NULL)
 713  705                  ber_bvfree(key_octs);
 714  706  
 715  707          if (p8obj_asn != NULLBER)
 716  708                  ber_free(p8obj_asn, 1);
 717  709  
 718  710          if (p8obj_octs != NULL)
 719  711                  ber_bvfree(p8obj_octs);
 720  712  
 721  713          return (rv);
 722  714  }
 723  715  
 724  716  /* Encode DH X9.42 private key in ASN.1 BER syntax. */
 725  717  static CK_RV
 726  718  x942_dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 727  719  {
 728  720          CK_RV           rv = CKR_OK;
 729  721          BerElement      *key_asn = NULLBER, *p8obj_asn = NULLBER;
 730  722          BerValue        *key_octs = NULL, *p8obj_octs = NULL;
 731  723          int             version = SOFT_ASN_VERSION;
 732  724          biginteger_t    tmp_pad = { NULL, 0 };
 733  725  
 734  726          /*
 735  727           * The ASN.1 syntax for a X9.42 DH private key is:
 736  728           *
 737  729           * PKCS#8       \* PrivateKeyInfo *\
 738  730           * ---------------------------------
 739  731           * Sequence {
 740  732           *      version         INTEGER;
 741  733           *      Sequence {      \* PrivateKeyAlgorithm *\
 742  734           *              OID     0x06,   \* DH X9.42 algorithm OID *\
 743  735           *              param(DH-params) OCTETSTRING =
 744  736           *                      PKCS#3  \* DHParameter *\
 745  737           *                      -------------------------
 746  738           *                      Sequence {
 747  739           *                              prime   INTEGER,
 748  740           *                              base    INTEGER,
 749  741           *                              subprime INTEGER \* for X9.42 *\
 750  742           *                      }
 751  743           *      }
 752  744           *      DHPrivateKey    OCTETSTRING =
 753  745           *              PKCS#1  \* DHPrivateKey *\
 754  746           *              --------------------------
 755  747           *              value           INTEGER
 756  748           * }
 757  749           *
 758  750           * The code below starts building the innermost octets
 759  751           * DHPrivateKey, and then builds the PrivateKeyInfo
 760  752           * sequence around that octet string.  The BER syntax
 761  753           * used in this function is (others may be possible):
 762  754           *      { i { to { to to } } to }
 763  755           * where "i" is for integers with fixed size
 764  756           * where "to" is for integers that vary in size (length + value)
 765  757           * where "{}" delimit sequences
 766  758           */
 767  759  
 768  760          /* DHPrivateKey ... */
 769  761          if ((key_asn = ber_alloc()) == NULLBER)
 770  762                  return (CKR_HOST_MEMORY);
 771  763  
 772  764          /* ... value */
 773  765          if ((rv = pad_bigint_attr(OBJ_PRI_DH942_VALUE(objp), &tmp_pad)) !=
 774  766              CKR_OK)
 775  767                  goto cleanup_x942dhpri2asn;
 776  768          if (ber_printf(key_asn, "to", LBER_INTEGER,
 777  769              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 778  770                  rv = CKR_GENERAL_ERROR;
 779  771                  goto cleanup_x942dhpri2asn;
 780  772          }
 781  773  
 782  774          /* Convert key ASN.1 to octet string. */
 783  775          if (ber_flatten(key_asn, &key_octs) == -1) {
 784  776                  rv = CKR_GENERAL_ERROR;
 785  777                  goto cleanup_x942dhpri2asn;
 786  778          }
 787  779  
 788  780          /* PKCS#8 PrivateKeyInfo ... */
 789  781          if ((p8obj_asn = ber_alloc()) == NULLBER) {
 790  782                  rv = CKR_HOST_MEMORY;
 791  783                  goto cleanup_x942dhpri2asn;
 792  784          }
 793  785  
 794  786          /*
 795  787           * Start off the PKCS#8 object ASN.1:
 796  788           * begin-sequence {
 797  789           *      version
 798  790           *      begin-sequence {
 799  791           *              OID,
 800  792           * ...
 801  793           */
 802  794          if (ber_printf(p8obj_asn, "{i{to", version,
 803  795              OID_TAG, DH942_OID, sizeof (DH942_OID)) == -1) {
 804  796                  rv = CKR_GENERAL_ERROR;
 805  797                  goto cleanup_x942dhpri2asn;
 806  798          }
 807  799  
 808  800          /*
 809  801           * Add DH parameters:
 810  802           * ...
 811  803           *              begin-sequence {
 812  804           *                      prime,
 813  805           * ...
 814  806           */
 815  807          if ((rv = pad_bigint_attr(OBJ_PRI_DH942_PRIME(objp), &tmp_pad)) !=
 816  808              CKR_OK)
 817  809                  goto cleanup_x942dhpri2asn;
 818  810          if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
 819  811              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 820  812                  rv = CKR_GENERAL_ERROR;
 821  813                  goto cleanup_x942dhpri2asn;
 822  814          }
 823  815  
 824  816          /*
 825  817           * ...
 826  818           *                      base,
 827  819           * ...
 828  820           */
 829  821          if ((rv = pad_bigint_attr(OBJ_PRI_DH942_BASE(objp), &tmp_pad)) !=
 830  822              CKR_OK)
 831  823                  goto cleanup_x942dhpri2asn;
 832  824          if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
 833  825              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 834  826                  rv = CKR_GENERAL_ERROR;
 835  827                  goto cleanup_x942dhpri2asn;
 836  828          }
 837  829  
 838  830          /*
 839  831           * ...
 840  832           *                      subprime
 841  833           *              } end-sequence
 842  834           */
 843  835          if ((rv = pad_bigint_attr(OBJ_PRI_DH942_SUBPRIME(objp), &tmp_pad)) !=
 844  836              CKR_OK)
 845  837                  goto cleanup_x942dhpri2asn;
 846  838          if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
 847  839              tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
 848  840                  rv = CKR_GENERAL_ERROR;
 849  841                  goto cleanup_x942dhpri2asn;
 850  842          }
 851  843  
 852  844          /*
 853  845           * Add the key octet string:
 854  846           *      } end-sequence
 855  847           *      DHPrivateKey
 856  848           * } end-sequence
 857  849           */
 858  850          if (ber_printf(p8obj_asn, "}o}",
 859  851              key_octs->bv_val, key_octs->bv_len) == -1) {
 860  852                  rv = CKR_GENERAL_ERROR;
 861  853                  goto cleanup_x942dhpri2asn;
 862  854          }
 863  855  
 864  856          /* Convert PKCS#8 object ASN.1 to octet string. */
 865  857          if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
 866  858                  rv = CKR_GENERAL_ERROR;
 867  859                  goto cleanup_x942dhpri2asn;
 868  860          }
 869  861  
 870  862          /* Ship out the PKCS#8 object ASN.1 octet string, if possible. */
 871  863          /*
 872  864           * If the user passes in a null buf, then buf_len is set.
 873  865           * If the user passes in a value with buf_len, then it can
 874  866           * be checked to see if the accompanying buf is big enough.
 875  867           * If it is, the octet string is copied into a pre-malloc'd
 876  868           * buf; otherwise the user must resize buf and call again.
 877  869           * In either case, buf_len is reset to the corrected size.
 878  870           * See PKCS#11 section 11.2.
 879  871           */
 880  872  #ifdef _LP64
 881  873          /* LINTED E_CAST_INT_TO_SMALL_INT */
 882  874          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 883  875  #else
 884  876          if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
 885  877  #endif
  
    | 
      ↓ open down ↓ | 
    168 lines elided | 
    
      ↑ open up ↑ | 
  
 886  878                  *buf_len = p8obj_octs->bv_len;
 887  879                  rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
 888  880                  goto cleanup_x942dhpri2asn;
 889  881          }
 890  882  
 891  883          *buf_len = p8obj_octs->bv_len;
 892  884          (void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
 893  885  
 894  886  cleanup_x942dhpri2asn:
 895  887  
 896      -        if (tmp_pad.big_value != NULL) {
 897      -                (void) memset(tmp_pad.big_value, 0x0, tmp_pad.big_value_len);
 898      -                free(tmp_pad.big_value);
 899      -        }
      888 +        freezero(tmp_pad.big_value, tmp_pad.big_value_len);
 900  889  
 901  890          if (key_asn != NULLBER)
 902  891                  ber_free(key_asn, 1);
 903  892  
 904  893          if (key_octs != NULL)
 905  894                  ber_bvfree(key_octs);
 906  895  
 907  896          if (p8obj_asn != NULLBER)
 908  897                  ber_free(p8obj_asn, 1);
 909  898  
 910  899          if (p8obj_octs != NULL)
 911  900                  ber_bvfree(p8obj_octs);
 912  901  
 913  902          return (rv);
 914  903  }
 915  904  
 916  905  /*
 917  906   * Encode the object key from the soft_object_t into ASN.1 format.
 918  907   */
 919  908  CK_RV
 920  909  soft_object_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
 921  910  {
 922  911          CK_OBJECT_CLASS class = objp->class;
 923  912          CK_KEY_TYPE     keytype = objp->key_type;
 924  913  
 925  914          switch (class) {
 926  915  
 927  916          case CKO_PRIVATE_KEY:
 928  917                  switch (keytype) {
 929  918                  case CKK_RSA:
 930  919                          return (rsa_pri_to_asn1(objp, buf, buf_len));
 931  920  
 932  921                  case CKK_DSA:
 933  922                          return (dsa_pri_to_asn1(objp, buf, buf_len));
 934  923  
 935  924                  case CKK_DH:
 936  925                          return (dh_pri_to_asn1(objp, buf, buf_len));
 937  926  
 938  927                  case CKK_X9_42_DH:
 939  928                          return (x942_dh_pri_to_asn1(objp, buf, buf_len));
 940  929  
 941  930                  default:
 942  931                          return (CKR_FUNCTION_NOT_SUPPORTED);
 943  932                  } /* keytype */
 944  933  
 945  934          default:
 946  935                  return (CKR_FUNCTION_NOT_SUPPORTED);
 947  936  
 948  937          } /* class */
 949  938  }
 950  939  
 951  940  /* Decode ASN.1 BER syntax into RSA private key. */
 952  941  static CK_RV
 953  942  asn1_to_rsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
 954  943  {
 955  944          CK_RV           rv = CKR_OK;
 956  945          BerValue        p8obj_octs, key_octs;
 957  946          BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
 958  947          ber_len_t       size, tmplen;
 959  948          char            *cookie;
 960  949          int             version;
 961  950          uchar_t         oid[sizeof (RSA_OID) + 1];
 962  951          biginteger_t    tmp, tmp_nopad = { NULL, 0 };
 963  952  
 964  953          p8obj_octs.bv_val = (char *)buf;
 965  954  #ifdef _LP64
 966  955          /* LINTED E_CAST_INT_TO_SMALL_INT */
 967  956          p8obj_octs.bv_len = (ber_len_t)buf_len;
 968  957  #else
 969  958          p8obj_octs.bv_len = (ber_len_t)buf_len;
 970  959  #endif
 971  960  
 972  961          key_octs.bv_val = NULL;
 973  962          key_octs.bv_len = 0;
 974  963  
 975  964          /* Decode PKCS#8 object ASN.1, verifying it is RSA private key. */
 976  965          if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
 977  966                  return (CKR_GENERAL_ERROR);
 978  967  
 979  968          /* PKCS#8 PrivateKeyInfo ... */
 980  969          if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
 981  970                  rv = CKR_WRAPPED_KEY_INVALID;
 982  971                  goto cleanup_asn2rsapri;
 983  972          }
 984  973          /* ... begin-sequence { version, */
 985  974          (void) ber_scanf(p8obj_asn, "i", &version);     /* "{i" ? */
 986  975  
 987  976          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
 988  977                  rv = CKR_WRAPPED_KEY_INVALID;
 989  978                  goto cleanup_asn2rsapri;
 990  979          }
 991  980          /* ... begin-sequence { */
 992  981          (void) ber_scanf(p8obj_asn, "{");
 993  982  
 994  983          if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
 995  984                  rv = CKR_WRAPPED_KEY_INVALID;
 996  985                  goto cleanup_asn2rsapri;
 997  986          }
 998  987          /* ... OID, \* RSA algorithm OID *\ */
 999  988          if (size != sizeof (RSA_OID)) {
1000  989                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1001  990                  goto cleanup_asn2rsapri;
1002  991          }
1003  992          size = sizeof (oid);
1004  993          (void) ber_scanf(p8obj_asn, "s", oid, &size);
1005  994          if (memcmp(oid, RSA_OID, size) != 0) {
1006  995                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1007  996                  goto cleanup_asn2rsapri;
1008  997          }
1009  998  
1010  999          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_NULL) {
1011 1000                  rv = CKR_WRAPPED_KEY_INVALID;
1012 1001                  goto cleanup_asn2rsapri;
1013 1002          }
1014 1003          /* ... param(NULL) } end-sequence */
1015 1004          (void) ber_scanf(p8obj_asn, "n");               /* "n}" ? */
1016 1005  
1017 1006          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1018 1007                  rv = CKR_WRAPPED_KEY_INVALID;
1019 1008                  goto cleanup_asn2rsapri;
1020 1009          }
1021 1010          /* ... RSAPrivateKey } end-sequence */
1022 1011          key_octs.bv_len = size + 1;
1023 1012          if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1024 1013                  rv = CKR_HOST_MEMORY;
1025 1014                  goto cleanup_asn2rsapri;
1026 1015          }
1027 1016          (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1028 1017              key_octs.bv_val, &key_octs.bv_len);
1029 1018  
1030 1019          /* Decode key octet string into softtoken key object. */
1031 1020          if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1032 1021                  rv = CKR_GENERAL_ERROR;
1033 1022                  goto cleanup_asn2rsapri;
1034 1023          }
1035 1024  
1036 1025          /* ... begin-sequence { version, */
1037 1026          if (ber_first_element(key_asn, &size, &cookie) != LBER_INTEGER) {
1038 1027                  rv = CKR_WRAPPED_KEY_INVALID;
1039 1028                  goto cleanup_asn2rsapri;
1040 1029          }
1041 1030          (void) ber_scanf(key_asn, "i", &version);       /* "{i" ? */
1042 1031  
1043 1032          /* ... modulus, */
1044 1033          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1045 1034                  rv = CKR_WRAPPED_KEY_INVALID;
1046 1035                  goto cleanup_asn2rsapri;
1047 1036          }
1048 1037          if (size > MAX_RSA_KEY) {
1049 1038                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1050 1039                  goto cleanup_asn2rsapri;
1051 1040          }
1052 1041          tmplen = size + 1;
1053 1042          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1054 1043                  rv = CKR_HOST_MEMORY;
1055 1044                  goto cleanup_asn2rsapri;
1056 1045          }
1057 1046          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1058 1047          tmp.big_value_len = tmplen;
1059 1048          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1060 1049                  free(tmp.big_value);
1061 1050                  goto cleanup_asn2rsapri;
1062 1051          }
1063 1052          free(tmp.big_value);
1064 1053          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_MOD(keyp));
1065 1054  
1066 1055          /* ... public exponent, */
1067 1056          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1068 1057                  rv = CKR_WRAPPED_KEY_INVALID;
1069 1058                  goto error_asn2rsapri;
1070 1059          }
1071 1060          if (size > MAX_RSA_KEY) {
1072 1061                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1073 1062                  goto error_asn2rsapri;
1074 1063          }
1075 1064          tmplen = size + 1;
1076 1065          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1077 1066                  rv = CKR_HOST_MEMORY;
1078 1067                  goto error_asn2rsapri;
1079 1068          }
1080 1069          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1081 1070          tmp.big_value_len = tmplen;
1082 1071          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1083 1072                  free(tmp.big_value);
1084 1073                  goto error_asn2rsapri;
1085 1074          }
1086 1075          free(tmp.big_value);
1087 1076          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PUBEXPO(keyp));
1088 1077  
1089 1078          /* ... private exponent, */
1090 1079          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1091 1080                  rv = CKR_WRAPPED_KEY_INVALID;
1092 1081                  goto error_asn2rsapri;
1093 1082          }
1094 1083          if (size > MAX_RSA_KEY) {
1095 1084                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1096 1085                  goto error_asn2rsapri;
1097 1086          }
1098 1087          tmplen = size + 1;
1099 1088          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1100 1089                  rv = CKR_HOST_MEMORY;
1101 1090                  goto error_asn2rsapri;
1102 1091          }
1103 1092          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1104 1093          tmp.big_value_len = tmplen;
1105 1094          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1106 1095                  free(tmp.big_value);
1107 1096                  goto error_asn2rsapri;
1108 1097          }
1109 1098          free(tmp.big_value);
1110 1099          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIEXPO(keyp));
1111 1100  
1112 1101          /* ... prime 1, */
1113 1102          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1114 1103                  rv = CKR_WRAPPED_KEY_INVALID;
1115 1104                  goto error_asn2rsapri;
1116 1105          }
1117 1106          if (size > MAX_RSA_KEY) {
1118 1107                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1119 1108                  goto error_asn2rsapri;
1120 1109          }
1121 1110          tmplen = size + 1;
1122 1111          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1123 1112                  rv = CKR_HOST_MEMORY;
1124 1113                  goto error_asn2rsapri;
1125 1114          }
1126 1115          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1127 1116          tmp.big_value_len = tmplen;
1128 1117          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1129 1118                  free(tmp.big_value);
1130 1119                  goto error_asn2rsapri;
1131 1120          }
1132 1121          free(tmp.big_value);
1133 1122          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME1(keyp));
1134 1123  
1135 1124          /* ... prime 2, */
1136 1125          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1137 1126                  rv = CKR_WRAPPED_KEY_INVALID;
1138 1127                  goto error_asn2rsapri;
1139 1128          }
1140 1129          if (size > MAX_RSA_KEY) {
1141 1130                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1142 1131                  goto error_asn2rsapri;
1143 1132          }
1144 1133          tmplen = size + 1;
1145 1134          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1146 1135                  rv = CKR_HOST_MEMORY;
1147 1136                  goto error_asn2rsapri;
1148 1137          }
1149 1138          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1150 1139          tmp.big_value_len = tmplen;
1151 1140          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1152 1141                  free(tmp.big_value);
1153 1142                  goto error_asn2rsapri;
1154 1143          }
1155 1144          free(tmp.big_value);
1156 1145          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME2(keyp));
1157 1146  
1158 1147          /* ... exponent 1, */
1159 1148          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1160 1149                  rv = CKR_WRAPPED_KEY_INVALID;
1161 1150                  goto error_asn2rsapri;
1162 1151          }
1163 1152          if (size > MAX_RSA_KEY) {
1164 1153                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1165 1154                  goto error_asn2rsapri;
1166 1155          }
1167 1156          tmplen = size + 1;
1168 1157          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1169 1158                  rv = CKR_HOST_MEMORY;
1170 1159                  goto error_asn2rsapri;
1171 1160          }
1172 1161          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1173 1162          tmp.big_value_len = tmplen;
1174 1163          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1175 1164                  free(tmp.big_value);
1176 1165                  goto error_asn2rsapri;
1177 1166          }
1178 1167          free(tmp.big_value);
1179 1168          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO1(keyp));
1180 1169  
1181 1170          /* ... exponent 2, */
1182 1171          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1183 1172                  rv = CKR_WRAPPED_KEY_INVALID;
1184 1173                  goto error_asn2rsapri;
1185 1174          }
1186 1175          if (size > MAX_RSA_KEY) {
1187 1176                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1188 1177                  goto error_asn2rsapri;
1189 1178          }
1190 1179          tmplen = size + 1;
1191 1180          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1192 1181                  rv = CKR_HOST_MEMORY;
1193 1182                  goto error_asn2rsapri;
1194 1183          }
1195 1184          (void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
1196 1185          tmp.big_value_len = tmplen;
1197 1186          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1198 1187                  free(tmp.big_value);
1199 1188                  goto error_asn2rsapri;
1200 1189          }
1201 1190          free(tmp.big_value);
1202 1191          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO2(keyp));
1203 1192  
1204 1193          /* ... coefficient } end-sequence */
1205 1194          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1206 1195                  rv = CKR_WRAPPED_KEY_INVALID;
1207 1196                  goto error_asn2rsapri;
1208 1197          }
1209 1198          if (size > MAX_RSA_KEY) {
1210 1199                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1211 1200                  goto error_asn2rsapri;
1212 1201          }
1213 1202          tmplen = size + 1;
1214 1203          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1215 1204                  rv = CKR_HOST_MEMORY;
1216 1205                  goto error_asn2rsapri;
1217 1206          }
1218 1207          (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1219 1208              tmp.big_value, &tmplen);
1220 1209          tmp.big_value_len = tmplen;
1221 1210          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1222 1211                  free(tmp.big_value);
1223 1212                  goto error_asn2rsapri;
1224 1213          }
1225 1214          free(tmp.big_value);
1226 1215          copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_COEF(keyp));
1227 1216  
1228 1217          goto cleanup_asn2rsapri;
1229 1218  
1230 1219  error_asn2rsapri:
1231 1220  
1232 1221          bigint_attr_cleanup(KEY_PRI_RSA_MOD(keyp));
  
    | 
      ↓ open down ↓ | 
    323 lines elided | 
    
      ↑ open up ↑ | 
  
1233 1222          bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(keyp));
1234 1223          bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(keyp));
1235 1224          bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(keyp));
1236 1225          bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(keyp));
1237 1226          bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(keyp));
1238 1227          bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(keyp));
1239 1228          bigint_attr_cleanup(KEY_PRI_RSA_COEF(keyp));
1240 1229  
1241 1230  cleanup_asn2rsapri:
1242 1231  
1243      -        if (tmp_nopad.big_value != NULL) {
1244      -                (void) memset(tmp_nopad.big_value, 0x0,
1245      -                    tmp_nopad.big_value_len);
1246      -                free(tmp_nopad.big_value);
1247      -        }
     1232 +        freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1248 1233  
1249 1234          if (p8obj_asn != NULLBER)
1250 1235                  ber_free(p8obj_asn, 1);
1251 1236  
1252 1237          if (key_octs.bv_val != NULL)
1253 1238                  free(key_octs.bv_val);
1254 1239  
1255 1240          if (key_asn != NULLBER)
1256 1241                  ber_free(key_asn, 1);
1257 1242  
1258 1243          return (rv);
1259 1244  }
1260 1245  
1261 1246  /* Decode ASN.1 BER syntax into DSA private key. */
1262 1247  static CK_RV
1263 1248  asn1_to_dsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1264 1249  {
1265 1250          CK_RV           rv = CKR_OK;
1266 1251          BerValue        p8obj_octs, key_octs;
1267 1252          BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1268 1253          ber_len_t       size, tmplen;
1269 1254          char            *cookie;
1270 1255          int             version;
1271 1256          uchar_t         oid[sizeof (DSA_OID) + 1];
1272 1257          biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1273 1258  
1274 1259          p8obj_octs.bv_val = (char *)buf;
1275 1260  #ifdef _LP64
1276 1261          /* LINTED E_CAST_INT_TO_SMALL_INT */
1277 1262          p8obj_octs.bv_len = (ber_len_t)buf_len;
1278 1263  #else
1279 1264          p8obj_octs.bv_len = (ber_len_t)buf_len;
1280 1265  #endif
1281 1266  
1282 1267          key_octs.bv_val = NULL;
1283 1268          key_octs.bv_len = 0;
1284 1269  
1285 1270          /* Decode PKCS#8 object ASN.1, verifying it is DSA private key. */
1286 1271          if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1287 1272                  return (CKR_GENERAL_ERROR);
1288 1273  
1289 1274          /* PKCS#8 PrivateKeyInfo ... */
1290 1275          if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1291 1276                  rv = CKR_WRAPPED_KEY_INVALID;
1292 1277                  goto cleanup_asn2dsapri;
1293 1278          }
1294 1279          /* ... begin-sequence { version, */
1295 1280          (void) ber_scanf(p8obj_asn, "i", &version);     /* "{i" ? */
1296 1281  
1297 1282          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1298 1283                  rv = CKR_WRAPPED_KEY_INVALID;
1299 1284                  goto cleanup_asn2dsapri;
1300 1285          }
1301 1286          /* ... begin-sequence { */
1302 1287          (void) ber_scanf(p8obj_asn, "{");
1303 1288  
1304 1289          if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1305 1290                  rv = CKR_WRAPPED_KEY_INVALID;
1306 1291                  goto cleanup_asn2dsapri;
1307 1292          }
1308 1293          /* ... OID, \* DSA algorithm OID *\ */
1309 1294          if (size != sizeof (DSA_OID)) {
1310 1295                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1311 1296                  goto cleanup_asn2dsapri;
1312 1297          }
1313 1298          size = sizeof (oid);
1314 1299          (void) ber_scanf(p8obj_asn, "s", oid, &size);
1315 1300          if (memcmp(oid, DSA_OID, size) != 0) {
1316 1301                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1317 1302                  goto cleanup_asn2dsapri;
1318 1303          }
1319 1304  
1320 1305          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1321 1306                  rv = CKR_WRAPPED_KEY_INVALID;
1322 1307                  goto cleanup_asn2dsapri;
1323 1308          }
1324 1309          /* ... begin-sequence { */
1325 1310          (void) ber_scanf(p8obj_asn, "{");
1326 1311  
1327 1312          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1328 1313                  rv = CKR_WRAPPED_KEY_INVALID;
1329 1314                  goto cleanup_asn2dsapri;
1330 1315          }
1331 1316          /* ... prime, */
1332 1317          if (size > MAX_DSA_KEY) {
1333 1318                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1334 1319                  goto cleanup_asn2dsapri;
1335 1320          }
1336 1321          tmplen = size + 1;
1337 1322          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1338 1323                  rv = CKR_HOST_MEMORY;
1339 1324                  goto cleanup_asn2dsapri;
1340 1325          }
1341 1326          (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1342 1327          tmp.big_value_len = tmplen;
1343 1328          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1344 1329                  free(tmp.big_value);
1345 1330                  goto cleanup_asn2dsapri;
1346 1331          }
1347 1332          free(tmp.big_value);
1348 1333          copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_PRIME(keyp));
1349 1334  
1350 1335          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1351 1336                  rv = CKR_WRAPPED_KEY_INVALID;
1352 1337                  goto error_asn2dsapri;
1353 1338          }
1354 1339          /* ... subprime, */
1355 1340          if (size > MAX_DSA_KEY) {
1356 1341                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1357 1342                  goto error_asn2dsapri;
1358 1343          }
1359 1344          tmplen = size + 1;
1360 1345          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1361 1346                  rv = CKR_HOST_MEMORY;
1362 1347                  goto error_asn2dsapri;
1363 1348          }
1364 1349          (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1365 1350          tmp.big_value_len = tmplen;
1366 1351          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1367 1352                  free(tmp.big_value);
1368 1353                  goto error_asn2dsapri;
1369 1354          }
1370 1355          free(tmp.big_value);
1371 1356          copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_SUBPRIME(keyp));
1372 1357  
1373 1358          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1374 1359                  rv = CKR_WRAPPED_KEY_INVALID;
1375 1360                  goto error_asn2dsapri;
1376 1361          }
1377 1362          /* ... base } end-sequence } end-sequence */
1378 1363          if (size > MAX_DSA_KEY) {
1379 1364                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1380 1365                  goto error_asn2dsapri;
1381 1366          }
1382 1367          tmplen = size + 1;
1383 1368          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1384 1369                  rv = CKR_HOST_MEMORY;
1385 1370                  goto error_asn2dsapri;
1386 1371          }
1387 1372          (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1388 1373              tmp.big_value, &tmplen);
1389 1374          tmp.big_value_len = tmplen;
1390 1375          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1391 1376                  free(tmp.big_value);
1392 1377                  goto error_asn2dsapri;
1393 1378          }
1394 1379          free(tmp.big_value);
1395 1380          copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_BASE(keyp));
1396 1381  
1397 1382          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1398 1383                  rv = CKR_WRAPPED_KEY_INVALID;
1399 1384                  goto error_asn2dsapri;
1400 1385          }
1401 1386          /* ... DSAPrivateKey } end-sequence */
1402 1387          key_octs.bv_len = size + 1;
1403 1388          if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1404 1389                  rv = CKR_HOST_MEMORY;
1405 1390                  goto error_asn2dsapri;
1406 1391          }
1407 1392          (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1408 1393              key_octs.bv_val, &key_octs.bv_len);
1409 1394  
1410 1395          /* Decode key octet string into softtoken key object. */
1411 1396          if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1412 1397                  rv = CKR_GENERAL_ERROR;
1413 1398                  goto error_asn2dsapri;
1414 1399          }
1415 1400  
1416 1401          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1417 1402                  rv = CKR_WRAPPED_KEY_INVALID;
1418 1403                  goto error_asn2dsapri;
1419 1404          }
1420 1405          /* ... value } end-sequence */
1421 1406          if (size > MAX_DSA_KEY) {
1422 1407                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1423 1408                  goto error_asn2dsapri;
1424 1409          }
1425 1410          tmplen = size + 1;
1426 1411          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1427 1412                  rv = CKR_HOST_MEMORY;
1428 1413                  goto error_asn2dsapri;
1429 1414          }
1430 1415          (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1431 1416              tmp.big_value, &tmplen);
1432 1417          tmp.big_value_len = tmplen;
1433 1418          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1434 1419                  free(tmp.big_value);
1435 1420                  goto error_asn2dsapri;
1436 1421          }
1437 1422          free(tmp.big_value);
1438 1423          copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_VALUE(keyp));
1439 1424  
1440 1425          goto cleanup_asn2dsapri;
  
    | 
      ↓ open down ↓ | 
    183 lines elided | 
    
      ↑ open up ↑ | 
  
1441 1426  
1442 1427  error_asn2dsapri:
1443 1428  
1444 1429          bigint_attr_cleanup(KEY_PRI_DSA_PRIME(keyp));
1445 1430          bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(keyp));
1446 1431          bigint_attr_cleanup(KEY_PRI_DSA_BASE(keyp));
1447 1432          bigint_attr_cleanup(KEY_PRI_DSA_VALUE(keyp));
1448 1433  
1449 1434  cleanup_asn2dsapri:
1450 1435  
1451      -        if (tmp_nopad.big_value != NULL) {
1452      -                (void) memset(tmp_nopad.big_value, 0x0,
1453      -                    tmp_nopad.big_value_len);
1454      -                free(tmp_nopad.big_value);
1455      -        }
     1436 +        freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1456 1437  
1457 1438          if (p8obj_asn != NULLBER)
1458 1439                  ber_free(p8obj_asn, 1);
1459 1440  
1460 1441          if (key_octs.bv_val != NULL)
1461 1442                  free(key_octs.bv_val);
1462 1443  
1463 1444          if (key_asn != NULLBER)
1464 1445                  ber_free(key_asn, 1);
1465 1446  
1466 1447          return (rv);
1467 1448  }
1468 1449  
1469 1450  /* Decode ASN.1 BER syntax into DH private key. */
1470 1451  static CK_RV
1471 1452  asn1_to_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1472 1453  {
1473 1454          CK_RV           rv = CKR_OK;
1474 1455          BerValue        p8obj_octs, key_octs;
1475 1456          BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1476 1457          ber_len_t       size, tmplen;
1477 1458          char            *cookie;
1478 1459          int             version;
1479 1460          uchar_t         oid[sizeof (DH_OID) + 1];
1480 1461          biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1481 1462  
1482 1463          p8obj_octs.bv_val = (char *)buf;
1483 1464  #ifdef _LP64
1484 1465          /* LINTED E_CAST_INT_TO_SMALL_INT */
1485 1466          p8obj_octs.bv_len = (ber_len_t)buf_len;
1486 1467  #else
1487 1468          p8obj_octs.bv_len = (ber_len_t)buf_len;
1488 1469  #endif
1489 1470  
1490 1471          key_octs.bv_val = NULL;
1491 1472          key_octs.bv_len = 0;
1492 1473  
1493 1474          /* Decode PKCS#8 object ASN.1, verifying it is DH private key. */
1494 1475          if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1495 1476                  return (CKR_GENERAL_ERROR);
1496 1477  
1497 1478          /* PKCS#8 PrivateKeyInfo ... */
1498 1479          if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1499 1480                  rv = CKR_WRAPPED_KEY_INVALID;
1500 1481                  goto cleanup_asn2dhpri;
1501 1482          }
1502 1483          /* ... begin-sequence { version, */
1503 1484          (void) ber_scanf(p8obj_asn, "i", &version);     /* "{i" ? */
1504 1485  
1505 1486          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1506 1487                  rv = CKR_WRAPPED_KEY_INVALID;
1507 1488                  goto cleanup_asn2dhpri;
1508 1489          }
1509 1490          /* ... begin-sequence { */
1510 1491          (void) ber_scanf(p8obj_asn, "{");
1511 1492  
1512 1493          if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1513 1494                  rv = CKR_WRAPPED_KEY_INVALID;
1514 1495                  goto cleanup_asn2dhpri;
1515 1496          }
1516 1497          /* ... OID, \* DH algorithm OID *\ */
1517 1498          if (size != sizeof (DH_OID)) {
1518 1499                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1519 1500                  goto cleanup_asn2dhpri;
1520 1501          }
1521 1502          size = sizeof (oid);
1522 1503          (void) ber_scanf(p8obj_asn, "s", oid, &size);
1523 1504          if (memcmp(oid, DH_OID, size) != 0) {
1524 1505                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1525 1506                  goto cleanup_asn2dhpri;
1526 1507          }
1527 1508  
1528 1509          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1529 1510                  rv = CKR_WRAPPED_KEY_INVALID;
1530 1511                  goto cleanup_asn2dhpri;
1531 1512          }
1532 1513          /* ... begin-sequence { */
1533 1514          (void) ber_scanf(p8obj_asn, "{");
1534 1515  
1535 1516          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1536 1517                  rv = CKR_WRAPPED_KEY_INVALID;
1537 1518                  goto cleanup_asn2dhpri;
1538 1519          }
1539 1520          /* ... prime, */
1540 1521          if (size > MAX_DH_KEY) {
1541 1522                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1542 1523                  goto cleanup_asn2dhpri;
1543 1524          }
1544 1525          tmplen = size + 1;
1545 1526          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1546 1527                  rv = CKR_HOST_MEMORY;
1547 1528                  goto cleanup_asn2dhpri;
1548 1529          }
1549 1530          (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1550 1531          tmp.big_value_len = tmplen;
1551 1532          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1552 1533                  free(tmp.big_value);
1553 1534                  goto cleanup_asn2dhpri;
1554 1535          }
1555 1536          free(tmp.big_value);
1556 1537          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_PRIME(keyp));
1557 1538  
1558 1539          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1559 1540                  rv = CKR_WRAPPED_KEY_INVALID;
1560 1541                  goto error_asn2dhpri;
1561 1542          }
1562 1543          /* ... base } end-sequence } end-sequence */
1563 1544          if (size > MAX_DH_KEY) {
1564 1545                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1565 1546                  goto error_asn2dhpri;
1566 1547          }
1567 1548          tmplen = size + 1;
1568 1549          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1569 1550                  rv = CKR_HOST_MEMORY;
1570 1551                  goto error_asn2dhpri;
1571 1552          }
1572 1553          (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1573 1554              tmp.big_value, &tmplen);
1574 1555          tmp.big_value_len = tmplen;
1575 1556          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1576 1557                  free(tmp.big_value);
1577 1558                  goto error_asn2dhpri;
1578 1559          }
1579 1560          free(tmp.big_value);
1580 1561          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_BASE(keyp));
1581 1562  
1582 1563          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1583 1564                  rv = CKR_WRAPPED_KEY_INVALID;
1584 1565                  goto error_asn2dhpri;
1585 1566          }
1586 1567          /* ... DHPrivateKey } end-sequence */
1587 1568          key_octs.bv_len = size + 1;
1588 1569          if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1589 1570                  rv = CKR_HOST_MEMORY;
1590 1571                  goto error_asn2dhpri;
1591 1572          }
1592 1573          (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1593 1574              key_octs.bv_val, &key_octs.bv_len);
1594 1575  
1595 1576          /* Decode key octet string into softtoken key object. */
1596 1577          if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1597 1578                  rv = CKR_GENERAL_ERROR;
1598 1579                  goto error_asn2dhpri;
1599 1580          }
1600 1581  
1601 1582          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1602 1583                  rv = CKR_WRAPPED_KEY_INVALID;
1603 1584                  goto error_asn2dhpri;
1604 1585          }
1605 1586          /* ... value } end-sequence */
1606 1587          if (size > MAX_DH_KEY) {
1607 1588                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1608 1589                  goto error_asn2dhpri;
1609 1590          }
1610 1591          tmplen = size + 1;
1611 1592          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1612 1593                  rv = CKR_HOST_MEMORY;
1613 1594                  goto error_asn2dhpri;
1614 1595          }
1615 1596          (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1616 1597              tmp.big_value, &tmplen);
1617 1598          tmp.big_value_len = tmplen;
1618 1599          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1619 1600                  free(tmp.big_value);
1620 1601                  goto error_asn2dhpri;
1621 1602          }
1622 1603          free(tmp.big_value);
1623 1604          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_VALUE(keyp));
1624 1605  
  
    | 
      ↓ open down ↓ | 
    159 lines elided | 
    
      ↑ open up ↑ | 
  
1625 1606          goto cleanup_asn2dhpri;
1626 1607  
1627 1608  error_asn2dhpri:
1628 1609  
1629 1610          bigint_attr_cleanup(KEY_PRI_DH_PRIME(keyp));
1630 1611          bigint_attr_cleanup(KEY_PRI_DH_BASE(keyp));
1631 1612          bigint_attr_cleanup(KEY_PRI_DH_VALUE(keyp));
1632 1613  
1633 1614  cleanup_asn2dhpri:
1634 1615  
1635      -        if (tmp_nopad.big_value != NULL) {
1636      -                (void) memset(tmp_nopad.big_value, 0x0,
1637      -                    tmp_nopad.big_value_len);
1638      -                free(tmp_nopad.big_value);
1639      -        }
     1616 +        freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1640 1617  
1641 1618          if (p8obj_asn != NULLBER)
1642 1619                  ber_free(p8obj_asn, 1);
1643 1620  
1644 1621          if (key_octs.bv_val != NULL)
1645 1622                  free(key_octs.bv_val);
1646 1623  
1647 1624          if (key_asn != NULLBER)
1648 1625                  ber_free(key_asn, 1);
1649 1626  
1650 1627          return (rv);
1651 1628  }
1652 1629  
1653 1630  /* Decode ASN.1 BER syntax into DH X9.42 private key. */
1654 1631  static CK_RV
1655 1632  asn1_to_x942_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
1656 1633  {
1657 1634          CK_RV           rv = CKR_OK;
1658 1635          BerValue        p8obj_octs, key_octs;
1659 1636          BerElement      *p8obj_asn = NULLBER, *key_asn = NULLBER;
1660 1637          ber_len_t       size, tmplen;
1661 1638          char            *cookie;
1662 1639          int             version;
1663 1640          uchar_t         oid[sizeof (DH942_OID) + 1];
1664 1641          biginteger_t    tmp, tmp_nopad = { NULL, 0 };
1665 1642  
1666 1643          p8obj_octs.bv_val = (char *)buf;
1667 1644  #ifdef _LP64
1668 1645          /* LINTED E_CAST_INT_TO_SMALL_INT */
1669 1646          p8obj_octs.bv_len = (ber_len_t)buf_len;
1670 1647  #else
1671 1648          p8obj_octs.bv_len = (ber_len_t)buf_len;
1672 1649  #endif
1673 1650  
1674 1651          key_octs.bv_val = NULL;
1675 1652          key_octs.bv_len = 0;
1676 1653  
1677 1654          /* Decode PKCS#8 object ASN.1, verifying it is DH X9.42 private key. */
1678 1655          if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
1679 1656                  return (CKR_GENERAL_ERROR);
1680 1657  
1681 1658          /* PKCS#8 PrivateKeyInfo ... */
1682 1659          if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
1683 1660                  rv = CKR_WRAPPED_KEY_INVALID;
1684 1661                  goto cleanup_asn2x942dhpri;
1685 1662          }
1686 1663          /* ... begin-sequence { version, */
1687 1664          (void) ber_scanf(p8obj_asn, "i", &version);     /* "{i" ? */
1688 1665  
1689 1666          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1690 1667                  rv = CKR_WRAPPED_KEY_INVALID;
1691 1668                  goto cleanup_asn2x942dhpri;
1692 1669          }
1693 1670          /* ... begin-sequence { */
1694 1671          (void) ber_scanf(p8obj_asn, "{");
1695 1672  
1696 1673          if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
1697 1674                  rv = CKR_WRAPPED_KEY_INVALID;
1698 1675                  goto cleanup_asn2x942dhpri;
1699 1676          }
1700 1677          /* ... OID, \* DH X9.42 algorithm OID *\ */
1701 1678          if (size != sizeof (DH942_OID)) {
1702 1679                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1703 1680                  goto cleanup_asn2x942dhpri;
1704 1681          }
1705 1682          size = sizeof (oid);
1706 1683          (void) ber_scanf(p8obj_asn, "s", oid, &size);
1707 1684          if (memcmp(oid, DH942_OID, size) != 0) {
1708 1685                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1709 1686                  goto cleanup_asn2x942dhpri;
1710 1687          }
1711 1688  
1712 1689          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
1713 1690                  rv = CKR_WRAPPED_KEY_INVALID;
1714 1691                  goto cleanup_asn2x942dhpri;
1715 1692          }
1716 1693          /* ... begin-sequence { */
1717 1694          (void) ber_scanf(p8obj_asn, "{");
1718 1695  
1719 1696          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1720 1697                  rv = CKR_WRAPPED_KEY_INVALID;
1721 1698                  goto cleanup_asn2x942dhpri;
1722 1699          }
1723 1700          /* ... prime, */
1724 1701          if (size > MAX_DH942_KEY) {
1725 1702                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1726 1703                  goto cleanup_asn2x942dhpri;
1727 1704          }
1728 1705          tmplen = size + 1;
1729 1706          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1730 1707                  rv = CKR_HOST_MEMORY;
1731 1708                  goto cleanup_asn2x942dhpri;
1732 1709          }
1733 1710          (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1734 1711          tmp.big_value_len = tmplen;
1735 1712          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1736 1713                  free(tmp.big_value);
1737 1714                  goto cleanup_asn2x942dhpri;
1738 1715          }
1739 1716          free(tmp.big_value);
1740 1717          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_PRIME(keyp));
1741 1718  
1742 1719          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1743 1720                  rv = CKR_WRAPPED_KEY_INVALID;
1744 1721                  goto error_asn2x942dhpri;
1745 1722          }
1746 1723          /* ... base, */
1747 1724          if (size > MAX_DH942_KEY) {
1748 1725                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1749 1726                  goto error_asn2x942dhpri;
1750 1727          }
1751 1728          tmplen = size + 1;
1752 1729          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1753 1730                  rv = CKR_HOST_MEMORY;
1754 1731                  goto error_asn2x942dhpri;
1755 1732          }
1756 1733          (void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
1757 1734          tmp.big_value_len = tmplen;
1758 1735          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1759 1736                  free(tmp.big_value);
1760 1737                  goto error_asn2x942dhpri;
1761 1738          }
1762 1739          free(tmp.big_value);
1763 1740          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_BASE(keyp));
1764 1741  
1765 1742          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
1766 1743                  rv = CKR_WRAPPED_KEY_INVALID;
1767 1744                  goto error_asn2x942dhpri;
1768 1745          }
1769 1746          /* ... subprime } end-sequence } end-sequence */
1770 1747          if (size > MAX_DH942_KEY) {
1771 1748                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1772 1749                  goto error_asn2x942dhpri;
1773 1750          }
1774 1751          tmplen = size + 1;
1775 1752          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1776 1753                  rv = CKR_HOST_MEMORY;
1777 1754                  goto error_asn2x942dhpri;
1778 1755          }
1779 1756          (void) ber_scanf(p8obj_asn, "s",                /* "s}}" ? */
1780 1757              tmp.big_value, &tmplen);
1781 1758          tmp.big_value_len = tmplen;
1782 1759          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1783 1760                  free(tmp.big_value);
1784 1761                  goto error_asn2x942dhpri;
1785 1762          }
1786 1763          free(tmp.big_value);
1787 1764          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_SUBPRIME(keyp));
1788 1765  
1789 1766          if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
1790 1767                  rv = CKR_WRAPPED_KEY_INVALID;
1791 1768                  goto error_asn2x942dhpri;
1792 1769          }
1793 1770          /* ... DHPrivateKey } end-sequence */
1794 1771          key_octs.bv_len = size + 1;
1795 1772          if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
1796 1773                  rv = CKR_HOST_MEMORY;
1797 1774                  goto error_asn2x942dhpri;
1798 1775          }
1799 1776          (void) ber_scanf(p8obj_asn, "s",                /* "s}" ? */
1800 1777              key_octs.bv_val, &key_octs.bv_len);
1801 1778  
1802 1779          /* Decode key octet string into softtoken key object. */
1803 1780          if ((key_asn = ber_init(&key_octs)) == NULLBER) {
1804 1781                  rv = CKR_GENERAL_ERROR;
1805 1782                  goto error_asn2x942dhpri;
1806 1783          }
1807 1784  
1808 1785          if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
1809 1786                  rv = CKR_WRAPPED_KEY_INVALID;
1810 1787                  goto error_asn2x942dhpri;
1811 1788          }
1812 1789          /* ... value } end-sequence */
1813 1790          if (size > MAX_DH942_KEY) {
1814 1791                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1815 1792                  goto error_asn2x942dhpri;
1816 1793          }
1817 1794          tmplen = size + 1;
1818 1795          if ((tmp.big_value = malloc(tmplen)) == NULL) {
1819 1796                  rv = CKR_HOST_MEMORY;
1820 1797                  goto error_asn2x942dhpri;
1821 1798          }
1822 1799          (void) ber_scanf(key_asn, "s",          /* "s}" ? */
1823 1800              tmp.big_value, &tmplen);
1824 1801          tmp.big_value_len = tmplen;
1825 1802          if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
1826 1803                  free(tmp.big_value);
1827 1804                  goto error_asn2x942dhpri;
1828 1805          }
1829 1806          free(tmp.big_value);
1830 1807          copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_VALUE(keyp));
1831 1808  
1832 1809          goto cleanup_asn2x942dhpri;
  
    | 
      ↓ open down ↓ | 
    183 lines elided | 
    
      ↑ open up ↑ | 
  
1833 1810  
1834 1811  error_asn2x942dhpri:
1835 1812  
1836 1813          bigint_attr_cleanup(KEY_PRI_DH942_PRIME(keyp));
1837 1814          bigint_attr_cleanup(KEY_PRI_DH942_BASE(keyp));
1838 1815          bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(keyp));
1839 1816          bigint_attr_cleanup(KEY_PRI_DH942_VALUE(keyp));
1840 1817  
1841 1818  cleanup_asn2x942dhpri:
1842 1819  
1843      -        if (tmp_nopad.big_value != NULL) {
1844      -                (void) memset(tmp_nopad.big_value, 0x0,
1845      -                    tmp_nopad.big_value_len);
1846      -                free(tmp_nopad.big_value);
1847      -        }
     1820 +        freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
1848 1821  
1849 1822          if (p8obj_asn != NULLBER)
1850 1823                  ber_free(p8obj_asn, 1);
1851 1824  
1852 1825          if (key_octs.bv_val != NULL)
1853 1826                  free(key_octs.bv_val);
1854 1827  
1855 1828          if (key_asn != NULLBER)
1856 1829                  ber_free(key_asn, 1);
1857 1830  
1858 1831          return (rv);
1859 1832  }
1860 1833  
1861 1834  /*
1862 1835   * Decode the object key from ASN.1 format into soft_object_t.
1863 1836   */
1864 1837  CK_RV
1865 1838  soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len)
1866 1839  {
1867      -        CK_RV           rv = CKR_OK;
     1840 +        CK_RV           rv = CKR_OK;
1868 1841          CK_OBJECT_CLASS class = objp->class;
1869 1842          CK_KEY_TYPE     keytype = objp->key_type;
1870 1843          private_key_obj_t *pvk;
1871 1844  
1872 1845          switch (class) {
1873 1846  
1874 1847          case CKO_PRIVATE_KEY:
1875 1848                  /* Allocate storage for Private Key Object. */
1876 1849                  if ((pvk = calloc(1, sizeof (private_key_obj_t))) == NULL) {
1877 1850                          rv = CKR_HOST_MEMORY;
1878 1851                          return (rv);
1879 1852                  }
1880 1853  
1881 1854                  switch (keytype) {
1882 1855                  case CKK_RSA:
1883 1856                          rv = asn1_to_rsa_pri(pvk, buf, buf_len);
1884 1857                          break;
1885 1858  
1886 1859                  case CKK_DSA:
1887 1860                          rv = asn1_to_dsa_pri(pvk, buf, buf_len);
1888 1861                          break;
1889 1862  
1890 1863                  case CKK_DH:
1891 1864                          rv = asn1_to_dh_pri(pvk, buf, buf_len);
1892 1865                          break;
1893 1866  
1894 1867                  case CKK_X9_42_DH:
1895 1868                          rv = asn1_to_x942_dh_pri(pvk, buf, buf_len);
1896 1869                          break;
1897 1870  
1898 1871                  default:
1899 1872                          rv = CKR_FUNCTION_NOT_SUPPORTED;
1900 1873                          break;
1901 1874  
1902 1875                  } /* keytype */
1903 1876  
1904 1877                  if (rv != CKR_OK)
1905 1878                          free(pvk);
1906 1879                  else
1907 1880                          objp->object_class_u.private_key = pvk;
1908 1881                  break;
1909 1882  
1910 1883          default:
1911 1884                  rv = CKR_FUNCTION_NOT_SUPPORTED;
1912 1885                  break;
1913 1886  
1914 1887          } /* class */
1915 1888  
1916 1889          return (rv);
1917 1890  }
  
    | 
      ↓ open down ↓ | 
    40 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX