Print this page
    
5878 Additional lint fixes for sunstudio12.1 and more modern OpenSSL
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Alexander Pyhalov <alp@rsu.ru>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
          +++ new/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
   1    1  /*
   2    2   * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
   3    3   *
   4    4   * Use is subject to license terms.
   5    5   */
   6    6  /*
   7    7   * Copyright (c) 2012, OmniTI Computer Consulting, Inc. All rights reserved.
   8    8   */
   9    9  /*
  10   10   * Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
  11   11   * project 2000.
  12   12   */
  13   13  /*
  14   14   * ====================================================================
  15   15   * Copyright (c) 2000-2004 The OpenSSL Project.  All rights reserved.
  16   16   *
  17   17   * Redistribution and use in source and binary forms, with or without
  18   18   * modification, are permitted provided that the following conditions
  19   19   * are met:
  20   20   *
  21   21   * 1. Redistributions of source code must retain the above copyright
  22   22   *    notice, this list of conditions and the following disclaimer.
  23   23   *
  24   24   * 2. Redistributions in binary form must reproduce the above copyright
  25   25   *    notice, this list of conditions and the following disclaimer in
  26   26   *    the documentation and/or other materials provided with the
  27   27   *    distribution.
  28   28   *
  29   29   * 3. All advertising materials mentioning features or use of this
  30   30   *    software must display the following acknowledgment:
  31   31   *    "This product includes software developed by the OpenSSL Project
  32   32   *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  33   33   *
  34   34   * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  35   35   *    endorse or promote products derived from this software without
  36   36   *    prior written permission. For written permission, please contact
  37   37   *    licensing@OpenSSL.org.
  38   38   *
  39   39   * 5. Products derived from this software may not be called "OpenSSL"
  40   40   *    nor may "OpenSSL" appear in their names without prior written
  41   41   *    permission of the OpenSSL Project.
  42   42   *
  43   43   * 6. Redistributions of any form whatsoever must retain the following
  44   44   *    acknowledgment:
  45   45   *    "This product includes software developed by the OpenSSL Project
  46   46   *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  47   47   *
  48   48   * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  49   49   * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50   50   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  51   51   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
  52   52   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  53   53   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  54   54   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55   55   * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  56   56   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  57   57   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  58   58   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  59   59   * OF THE POSSIBILITY OF SUCH DAMAGE.
  60   60   * ====================================================================
  61   61   *
  62   62   * This product includes cryptographic software written by Eric Young
  63   63   * (eay@cryptsoft.com).  This product includes software written by Tim
  64   64   * Hudson (tjh@cryptsoft.com).
  65   65   *
  66   66   */
  67   67  
  68   68  #include <stdlib.h>
  69   69  #include <kmfapiP.h>
  70   70  #include <ber_der.h>
  71   71  #include <fcntl.h>
  72   72  #include <sys/stat.h>
  73   73  #include <dirent.h>
  74   74  #include <cryptoutil.h>
  75   75  #include <synch.h>
  76   76  #include <thread.h>
  77   77  
  78   78  /* OPENSSL related headers */
  79   79  #include <openssl/bio.h>
  80   80  #include <openssl/bn.h>
  81   81  #include <openssl/asn1.h>
  82   82  #include <openssl/err.h>
  83   83  #include <openssl/bn.h>
  84   84  #include <openssl/x509.h>
  85   85  #include <openssl/rsa.h>
  86   86  #include <openssl/dsa.h>
  87   87  #include <openssl/x509v3.h>
  88   88  #include <openssl/objects.h>
  89   89  #include <openssl/pem.h>
  90   90  #include <openssl/pkcs12.h>
  91   91  #include <openssl/ocsp.h>
  92   92  #include <openssl/des.h>
  93   93  #include <openssl/rand.h>
  94   94  
  95   95  #define PRINT_ANY_EXTENSION (\
  96   96          KMF_X509_EXT_KEY_USAGE |\
  97   97          KMF_X509_EXT_CERT_POLICIES |\
  98   98          KMF_X509_EXT_SUBJALTNAME |\
  99   99          KMF_X509_EXT_BASIC_CONSTRAINTS |\
 100  100          KMF_X509_EXT_NAME_CONSTRAINTS |\
 101  101          KMF_X509_EXT_POLICY_CONSTRAINTS |\
 102  102          KMF_X509_EXT_EXT_KEY_USAGE |\
 103  103          KMF_X509_EXT_INHIBIT_ANY_POLICY |\
 104  104          KMF_X509_EXT_AUTH_KEY_ID |\
 105  105          KMF_X509_EXT_SUBJ_KEY_ID |\
 106  106          KMF_X509_EXT_POLICY_MAPPING)
 107  107  
 108  108  static uchar_t P[] = { 0x00, 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76,
 109  109          0xaa, 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69,
 110  110          0xcb, 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c,
 111  111          0xf7, 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82,
 112  112          0xe5, 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e,
 113  113          0xaf, 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a,
 114  114          0xac, 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24,
 115  115          0xc2, 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02,
 116  116          0x91 };
 117  117  
 118  118  static uchar_t Q[] = { 0x00, 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8,
 119  119          0xee, 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4,
 120  120          0x8e, 0xda, 0xce, 0x91, 0x5f };
 121  121  
 122  122  static uchar_t G[] = { 0x00, 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a,
 123  123          0x13, 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5,
 124  124          0x00, 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef,
 125  125          0xcb, 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c,
 126  126          0x2e, 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba,
 127  127          0xbf, 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c,
 128  128          0x9c, 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08,
 129  129          0x8c, 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88,
 130  130          0x02 };
 131  131  
 132  132  #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_OPENSSL; \
 133  133          h->lasterr.errcode = c;
 134  134  
 135  135  #define SET_SYS_ERROR(h, c) h->lasterr.kstype = -1; h->lasterr.errcode = c;
 136  136  
 137  137  /*
 138  138   * Declare some new macros for managing stacks of EVP_PKEYS, similar to
 139  139   * what wanboot did.
 140  140   */
 141  141  DECLARE_STACK_OF(EVP_PKEY)
 142  142  
 143  143  #define sk_EVP_PKEY_new_null() SKM_sk_new_null(EVP_PKEY)
 144  144  #define sk_EVP_PKEY_free(st) SKM_sk_free(EVP_PKEY, (st))
 145  145  #define sk_EVP_PKEY_num(st) SKM_sk_num(EVP_PKEY, (st))
 146  146  #define sk_EVP_PKEY_value(st, i) SKM_sk_value(EVP_PKEY, (st), (i))
 147  147  #define sk_EVP_PKEY_push(st, val) SKM_sk_push(EVP_PKEY, (st), (val))
 148  148  #define sk_EVP_PKEY_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY, (st), \
 149  149          (free_func))
 150  150  
 151  151  mutex_t init_lock = DEFAULTMUTEX;
 152  152  static int ssl_initialized = 0;
 153  153  static BIO *bio_err = NULL;
 154  154  
 155  155  static int
 156  156  test_for_file(char *, mode_t);
 157  157  static KMF_RETURN
 158  158  openssl_parse_bag(PKCS12_SAFEBAG *, char *, int,
 159  159      STACK_OF(EVP_PKEY) *, STACK_OF(X509) *);
 160  160  
 161  161  static KMF_RETURN
 162  162  local_export_pk12(KMF_HANDLE_T, KMF_CREDENTIAL *, int, KMF_X509_DER_CERT *,
 163  163      int, KMF_KEY_HANDLE *, char *);
 164  164  
 165  165  static KMF_RETURN set_pkey_attrib(EVP_PKEY *, ASN1_TYPE *, int);
 166  166  
 167  167  static KMF_RETURN
 168  168  extract_pem(KMF_HANDLE *, char *, char *, KMF_BIGINT *, char *,
 169  169      CK_UTF8CHAR *, CK_ULONG, EVP_PKEY **, KMF_DATA **, int *);
 170  170  
 171  171  static KMF_RETURN
 172  172  kmf_load_cert(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
 173  173      char *, KMF_DATA *);
 174  174  
 175  175  static KMF_RETURN
 176  176  load_certs(KMF_HANDLE *, char *, char *, KMF_BIGINT *, KMF_CERT_VALIDITY,
 177  177      char *, KMF_DATA **, uint32_t *);
 178  178  
 179  179  static KMF_RETURN
 180  180  sslBN2KMFBN(BIGNUM *, KMF_BIGINT *);
 181  181  
 182  182  static EVP_PKEY *
 183  183  ImportRawRSAKey(KMF_RAW_RSA_KEY *);
 184  184  
 185  185  static KMF_RETURN
 186  186  convertToRawKey(EVP_PKEY *, KMF_RAW_KEY_DATA *);
 187  187  
 188  188  KMF_RETURN
 189  189  OpenSSL_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 190  190  
 191  191  void
 192  192  OpenSSL_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
 193  193  
 194  194  KMF_RETURN
 195  195  OpenSSL_StoreCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
 196  196  
 197  197  KMF_RETURN
 198  198  OpenSSL_DeleteCert(KMF_HANDLE_T handle, int, KMF_ATTRIBUTE *);
 199  199  
 200  200  KMF_RETURN
 201  201  OpenSSL_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 202  202  
 203  203  KMF_RETURN
 204  204  OpenSSL_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 205  205  
 206  206  KMF_RETURN
 207  207  OpenSSL_EncodePubKeyData(KMF_HANDLE_T,  KMF_KEY_HANDLE *, KMF_DATA *);
 208  208  
 209  209  KMF_RETURN
 210  210  OpenSSL_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
 211  211          KMF_DATA *, KMF_DATA *);
 212  212  
 213  213  KMF_RETURN
 214  214  OpenSSL_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 215  215  
 216  216  KMF_RETURN
 217  217  OpenSSL_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 218  218  
 219  219  KMF_RETURN
 220  220  OpenSSL_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 221  221  
 222  222  KMF_RETURN
 223  223  OpenSSL_ListCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 224  224  
 225  225  KMF_RETURN
 226  226  OpenSSL_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 227  227  
 228  228  KMF_RETURN
 229  229  OpenSSL_CertGetPrintable(KMF_HANDLE_T, const KMF_DATA *,
 230  230          KMF_PRINTABLE_ITEM, char *);
 231  231  
 232  232  KMF_RETURN
 233  233  OpenSSL_GetErrorString(KMF_HANDLE_T, char **);
 234  234  
 235  235  KMF_RETURN
 236  236  OpenSSL_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 237  237  
 238  238  KMF_RETURN
 239  239  OpenSSL_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
 240  240          KMF_DATA *, KMF_DATA *);
 241  241  
 242  242  KMF_RETURN
 243  243  OpenSSL_CreateOCSPRequest(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 244  244  
 245  245  KMF_RETURN
 246  246  OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 247  247  
 248  248  KMF_RETURN
 249  249  OpenSSL_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 250  250  
 251  251  KMF_RETURN
 252  252  OpenSSL_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 253  253  
 254  254  KMF_RETURN
 255  255  OpenSSL_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
 256  256  
 257  257  KMF_RETURN
 258  258  OpenSSL_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
 259  259  
 260  260  KMF_RETURN
 261  261  OpenSSL_VerifyCRLFile(KMF_HANDLE_T, char *, KMF_DATA *);
 262  262  
 263  263  KMF_RETURN
 264  264  OpenSSL_CheckCRLDate(KMF_HANDLE_T, char *);
 265  265  
 266  266  static
 267  267  KMF_PLUGIN_FUNCLIST openssl_plugin_table =
 268  268  {
 269  269          1,                              /* Version */
 270  270          NULL, /* ConfigureKeystore */
 271  271          OpenSSL_FindCert,
 272  272          OpenSSL_FreeKMFCert,
 273  273          OpenSSL_StoreCert,
 274  274          NULL, /* ImportCert */
 275  275          OpenSSL_ImportCRL,
 276  276          OpenSSL_DeleteCert,
 277  277          OpenSSL_DeleteCRL,
 278  278          OpenSSL_CreateKeypair,
 279  279          OpenSSL_FindKey,
 280  280          OpenSSL_EncodePubKeyData,
 281  281          OpenSSL_SignData,
 282  282          OpenSSL_DeleteKey,
 283  283          OpenSSL_ListCRL,
 284  284          NULL,   /* FindCRL */
 285  285          OpenSSL_FindCertInCRL,
 286  286          OpenSSL_GetErrorString,
 287  287          OpenSSL_FindPrikeyByCert,
 288  288          OpenSSL_DecryptData,
 289  289          OpenSSL_ExportPK12,
 290  290          OpenSSL_CreateSymKey,
 291  291          OpenSSL_GetSymKeyValue,
 292  292          NULL,   /* SetTokenPin */
 293  293          OpenSSL_StoreKey,
 294  294          NULL    /* Finalize */
 295  295  };
 296  296  
 297  297  static mutex_t *lock_cs;
 298  298  static long *lock_count;
 299  299  
 300  300  static void
 301  301  /* ARGSUSED1 */
 302  302  locking_cb(int mode, int type, char *file, int line)
 303  303  {
 304  304          if (mode & CRYPTO_LOCK) {
 305  305                  (void) mutex_lock(&(lock_cs[type]));
 306  306                  lock_count[type]++;
 307  307          } else {
 308  308                  (void) mutex_unlock(&(lock_cs[type]));
 309  309          }
 310  310  }
 311  311  
 312  312  static unsigned long
 313  313  thread_id()
 314  314  {
 315  315          return ((unsigned long)thr_self());
 316  316  }
 317  317  
 318  318  KMF_PLUGIN_FUNCLIST *
 319  319  KMF_Plugin_Initialize()
 320  320  {
 321  321          int i;
 322  322  
 323  323          (void) mutex_lock(&init_lock);
 324  324          if (!ssl_initialized) {
 325  325                  /*
 326  326                   * Add support for extension OIDs that are not yet in the
 327  327                   * openssl default set.
 328  328                   */
 329  329                  (void) OBJ_create("2.5.29.30", "nameConstraints",
 330  330                      "X509v3 Name Constraints");
 331  331                  (void) OBJ_create("2.5.29.33", "policyMappings",
 332  332                      "X509v3 Policy Mappings");
 333  333                  (void) OBJ_create("2.5.29.36", "policyConstraints",
 334  334                      "X509v3 Policy Constraints");
 335  335                  (void) OBJ_create("2.5.29.46", "freshestCRL",
 336  336                      "X509v3 Freshest CRL");
 337  337                  (void) OBJ_create("2.5.29.54", "inhibitAnyPolicy",
 338  338                      "X509v3 Inhibit Any-Policy");
 339  339                  /*
 340  340                   * Set up for thread-safe operation.
 341  341                   */
 342  342                  lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (mutex_t));
 343  343                  if (lock_cs == NULL) {
 344  344                          (void) mutex_unlock(&init_lock);
 345  345                          return (NULL);
 346  346                  }
 347  347  
 348  348                  lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (long));
 349  349                  if (lock_count == NULL) {
 350  350                          OPENSSL_free(lock_cs);
 351  351                          (void) mutex_unlock(&init_lock);
 352  352                          return (NULL);
 353  353                  }
 354  354  
 355  355                  for (i = 0; i < CRYPTO_num_locks(); i++) {
 356  356                          lock_count[i] = 0;
 357  357                          (void) mutex_init(&lock_cs[i], USYNC_THREAD, NULL);
 358  358                  }
 359  359  
 360  360                  CRYPTO_set_id_callback((unsigned long (*)())thread_id);
 361  361                  if (CRYPTO_get_locking_callback() == NULL)
 362  362                          CRYPTO_set_locking_callback((void (*)())locking_cb);
 363  363  
 364  364                  OpenSSL_add_all_algorithms();
 365  365  
 366  366                  /* Enable error strings for reporting */
 367  367                  ERR_load_crypto_strings();
 368  368  
 369  369                  ssl_initialized = 1;
 370  370          }
 371  371          (void) mutex_unlock(&init_lock);
 372  372  
 373  373          return (&openssl_plugin_table);
 374  374  }
 375  375  /*
 376  376   * Convert an SSL DN to a KMF DN.
 377  377   */
 378  378  static KMF_RETURN
 379  379  get_x509_dn(X509_NAME *sslDN, KMF_X509_NAME *kmfDN)
 380  380  {
 381  381          KMF_DATA derdata;
 382  382          KMF_RETURN rv = KMF_OK;
 383  383          uchar_t *tmp;
 384  384  
 385  385          /* Convert to raw DER format */
 386  386          derdata.Length = i2d_X509_NAME(sslDN, NULL);
 387  387          if ((tmp = derdata.Data = (uchar_t *)OPENSSL_malloc(derdata.Length))
 388  388              == NULL) {
 389  389                  return (KMF_ERR_MEMORY);
 390  390          }
 391  391          (void) i2d_X509_NAME(sslDN, &tmp);
 392  392  
 393  393          /* Decode to KMF format */
 394  394          rv = DerDecodeName(&derdata, kmfDN);
 395  395          if (rv != KMF_OK) {
 396  396                  rv = KMF_ERR_BAD_CERT_FORMAT;
 397  397          }
 398  398          OPENSSL_free(derdata.Data);
 399  399  
 400  400          return (rv);
 401  401  }
 402  402  
 403  403  int
 404  404  isdir(char *path)
 405  405  {
 406  406          struct stat s;
 407  407  
 408  408          if (stat(path, &s) == -1)
 409  409                  return (0);
 410  410  
 411  411          return ((s.st_mode & S_IFMT) == S_IFDIR);
 412  412  }
 413  413  
 414  414  static KMF_RETURN
 415  415  ssl_cert2KMFDATA(KMF_HANDLE *kmfh, X509 *x509cert, KMF_DATA *cert)
 416  416  {
 417  417          KMF_RETURN rv = KMF_OK;
 418  418          unsigned char *buf = NULL, *p;
 419  419          int len;
 420  420  
 421  421          /*
 422  422           * Convert the X509 internal struct to DER encoded data
 423  423           */
 424  424          if ((len = i2d_X509(x509cert, NULL)) < 0) {
 425  425                  SET_ERROR(kmfh, ERR_get_error());
 426  426                  rv = KMF_ERR_BAD_CERT_FORMAT;
 427  427                  goto cleanup;
 428  428          }
 429  429          if ((buf = malloc(len)) == NULL) {
 430  430                  SET_SYS_ERROR(kmfh, errno);
 431  431                  rv = KMF_ERR_MEMORY;
 432  432                  goto cleanup;
 433  433          }
 434  434  
 435  435          /*
 436  436           * i2d_X509 will increment the buf pointer so that we need to
 437  437           * save it.
 438  438           */
 439  439          p = buf;
 440  440          if ((len = i2d_X509(x509cert, &p)) < 0) {
 441  441                  SET_ERROR(kmfh, ERR_get_error());
 442  442                  free(buf);
 443  443                  rv = KMF_ERR_BAD_CERT_FORMAT;
 444  444                  goto cleanup;
 445  445          }
 446  446  
 447  447          /* caller's responsibility to free it */
 448  448          cert->Data = buf;
 449  449          cert->Length = len;
 450  450  
 451  451  cleanup:
 452  452          if (rv != KMF_OK) {
 453  453                  if (buf)
 454  454                          free(buf);
 455  455                  cert->Data = NULL;
 456  456                  cert->Length = 0;
 457  457          }
 458  458  
 459  459          return (rv);
 460  460  }
 461  461  
 462  462  
 463  463  static KMF_RETURN
 464  464  check_cert(X509 *xcert, char *issuer, char *subject, KMF_BIGINT *serial,
 465  465      boolean_t *match)
 466  466  {
 467  467          KMF_RETURN rv = KMF_OK;
 468  468          boolean_t findIssuer = FALSE;
 469  469          boolean_t findSubject = FALSE;
 470  470          boolean_t findSerial = FALSE;
 471  471          KMF_X509_NAME issuerDN, subjectDN;
 472  472          KMF_X509_NAME certIssuerDN, certSubjectDN;
 473  473  
 474  474          *match = FALSE;
 475  475          if (xcert == NULL) {
 476  476                  return (KMF_ERR_BAD_PARAMETER);
 477  477          }
 478  478  
 479  479          (void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
 480  480          (void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
 481  481          (void) memset(&certIssuerDN, 0, sizeof (KMF_X509_NAME));
 482  482          (void) memset(&certSubjectDN, 0, sizeof (KMF_X509_NAME));
 483  483  
 484  484          if (issuer != NULL && strlen(issuer)) {
 485  485                  rv = kmf_dn_parser(issuer, &issuerDN);
 486  486                  if (rv != KMF_OK)
 487  487                          return (KMF_ERR_BAD_PARAMETER);
 488  488  
 489  489                  rv = get_x509_dn(xcert->cert_info->issuer, &certIssuerDN);
 490  490                  if (rv != KMF_OK) {
 491  491                          kmf_free_dn(&issuerDN);
 492  492                          return (KMF_ERR_BAD_PARAMETER);
 493  493                  }
 494  494  
 495  495                  findIssuer = TRUE;
 496  496          }
 497  497          if (subject != NULL && strlen(subject)) {
 498  498                  rv = kmf_dn_parser(subject, &subjectDN);
 499  499                  if (rv != KMF_OK) {
 500  500                          rv = KMF_ERR_BAD_PARAMETER;
 501  501                          goto cleanup;
 502  502                  }
 503  503  
 504  504                  rv = get_x509_dn(xcert->cert_info->subject, &certSubjectDN);
 505  505                  if (rv != KMF_OK) {
 506  506                          rv = KMF_ERR_BAD_PARAMETER;
 507  507                          goto cleanup;
 508  508                  }
 509  509                  findSubject = TRUE;
 510  510          }
 511  511          if (serial != NULL && serial->val != NULL)
 512  512                  findSerial = TRUE;
 513  513  
 514  514          if (findSerial) {
 515  515                  BIGNUM *bn;
 516  516  
 517  517                  /* Comparing BIGNUMs is a pain! */
 518  518                  bn = ASN1_INTEGER_to_BN(xcert->cert_info->serialNumber, NULL);
 519  519                  if (bn != NULL) {
 520  520                          int bnlen = BN_num_bytes(bn);
 521  521  
 522  522                          if (bnlen == serial->len) {
 523  523                                  uchar_t *a = malloc(bnlen);
 524  524                                  if (a == NULL) {
 525  525                                          rv = KMF_ERR_MEMORY;
 526  526                                          BN_free(bn);
 527  527                                          goto cleanup;
 528  528                                  }
 529  529                                  bnlen = BN_bn2bin(bn, a);
 530  530                                  *match = (memcmp(a, serial->val, serial->len) ==
 531  531                                      0);
 532  532                                  rv = KMF_OK;
 533  533                                  free(a);
 534  534                          }
 535  535                          BN_free(bn);
 536  536                          if (!(*match))
 537  537                                  goto cleanup;
 538  538                  } else {
 539  539                          rv = KMF_OK;
 540  540                          goto cleanup;
 541  541                  }
 542  542          }
 543  543          if (findIssuer) {
 544  544                  *match = (kmf_compare_rdns(&issuerDN, &certIssuerDN) == 0);
 545  545                  if ((*match) == B_FALSE) {
 546  546                          /* stop checking and bail */
 547  547                          rv = KMF_OK;
 548  548                          goto cleanup;
 549  549                  }
 550  550          }
 551  551          if (findSubject) {
 552  552                  *match = (kmf_compare_rdns(&subjectDN, &certSubjectDN) == 0);
 553  553                  if ((*match) == B_FALSE) {
 554  554                          /* stop checking and bail */
 555  555                          rv = KMF_OK;
 556  556                          goto cleanup;
 557  557                  }
 558  558          }
 559  559  
 560  560          *match = TRUE;
 561  561  cleanup:
 562  562          if (findIssuer) {
 563  563                  kmf_free_dn(&issuerDN);
 564  564                  kmf_free_dn(&certIssuerDN);
 565  565          }
 566  566          if (findSubject) {
 567  567                  kmf_free_dn(&subjectDN);
 568  568                  kmf_free_dn(&certSubjectDN);
 569  569          }
 570  570  
 571  571          return (rv);
 572  572  }
 573  573  
 574  574  
 575  575  /*
 576  576   * This function loads a certificate file into an X509 data structure, and
 577  577   * checks if its issuer, subject or the serial number matches with those
 578  578   * values.  If it matches, then return the X509 data structure.
 579  579   */
 580  580  static KMF_RETURN
 581  581  load_X509cert(KMF_HANDLE *kmfh,
 582  582      char *issuer, char *subject, KMF_BIGINT *serial,
 583  583      char *pathname, X509 **outcert)
 584  584  {
 585  585          KMF_RETURN rv = KMF_OK;
 586  586          X509 *xcert = NULL;
 587  587          BIO *bcert = NULL;
 588  588          boolean_t  match = FALSE;
 589  589          KMF_ENCODE_FORMAT format;
 590  590  
 591  591          /*
 592  592           * auto-detect the file format, regardless of what
 593  593           * the 'format' parameters in the params say.
 594  594           */
 595  595          rv = kmf_get_file_format(pathname, &format);
 596  596          if (rv != KMF_OK) {
 597  597                  if (rv == KMF_ERR_OPEN_FILE)
 598  598                          rv = KMF_ERR_CERT_NOT_FOUND;
 599  599                  return (rv);
 600  600          }
 601  601  
 602  602          /* Not ASN1(DER) format */
 603  603          if ((bcert = BIO_new_file(pathname, "rb")) == NULL) {
 604  604                  SET_ERROR(kmfh, ERR_get_error());
 605  605                  rv = KMF_ERR_OPEN_FILE;
 606  606                  goto cleanup;
 607  607          }
 608  608  
 609  609          if (format == KMF_FORMAT_PEM)
 610  610                  xcert = PEM_read_bio_X509_AUX(bcert, NULL, NULL, NULL);
 611  611          else if (format == KMF_FORMAT_ASN1)
 612  612                  xcert = d2i_X509_bio(bcert, NULL);
 613  613          else if (format == KMF_FORMAT_PKCS12) {
 614  614                  PKCS12 *p12 = d2i_PKCS12_bio(bcert, NULL);
 615  615                  if (p12 != NULL) {
 616  616                          (void) PKCS12_parse(p12, NULL, NULL, &xcert, NULL);
 617  617                          PKCS12_free(p12);
 618  618                          p12 = NULL;
 619  619                  } else {
 620  620                          SET_ERROR(kmfh, ERR_get_error());
 621  621                          rv = KMF_ERR_BAD_CERT_FORMAT;
 622  622                  }
 623  623          } else {
 624  624                  rv = KMF_ERR_BAD_PARAMETER;
 625  625                  goto cleanup;
 626  626          }
 627  627  
 628  628          if (xcert == NULL) {
 629  629                  SET_ERROR(kmfh, ERR_get_error());
 630  630                  rv = KMF_ERR_BAD_CERT_FORMAT;
 631  631                  goto cleanup;
 632  632          }
 633  633  
 634  634          if (check_cert(xcert, issuer, subject, serial, &match) != KMF_OK ||
 635  635              match == FALSE) {
 636  636                  rv = KMF_ERR_CERT_NOT_FOUND;
 637  637                  goto cleanup;
 638  638          }
 639  639  
 640  640          if (outcert != NULL) {
 641  641                  *outcert = xcert;
 642  642          }
 643  643  
 644  644  cleanup:
 645  645          if (bcert != NULL) (void) BIO_free(bcert);
 646  646          if (rv != KMF_OK && xcert != NULL)
 647  647                  X509_free(xcert);
 648  648  
 649  649          return (rv);
 650  650  }
 651  651  
 652  652  static int
 653  653  datacmp(const void *a, const void *b)
 654  654  {
 655  655          KMF_DATA *adata = (KMF_DATA *)a;
 656  656          KMF_DATA *bdata = (KMF_DATA *)b;
 657  657          if (adata->Length > bdata->Length)
 658  658                  return (-1);
 659  659          if (adata->Length < bdata->Length)
 660  660                  return (1);
 661  661          return (0);
 662  662  }
 663  663  
 664  664  static KMF_RETURN
 665  665  load_certs(KMF_HANDLE *kmfh, char *issuer, char *subject, KMF_BIGINT *serial,
 666  666      KMF_CERT_VALIDITY validity, char *pathname,
 667  667      KMF_DATA **certlist, uint32_t *numcerts)
 668  668  {
 669  669          KMF_RETURN rv = KMF_OK;
 670  670          int i;
 671  671          KMF_DATA *certs = NULL;
 672  672          int nc = 0;
 673  673          int hits = 0;
 674  674          KMF_ENCODE_FORMAT format;
 675  675  
 676  676          rv = kmf_get_file_format(pathname, &format);
 677  677          if (rv != KMF_OK) {
 678  678                  if (rv == KMF_ERR_OPEN_FILE)
 679  679                          rv = KMF_ERR_CERT_NOT_FOUND;
 680  680                  return (rv);
 681  681          }
 682  682          if (format == KMF_FORMAT_ASN1) {
 683  683                  /* load a single certificate */
 684  684                  certs = (KMF_DATA *)malloc(sizeof (KMF_DATA));
 685  685                  if (certs == NULL)
 686  686                          return (KMF_ERR_MEMORY);
 687  687                  certs->Data = NULL;
 688  688                  certs->Length = 0;
 689  689                  rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
 690  690                      pathname, certs);
 691  691                  if (rv == KMF_OK) {
 692  692                          *certlist = certs;
 693  693                          *numcerts = 1;
 694  694                  } else {
 695  695                          kmf_free_data(certs);
 696  696                          free(certs);
 697  697                          certs = NULL;
 698  698                  }
 699  699                  return (rv);
 700  700          } else if (format == KMF_FORMAT_PKCS12) {
 701  701                  /* We need a credential to access a PKCS#12 file */
 702  702                  rv = KMF_ERR_BAD_CERT_FORMAT;
 703  703          } else if (format == KMF_FORMAT_PEM ||
 704  704              format != KMF_FORMAT_PEM_KEYPAIR) {
 705  705  
 706  706                  /* This function only works on PEM files */
 707  707                  rv = extract_pem(kmfh, issuer, subject, serial, pathname,
 708  708                      (uchar_t *)NULL, 0, NULL, &certs, &nc);
 709  709          } else {
 710  710                  return (KMF_ERR_ENCODING);
 711  711          }
 712  712  
 713  713          if (rv != KMF_OK)
 714  714                  return (rv);
 715  715  
 716  716          for (i = 0; i < nc; i++) {
 717  717                  if (validity == KMF_NONEXPIRED_CERTS) {
 718  718                          rv = kmf_check_cert_date(kmfh, &certs[i]);
 719  719                  } else if (validity == KMF_EXPIRED_CERTS) {
 720  720                          rv = kmf_check_cert_date(kmfh, &certs[i]);
 721  721                          if (rv == KMF_OK)
 722  722                                  rv = KMF_ERR_CERT_NOT_FOUND;
 723  723                          if (rv == KMF_ERR_VALIDITY_PERIOD)
 724  724                                  rv = KMF_OK;
 725  725                  }
 726  726                  if (rv != KMF_OK) {
 727  727                          /* Remove this cert from the list by clearing it. */
 728  728                          kmf_free_data(&certs[i]);
 729  729                  } else {
 730  730                          hits++; /* count valid certs found */
 731  731                  }
 732  732                  rv = KMF_OK;
 733  733          }
 734  734          if (rv == KMF_OK && hits > 0) {
 735  735                  /*
 736  736                   * Sort the list of certs by length to put the cleared ones
 737  737                   * at the end so they don't get accessed by the caller.
 738  738                   */
 739  739                  qsort((void *)certs, nc, sizeof (KMF_DATA), datacmp);
 740  740                  *certlist = certs;
 741  741  
 742  742                  /* since we sorted the list, just return the number of hits */
 743  743                  *numcerts = hits;
 744  744          } else {
 745  745                  if (rv == KMF_OK && hits == 0)
 746  746                          rv = KMF_ERR_CERT_NOT_FOUND;
 747  747                  if (certs != NULL) {
 748  748                          free(certs);
 749  749                          certs = NULL;
 750  750                  }
 751  751          }
 752  752          return (rv);
 753  753  }
 754  754  
 755  755  static KMF_RETURN
 756  756  kmf_load_cert(KMF_HANDLE *kmfh,
 757  757      char *issuer, char *subject, KMF_BIGINT *serial,
 758  758      KMF_CERT_VALIDITY validity,
 759  759      char *pathname,
 760  760      KMF_DATA *cert)
 761  761  {
 762  762          KMF_RETURN rv = KMF_OK;
 763  763          X509 *x509cert = NULL;
 764  764  
 765  765          rv = load_X509cert(kmfh, issuer, subject, serial, pathname, &x509cert);
 766  766          if (rv == KMF_OK && x509cert != NULL && cert != NULL) {
 767  767                  rv = ssl_cert2KMFDATA(kmfh, x509cert, cert);
 768  768                  if (rv != KMF_OK) {
 769  769                          goto cleanup;
 770  770                  }
 771  771                  if (validity == KMF_NONEXPIRED_CERTS) {
 772  772                          rv = kmf_check_cert_date(kmfh, cert);
 773  773                  } else if (validity == KMF_EXPIRED_CERTS) {
 774  774                          rv = kmf_check_cert_date(kmfh, cert);
 775  775                          if (rv == KMF_OK)  {
 776  776                                  /*
 777  777                                   * This is a valid cert so skip it.
 778  778                                   */
 779  779                                  rv = KMF_ERR_CERT_NOT_FOUND;
 780  780                          }
 781  781                          if (rv == KMF_ERR_VALIDITY_PERIOD) {
 782  782                                  /*
 783  783                                   * We want to return success when we
 784  784                                   * find an invalid cert.
 785  785                                   */
 786  786                                  rv = KMF_OK;
 787  787                                  goto cleanup;
 788  788                          }
 789  789                  }
 790  790          }
 791  791  cleanup:
 792  792          if (x509cert != NULL)
 793  793                  X509_free(x509cert);
 794  794  
 795  795          return (rv);
 796  796  }
 797  797  
 798  798  static KMF_RETURN
 799  799  readAltFormatPrivateKey(KMF_DATA *filedata, EVP_PKEY **pkey)
 800  800  {
 801  801          KMF_RETURN ret = KMF_OK;
 802  802          KMF_RAW_RSA_KEY rsa;
 803  803          BerElement *asn1 = NULL;
 804  804          BerValue filebuf;
 805  805          BerValue OID = { NULL, 0 };
 806  806          BerValue *Mod = NULL, *PubExp = NULL;
 807  807          BerValue *PriExp = NULL, *Prime1 = NULL, *Prime2 = NULL;
 808  808          BerValue *Coef = NULL;
 809  809          BIGNUM *D = NULL, *P = NULL, *Q = NULL, *COEF = NULL;
 810  810          BIGNUM *Exp1 = NULL, *Exp2 = NULL, *pminus1 = NULL;
 811  811          BIGNUM *qminus1 = NULL;
 812  812          BN_CTX *ctx = NULL;
 813  813  
 814  814          *pkey = NULL;
 815  815  
 816  816          filebuf.bv_val = (char *)filedata->Data;
 817  817          filebuf.bv_len = filedata->Length;
 818  818  
 819  819          asn1 = kmfder_init(&filebuf);
 820  820          if (asn1 == NULL) {
 821  821                  ret = KMF_ERR_MEMORY;
 822  822                  goto out;
 823  823          }
 824  824  
 825  825          if (kmfber_scanf(asn1, "{{Dn{IIIIII}}}",
 826  826              &OID, &Mod, &PubExp, &PriExp, &Prime1,
 827  827              &Prime2, &Coef) == -1)  {
 828  828                  ret = KMF_ERR_ENCODING;
 829  829                  goto out;
 830  830          }
 831  831  
 832  832          /*
 833  833           * We have to derive the 2 Exponents using Bignumber math.
 834  834           * Exp1 = PriExp mod (Prime1 - 1)
 835  835           * Exp2 = PriExp mod (Prime2 - 1)
 836  836           */
 837  837  
 838  838          /* D = PrivateExponent */
 839  839          D = BN_bin2bn((const uchar_t *)PriExp->bv_val, PriExp->bv_len, D);
 840  840          if (D == NULL) {
 841  841                  ret = KMF_ERR_MEMORY;
 842  842                  goto out;
 843  843          }
 844  844  
 845  845          /* P = Prime1 (first prime factor of Modulus) */
 846  846          P = BN_bin2bn((const uchar_t *)Prime1->bv_val, Prime1->bv_len, P);
 847  847          if (D == NULL) {
 848  848                  ret = KMF_ERR_MEMORY;
 849  849                  goto out;
 850  850          }
 851  851  
 852  852          /* Q = Prime2 (second prime factor of Modulus) */
 853  853          Q = BN_bin2bn((const uchar_t *)Prime2->bv_val, Prime2->bv_len, Q);
 854  854  
 855  855          if ((ctx = BN_CTX_new()) == NULL) {
 856  856                  ret = KMF_ERR_MEMORY;
 857  857                  goto out;
 858  858          }
 859  859  
 860  860          /* Compute (P - 1) */
 861  861          pminus1 = BN_new();
 862  862          (void) BN_sub(pminus1, P, BN_value_one());
 863  863  
 864  864          /* Exponent1 = D mod (P - 1) */
 865  865          Exp1 = BN_new();
 866  866          (void) BN_mod(Exp1, D, pminus1, ctx);
 867  867  
 868  868          /* Compute (Q - 1) */
 869  869          qminus1 = BN_new();
 870  870          (void) BN_sub(qminus1, Q, BN_value_one());
 871  871  
 872  872          /* Exponent2 = D mod (Q - 1) */
 873  873          Exp2 = BN_new();
 874  874          (void) BN_mod(Exp2, D, qminus1, ctx);
 875  875  
 876  876          /* Coef = (Inverse Q) mod P */
 877  877          COEF = BN_new();
 878  878          (void) BN_mod_inverse(COEF, Q, P, ctx);
 879  879  
 880  880          /* Convert back to KMF format */
 881  881          (void) memset(&rsa, 0, sizeof (rsa));
 882  882  
 883  883          if ((ret = sslBN2KMFBN(Exp1, &rsa.exp1)) != KMF_OK)
 884  884                  goto out;
 885  885          if ((ret = sslBN2KMFBN(Exp2, &rsa.exp2)) != KMF_OK)
 886  886                  goto out;
 887  887          if ((ret = sslBN2KMFBN(COEF, &rsa.coef)) != KMF_OK)
 888  888                  goto out;
 889  889  
 890  890          rsa.mod.val = (uchar_t *)Mod->bv_val;
 891  891          rsa.mod.len = Mod->bv_len;
 892  892  
 893  893          rsa.pubexp.val = (uchar_t *)PubExp->bv_val;
 894  894          rsa.pubexp.len = PubExp->bv_len;
 895  895  
 896  896          rsa.priexp.val = (uchar_t *)PriExp->bv_val;
 897  897          rsa.priexp.len = PriExp->bv_len;
 898  898  
 899  899          rsa.prime1.val = (uchar_t *)Prime1->bv_val;
 900  900          rsa.prime1.len = Prime1->bv_len;
 901  901  
 902  902          rsa.prime2.val = (uchar_t *)Prime2->bv_val;
 903  903          rsa.prime2.len = Prime2->bv_len;
 904  904  
 905  905          *pkey = ImportRawRSAKey(&rsa);
 906  906  out:
 907  907          if (asn1 != NULL)
 908  908                  kmfber_free(asn1, 1);
 909  909  
 910  910          if (OID.bv_val) {
 911  911                  free(OID.bv_val);
 912  912          }
 913  913          if (PriExp)
 914  914                  free(PriExp);
 915  915  
 916  916          if (Mod)
 917  917                  free(Mod);
 918  918  
 919  919          if (PubExp)
 920  920                  free(PubExp);
 921  921  
 922  922          if (Coef) {
 923  923                  (void) memset(Coef->bv_val, 0, Coef->bv_len);
 924  924                  free(Coef->bv_val);
 925  925                  free(Coef);
 926  926          }
 927  927          if (Prime1)
 928  928                  free(Prime1);
 929  929          if (Prime2)
 930  930                  free(Prime2);
 931  931  
 932  932          if (ctx != NULL)
 933  933                  BN_CTX_free(ctx);
 934  934  
 935  935          if (D)
 936  936                  BN_clear_free(D);
 937  937          if (P)
 938  938                  BN_clear_free(P);
 939  939          if (Q)
 940  940                  BN_clear_free(Q);
 941  941          if (pminus1)
 942  942                  BN_clear_free(pminus1);
 943  943          if (qminus1)
 944  944                  BN_clear_free(qminus1);
 945  945          if (Exp1)
 946  946                  BN_clear_free(Exp1);
 947  947          if (Exp2)
 948  948                  BN_clear_free(Exp2);
 949  949  
 950  950          return (ret);
 951  951  
 952  952  }
 953  953  
 954  954  static EVP_PKEY *
 955  955  openssl_load_key(KMF_HANDLE_T handle, const char *file)
 956  956  {
 957  957          BIO *keyfile = NULL;
 958  958          EVP_PKEY *pkey = NULL;
 959  959          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
 960  960          KMF_ENCODE_FORMAT format;
 961  961          KMF_RETURN rv;
 962  962          KMF_DATA filedata;
 963  963  
 964  964          if (file == NULL) {
 965  965                  return (NULL);
 966  966          }
 967  967  
 968  968          if (kmf_get_file_format((char *)file, &format) != KMF_OK)
 969  969                  return (NULL);
 970  970  
 971  971          keyfile = BIO_new_file(file, "rb");
 972  972          if (keyfile == NULL) {
 973  973                  goto end;
 974  974          }
 975  975  
 976  976          if (format == KMF_FORMAT_ASN1) {
 977  977                  pkey = d2i_PrivateKey_bio(keyfile, NULL);
 978  978                  if (pkey == NULL) {
 979  979  
 980  980                          (void) BIO_free(keyfile);
 981  981                          keyfile = NULL;
 982  982                          /* Try odd ASN.1 variations */
 983  983                          rv = kmf_read_input_file(kmfh, (char *)file,
 984  984                              &filedata);
 985  985                          if (rv == KMF_OK) {
 986  986                                  (void) readAltFormatPrivateKey(&filedata,
 987  987                                      &pkey);
 988  988                                  kmf_free_data(&filedata);
 989  989                          }
 990  990                  }
 991  991          } else if (format == KMF_FORMAT_PEM ||
 992  992              format == KMF_FORMAT_PEM_KEYPAIR) {
 993  993                  pkey = PEM_read_bio_PrivateKey(keyfile, NULL, NULL, NULL);
 994  994                  if (pkey == NULL) {
 995  995                          KMF_DATA derdata;
 996  996                          /*
 997  997                           * Check if this is the alt. format
 998  998                           * RSA private key file.
 999  999                           */
1000 1000                          rv = kmf_read_input_file(kmfh, (char *)file,
1001 1001                              &filedata);
1002 1002                          if (rv == KMF_OK) {
1003 1003                                  uchar_t *d = NULL;
1004 1004                                  int len;
1005 1005                                  rv = kmf_pem_to_der(filedata.Data,
1006 1006                                      filedata.Length, &d, &len);
1007 1007                                  if (rv == KMF_OK && d != NULL) {
1008 1008                                          derdata.Data = d;
1009 1009                                          derdata.Length = (size_t)len;
1010 1010                                          (void) readAltFormatPrivateKey(
1011 1011                                              &derdata, &pkey);
1012 1012                                          free(d);
1013 1013                                  }
1014 1014                                  kmf_free_data(&filedata);
1015 1015                          }
1016 1016                  }
1017 1017          }
1018 1018  
1019 1019  end:
1020 1020          if (pkey == NULL)
1021 1021                  SET_ERROR(kmfh, ERR_get_error());
1022 1022  
1023 1023          if (keyfile != NULL)
1024 1024                  (void) BIO_free(keyfile);
1025 1025  
1026 1026          return (pkey);
1027 1027  }
1028 1028  
1029 1029  KMF_RETURN
1030 1030  OpenSSL_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1031 1031  {
1032 1032          KMF_RETURN rv = KMF_OK;
1033 1033          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1034 1034          int i, n;
1035 1035          uint32_t maxcerts = 0;
1036 1036          uint32_t *num_certs;
1037 1037          KMF_X509_DER_CERT *kmf_cert = NULL;
1038 1038          char *dirpath = NULL;
1039 1039          char *filename = NULL;
1040 1040          char *fullpath = NULL;
1041 1041          char *issuer = NULL;
1042 1042          char *subject = NULL;
1043 1043          KMF_BIGINT *serial = NULL;
1044 1044          KMF_CERT_VALIDITY validity;
1045 1045  
1046 1046          num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
1047 1047          if (num_certs == NULL)
1048 1048                  return (KMF_ERR_BAD_PARAMETER);
1049 1049  
1050 1050          /* num_certs should reference the size of kmf_cert */
1051 1051          maxcerts = *num_certs;
1052 1052          if (maxcerts == 0)
1053 1053                  maxcerts = 0xFFFFFFFF;
1054 1054          *num_certs = 0;
1055 1055  
1056 1056          /* Get the optional returned certificate list  */
1057 1057          kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
1058 1058              numattr);
1059 1059  
1060 1060          /*
1061 1061           * The dirpath attribute and the filename attribute can not be NULL
1062 1062           * at the same time.
1063 1063           */
1064 1064          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1065 1065          filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1066 1066              numattr);
1067 1067  
1068 1068          fullpath = get_fullpath(dirpath, filename);
1069 1069          if (fullpath == NULL)
1070 1070                  return (KMF_ERR_BAD_PARAMETER);
1071 1071  
1072 1072          /* Get optional search criteria attributes */
1073 1073          issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1074 1074          subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1075 1075          serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1076 1076          rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1077 1077              &validity, NULL);
1078 1078          if (rv != KMF_OK) {
1079 1079                  validity = KMF_ALL_CERTS;
1080 1080                  rv = KMF_OK;
1081 1081          }
1082 1082  
1083 1083          if (isdir(fullpath)) {
1084 1084                  DIR *dirp;
1085 1085                  struct dirent *dp;
1086 1086  
1087 1087                  n = 0;
1088 1088                  /* open all files in the directory and attempt to read them */
1089 1089                  if ((dirp = opendir(fullpath)) == NULL) {
1090 1090                          return (KMF_ERR_BAD_PARAMETER);
1091 1091                  }
1092 1092                  while ((dp = readdir(dirp)) != NULL) {
1093 1093                          char *fname;
1094 1094                          KMF_DATA *certlist = NULL;
1095 1095                          uint32_t loaded_certs = 0;
1096 1096  
1097 1097                          if (strcmp(dp->d_name, ".") == 0 ||
1098 1098                              strcmp(dp->d_name, "..") == 0)
1099 1099                                  continue;
1100 1100  
1101 1101                          fname = get_fullpath(fullpath, (char *)&dp->d_name);
1102 1102  
1103 1103                          rv = load_certs(kmfh, issuer, subject, serial,
1104 1104                              validity, fname, &certlist, &loaded_certs);
1105 1105  
1106 1106                          if (rv != KMF_OK) {
1107 1107                                  free(fname);
1108 1108                                  if (certlist != NULL) {
1109 1109                                          for (i = 0; i < loaded_certs; i++)
1110 1110                                                  kmf_free_data(&certlist[i]);
1111 1111                                          free(certlist);
1112 1112                                  }
1113 1113                                  continue;
1114 1114                          }
1115 1115  
1116 1116                          /* If load succeeds, add certdata to the list */
1117 1117                          if (kmf_cert != NULL) {
1118 1118                                  for (i = 0; i < loaded_certs &&
1119 1119                                      n < maxcerts; i++) {
1120 1120                                          kmf_cert[n].certificate.Data =
1121 1121                                              certlist[i].Data;
1122 1122                                          kmf_cert[n].certificate.Length =
1123 1123                                              certlist[i].Length;
1124 1124  
1125 1125                                          kmf_cert[n].kmf_private.keystore_type =
1126 1126                                              KMF_KEYSTORE_OPENSSL;
1127 1127                                          kmf_cert[n].kmf_private.flags =
1128 1128                                              KMF_FLAG_CERT_VALID;
1129 1129                                          kmf_cert[n].kmf_private.label =
1130 1130                                              strdup(fname);
1131 1131                                          n++;
1132 1132                                  }
1133 1133                                  /*
1134 1134                                   * If maxcerts < loaded_certs, clean up the
1135 1135                                   * certs that were not used.
1136 1136                                   */
1137 1137                                  for (; i < loaded_certs; i++)
1138 1138                                          kmf_free_data(&certlist[i]);
1139 1139                          } else {
1140 1140                                  for (i = 0; i < loaded_certs; i++)
1141 1141                                          kmf_free_data(&certlist[i]);
1142 1142                                  n += loaded_certs;
1143 1143                          }
1144 1144                          free(certlist);
1145 1145                          free(fname);
1146 1146                  }
1147 1147                  (*num_certs) = n;
1148 1148                  if (*num_certs == 0)
1149 1149                          rv = KMF_ERR_CERT_NOT_FOUND;
1150 1150                  if (*num_certs > 0)
1151 1151                          rv = KMF_OK;
1152 1152  exit:
1153 1153                  (void) closedir(dirp);
1154 1154          } else {
1155 1155                  KMF_DATA *certlist = NULL;
1156 1156                  uint32_t loaded_certs = 0;
1157 1157  
1158 1158                  rv = load_certs(kmfh, issuer, subject, serial, validity,
1159 1159                      fullpath, &certlist, &loaded_certs);
1160 1160                  if (rv != KMF_OK) {
1161 1161                          free(fullpath);
1162 1162                          return (rv);
1163 1163                  }
1164 1164  
1165 1165                  n = 0;
1166 1166                  if (kmf_cert != NULL && certlist != NULL) {
1167 1167                          for (i = 0; i < loaded_certs && i < maxcerts; i++) {
1168 1168                                  kmf_cert[n].certificate.Data =
1169 1169                                      certlist[i].Data;
1170 1170                                  kmf_cert[n].certificate.Length =
1171 1171                                      certlist[i].Length;
1172 1172                                  kmf_cert[n].kmf_private.keystore_type =
1173 1173                                      KMF_KEYSTORE_OPENSSL;
1174 1174                                  kmf_cert[n].kmf_private.flags =
1175 1175                                      KMF_FLAG_CERT_VALID;
1176 1176                                  kmf_cert[n].kmf_private.label =
1177 1177                                      strdup(fullpath);
1178 1178                                  n++;
1179 1179                          }
1180 1180                          /* If maxcerts < loaded_certs, clean up */
1181 1181                          for (; i < loaded_certs; i++)
1182 1182                                  kmf_free_data(&certlist[i]);
1183 1183                  } else if (certlist != NULL) {
1184 1184                          for (i = 0; i < loaded_certs; i++)
1185 1185                                  kmf_free_data(&certlist[i]);
1186 1186                          n = loaded_certs;
1187 1187                  }
1188 1188                  if (certlist != NULL)
1189 1189                          free(certlist);
1190 1190                  *num_certs = n;
1191 1191          }
1192 1192  
1193 1193          free(fullpath);
1194 1194  
1195 1195          return (rv);
1196 1196  }
1197 1197  
1198 1198  void
1199 1199  /*ARGSUSED*/
1200 1200  OpenSSL_FreeKMFCert(KMF_HANDLE_T handle,
1201 1201          KMF_X509_DER_CERT *kmf_cert)
1202 1202  {
1203 1203          if (kmf_cert != NULL) {
1204 1204                  if (kmf_cert->certificate.Data != NULL) {
1205 1205                          kmf_free_data(&kmf_cert->certificate);
1206 1206                  }
1207 1207                  if (kmf_cert->kmf_private.label)
1208 1208                          free(kmf_cert->kmf_private.label);
1209 1209          }
1210 1210  }
1211 1211  
1212 1212  /*ARGSUSED*/
1213 1213  KMF_RETURN
1214 1214  OpenSSL_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1215 1215  {
1216 1216          KMF_RETURN ret = KMF_OK;
1217 1217          KMF_DATA *cert = NULL;
1218 1218          char *outfilename = NULL;
1219 1219          char *dirpath = NULL;
1220 1220          char *fullpath = NULL;
1221 1221          KMF_ENCODE_FORMAT format;
1222 1222  
1223 1223          /* Get the cert data */
1224 1224          cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
1225 1225          if (cert == NULL || cert->Data == NULL)
1226 1226                  return (KMF_ERR_BAD_PARAMETER);
1227 1227  
1228 1228          /* Check the output filename and directory attributes. */
1229 1229          outfilename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1230 1230              numattr);
1231 1231          if (outfilename == NULL)
1232 1232                  return (KMF_ERR_BAD_PARAMETER);
1233 1233  
1234 1234          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1235 1235          fullpath = get_fullpath(dirpath, outfilename);
1236 1236          if (fullpath == NULL)
1237 1237                  return (KMF_ERR_BAD_CERTFILE);
1238 1238  
1239 1239          /* Check the optional format attribute */
1240 1240          ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1241 1241              &format, NULL);
1242 1242          if (ret != KMF_OK) {
1243 1243                  /* If there is no format attribute, then default to PEM */
1244 1244                  format = KMF_FORMAT_PEM;
1245 1245                  ret = KMF_OK;
1246 1246          } else if (format != KMF_FORMAT_ASN1 && format != KMF_FORMAT_PEM) {
1247 1247                  ret = KMF_ERR_BAD_CERT_FORMAT;
1248 1248                  goto out;
1249 1249          }
1250 1250  
1251 1251          /* Store the certificate in the file with the specified format */
1252 1252          ret = kmf_create_cert_file(cert, format, fullpath);
1253 1253  
1254 1254  out:
1255 1255          if (fullpath != NULL)
1256 1256                  free(fullpath);
1257 1257  
1258 1258          return (ret);
1259 1259  }
1260 1260  
1261 1261  
1262 1262  KMF_RETURN
1263 1263  OpenSSL_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
1264 1264  {
1265 1265          KMF_RETURN rv;
1266 1266          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1267 1267          KMF_DATA certdata = { 0, NULL };
1268 1268          char *dirpath = NULL;
1269 1269          char *filename = NULL;
1270 1270          char *fullpath = NULL;
1271 1271          char *issuer = NULL;
1272 1272          char *subject = NULL;
1273 1273          KMF_BIGINT *serial = NULL;
1274 1274          KMF_CERT_VALIDITY validity;
1275 1275  
1276 1276          /*
1277 1277           * Get the DIRPATH and CERT_FILENAME attributes.  They can not be
1278 1278           * NULL at the same time.
1279 1279           */
1280 1280          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1281 1281          filename = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist,
1282 1282              numattr);
1283 1283          fullpath = get_fullpath(dirpath, filename);
1284 1284          if (fullpath == NULL)
1285 1285                  return (KMF_ERR_BAD_PARAMETER);
1286 1286  
1287 1287          /* Get optional search criteria attributes */
1288 1288          issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
1289 1289          subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
1290 1290          serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
1291 1291          rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
1292 1292              &validity, NULL);
1293 1293          if (rv != KMF_OK) {
1294 1294                  validity = KMF_ALL_CERTS;
1295 1295                  rv = KMF_OK;
1296 1296          }
1297 1297  
1298 1298          if (isdir(fullpath)) {
1299 1299                  DIR *dirp;
1300 1300                  struct dirent *dp;
1301 1301  
1302 1302                  /* open all files in the directory and attempt to read them */
1303 1303                  if ((dirp = opendir(fullpath)) == NULL) {
1304 1304                          return (KMF_ERR_BAD_PARAMETER);
1305 1305                  }
1306 1306  
1307 1307                  while ((dp = readdir(dirp)) != NULL) {
1308 1308                          if (strcmp(dp->d_name, ".") != 0 &&
1309 1309                              strcmp(dp->d_name, "..") != 0) {
1310 1310                                  char *fname;
1311 1311  
1312 1312                                  fname = get_fullpath(fullpath,
1313 1313                                      (char *)&dp->d_name);
1314 1314  
1315 1315                                  if (fname == NULL) {
1316 1316                                          rv = KMF_ERR_MEMORY;
1317 1317                                          break;
1318 1318                                  }
1319 1319  
1320 1320                                  rv = kmf_load_cert(kmfh, issuer, subject,
1321 1321                                      serial, validity, fname, &certdata);
1322 1322  
1323 1323                                  if (rv == KMF_ERR_CERT_NOT_FOUND) {
1324 1324                                          free(fname);
1325 1325                                          kmf_free_data(&certdata);
1326 1326                                          rv = KMF_OK;
1327 1327                                          continue;
1328 1328                                  } else if (rv != KMF_OK) {
1329 1329                                          free(fname);
1330 1330                                          break;
1331 1331                                  }
1332 1332  
1333 1333                                  if (unlink(fname) != 0) {
1334 1334                                          SET_SYS_ERROR(kmfh, errno);
1335 1335                                          rv = KMF_ERR_INTERNAL;
1336 1336                                          free(fname);
1337 1337                                          break;
1338 1338                                  }
1339 1339                                  free(fname);
1340 1340                                  kmf_free_data(&certdata);
1341 1341                          }
1342 1342                  }
1343 1343                  (void) closedir(dirp);
1344 1344          } else {
1345 1345                  /* Just try to load a single certificate */
1346 1346                  rv = kmf_load_cert(kmfh, issuer, subject, serial, validity,
1347 1347                      fullpath, &certdata);
1348 1348                  if (rv == KMF_OK) {
1349 1349                          if (unlink(fullpath) != 0) {
1350 1350                                  SET_SYS_ERROR(kmfh, errno);
1351 1351                                  rv = KMF_ERR_INTERNAL;
1352 1352                          }
1353 1353                  }
1354 1354          }
1355 1355  
1356 1356  out:
1357 1357          if (fullpath != NULL)
1358 1358                  free(fullpath);
1359 1359  
1360 1360          kmf_free_data(&certdata);
1361 1361  
1362 1362          return (rv);
1363 1363  }
1364 1364  
1365 1365  KMF_RETURN
1366 1366  OpenSSL_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1367 1367          KMF_DATA *keydata)
1368 1368  {
1369 1369          KMF_RETURN rv = KMF_OK;
1370 1370          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1371 1371          int n;
1372 1372  
1373 1373          if (key == NULL || keydata == NULL ||
1374 1374              key->keyp == NULL)
1375 1375                  return (KMF_ERR_BAD_PARAMETER);
1376 1376  
1377 1377          if (key->keyalg == KMF_RSA) {
1378 1378                  RSA *pubkey = EVP_PKEY_get1_RSA(key->keyp);
1379 1379  
1380 1380                  if (!(n = i2d_RSA_PUBKEY(pubkey, &keydata->Data))) {
1381 1381                          SET_ERROR(kmfh, ERR_get_error());
1382 1382                          return (KMF_ERR_ENCODING);
1383 1383                  }
1384 1384                  RSA_free(pubkey);
1385 1385          } else if (key->keyalg == KMF_DSA) {
1386 1386                  DSA *pubkey = EVP_PKEY_get1_DSA(key->keyp);
1387 1387  
1388 1388                  if (!(n = i2d_DSA_PUBKEY(pubkey, &keydata->Data))) {
1389 1389                          SET_ERROR(kmfh, ERR_get_error());
1390 1390                          return (KMF_ERR_ENCODING);
1391 1391                  }
1392 1392                  DSA_free(pubkey);
1393 1393          } else {
1394 1394                  return (KMF_ERR_BAD_PARAMETER);
1395 1395          }
1396 1396          keydata->Length = n;
1397 1397  
1398 1398  cleanup:
1399 1399          if (rv != KMF_OK) {
1400 1400                  if (keydata->Data)
1401 1401                          free(keydata->Data);
1402 1402                  keydata->Data = NULL;
1403 1403                  keydata->Length = 0;
1404 1404          }
1405 1405  
1406 1406          return (rv);
1407 1407  }
1408 1408  
1409 1409  static KMF_RETURN
1410 1410  ssl_write_key(KMF_HANDLE *kmfh, KMF_ENCODE_FORMAT format, BIO *out,
1411 1411          KMF_CREDENTIAL *cred, EVP_PKEY *pkey, boolean_t private)
1412 1412  {
1413 1413          int rv = 0;
1414 1414          RSA *rsa;
1415 1415          DSA *dsa;
1416 1416  
1417 1417          if (pkey == NULL || out == NULL)
1418 1418                  return (KMF_ERR_BAD_PARAMETER);
1419 1419  
1420 1420          switch (format) {
1421 1421                  case KMF_FORMAT_RAWKEY:
1422 1422                          /* same as ASN.1 */
1423 1423                  case KMF_FORMAT_ASN1:
1424 1424                          if (pkey->type == EVP_PKEY_RSA) {
1425 1425                                  rsa = EVP_PKEY_get1_RSA(pkey);
1426 1426                                  if (private)
1427 1427                                          rv = i2d_RSAPrivateKey_bio(out, rsa);
1428 1428                                  else
1429 1429                                          rv = i2d_RSAPublicKey_bio(out, rsa);
1430 1430                                  RSA_free(rsa);
1431 1431                          } else if (pkey->type == EVP_PKEY_DSA) {
1432 1432                                  dsa = EVP_PKEY_get1_DSA(pkey);
1433 1433                                  rv = i2d_DSAPrivateKey_bio(out, dsa);
1434 1434                                  DSA_free(dsa);
1435 1435                          }
1436 1436                          if (rv == 1) {
1437 1437                                  rv = KMF_OK;
1438 1438                          } else {
1439 1439                                  SET_ERROR(kmfh, rv);
1440 1440                          }
1441 1441                          break;
1442 1442                  case KMF_FORMAT_PEM:
1443 1443                          if (pkey->type == EVP_PKEY_RSA) {
1444 1444                                  rsa = EVP_PKEY_get1_RSA(pkey);
1445 1445                                  if (private)
1446 1446                                          rv = PEM_write_bio_RSAPrivateKey(out,
1447 1447                                              rsa, NULL, NULL, 0, NULL,
1448 1448                                              (cred != NULL ? cred->cred : NULL));
1449 1449                                  else
1450 1450                                          rv = PEM_write_bio_RSAPublicKey(out,
1451 1451                                              rsa);
1452 1452                                  RSA_free(rsa);
1453 1453                          } else if (pkey->type == EVP_PKEY_DSA) {
1454 1454                                  dsa = EVP_PKEY_get1_DSA(pkey);
1455 1455                                  rv = PEM_write_bio_DSAPrivateKey(out,
1456 1456                                      dsa, NULL, NULL, 0, NULL,
1457 1457                                      (cred != NULL ? cred->cred : NULL));
1458 1458                                  DSA_free(dsa);
1459 1459                          }
1460 1460  
1461 1461                          if (rv == 1) {
1462 1462                                  rv = KMF_OK;
1463 1463                          } else {
1464 1464                                  SET_ERROR(kmfh, rv);
1465 1465                          }
1466 1466                          break;
1467 1467  
1468 1468                  default:
1469 1469                          rv = KMF_ERR_BAD_PARAMETER;
1470 1470          }
1471 1471  
1472 1472          return (rv);
1473 1473  }
1474 1474  
1475 1475  KMF_RETURN
1476 1476  OpenSSL_CreateKeypair(KMF_HANDLE_T handle, int numattr,
1477 1477          KMF_ATTRIBUTE *attrlist)
1478 1478  {
1479 1479          KMF_RETURN rv = KMF_OK;
1480 1480          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1481 1481          uint32_t eValue = 0x010001;
1482 1482          RSA *sslPrivKey = NULL;
1483 1483          DSA *sslDSAKey = NULL;
1484 1484          EVP_PKEY *eprikey = NULL;
1485 1485          EVP_PKEY *epubkey = NULL;
1486 1486          BIO *out = NULL;
1487 1487          KMF_KEY_HANDLE *pubkey = NULL, *privkey = NULL;
1488 1488          uint32_t keylen = 1024;
1489 1489          uint32_t keylen_size = sizeof (uint32_t);
1490 1490          boolean_t storekey = TRUE;
1491 1491          KMF_KEY_ALG keytype = KMF_RSA;
1492 1492  
1493 1493          rv = kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
1494 1494              &storekey, NULL);
1495 1495          if (rv != KMF_OK) {
1496 1496                  /* "storekey" is optional. Default is TRUE */
1497 1497                  rv = KMF_OK;
1498 1498          }
1499 1499  
1500 1500          rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
1501 1501              (void *)&keytype, NULL);
1502 1502          if (rv != KMF_OK)
1503 1503                  /* keytype is optional.  KMF_RSA is default */
1504 1504                  rv = KMF_OK;
1505 1505  
1506 1506          pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
1507 1507          if (pubkey == NULL)
1508 1508                  return (KMF_ERR_BAD_PARAMETER);
1509 1509  
1510 1510          privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
1511 1511          if (privkey == NULL)
1512 1512                  return (KMF_ERR_BAD_PARAMETER);
1513 1513  
1514 1514          (void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
1515 1515          (void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
1516 1516  
1517 1517          eprikey = EVP_PKEY_new();
1518 1518          if (eprikey == NULL) {
1519 1519                  SET_ERROR(kmfh, ERR_get_error());
1520 1520                  rv = KMF_ERR_KEYGEN_FAILED;
1521 1521                  goto cleanup;
1522 1522          }
1523 1523          epubkey = EVP_PKEY_new();
1524 1524          if (epubkey == NULL) {
1525 1525                  SET_ERROR(kmfh, ERR_get_error());
1526 1526                  rv = KMF_ERR_KEYGEN_FAILED;
1527 1527                  goto cleanup;
1528 1528          }
1529 1529          if (keytype == KMF_RSA) {
1530 1530                  KMF_BIGINT *rsaexp = NULL;
1531 1531  
1532 1532                  rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attrlist, numattr);
1533 1533                  if (rsaexp != NULL) {
1534 1534                          if (rsaexp->len > 0 &&
1535 1535                              rsaexp->len <= sizeof (eValue) &&
1536 1536                              rsaexp->val != NULL) {
1537 1537                                  /* LINTED E_BAD_PTR_CAST_ALIGN */
1538 1538                                  eValue = *(uint32_t *)rsaexp->val;
1539 1539                          } else {
1540 1540                                  rv = KMF_ERR_BAD_PARAMETER;
1541 1541                                  goto cleanup;
1542 1542                          }
1543 1543                  } else {
1544 1544                          /* RSA Exponent is optional. Default is 0x10001 */
1545 1545                          rv = KMF_OK;
1546 1546                  }
1547 1547  
1548 1548                  rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
1549 1549                      &keylen, &keylen_size);
1550 1550                  if (rv == KMF_ERR_ATTR_NOT_FOUND)
1551 1551                          /* keylen is optional, default is 1024 */
1552 1552                          rv = KMF_OK;
1553 1553                  if (rv != KMF_OK) {
1554 1554                          rv = KMF_ERR_BAD_PARAMETER;
1555 1555                          goto cleanup;
1556 1556                  }
1557 1557  
1558 1558                  sslPrivKey = RSA_generate_key(keylen, eValue, NULL, NULL);
1559 1559                  if (sslPrivKey == NULL) {
1560 1560                          SET_ERROR(kmfh, ERR_get_error());
1561 1561                          rv = KMF_ERR_KEYGEN_FAILED;
1562 1562                  } else {
1563 1563                          (void) EVP_PKEY_set1_RSA(eprikey, sslPrivKey);
1564 1564                          privkey->kstype = KMF_KEYSTORE_OPENSSL;
1565 1565                          privkey->keyalg = KMF_RSA;
1566 1566                          privkey->keyclass = KMF_ASYM_PRI;
1567 1567                          privkey->israw = FALSE;
1568 1568                          privkey->keyp = (void *)eprikey;
1569 1569  
1570 1570                          /* OpenSSL derives the public key from the private */
1571 1571                          (void) EVP_PKEY_set1_RSA(epubkey, sslPrivKey);
1572 1572                          pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1573 1573                          pubkey->keyalg = KMF_RSA;
1574 1574                          pubkey->israw = FALSE;
1575 1575                          pubkey->keyclass = KMF_ASYM_PUB;
1576 1576                          pubkey->keyp = (void *)epubkey;
1577 1577                  }
1578 1578          } else if (keytype == KMF_DSA) {
1579 1579                  DSA *dp;
1580 1580                  sslDSAKey = DSA_new();
1581 1581                  if (sslDSAKey == NULL) {
1582 1582                          SET_ERROR(kmfh, ERR_get_error());
1583 1583                          return (KMF_ERR_MEMORY);
1584 1584                  }
1585 1585  
1586 1586                  if ((sslDSAKey->p = BN_bin2bn(P, sizeof (P), sslDSAKey->p)) ==
1587 1587                      NULL) {
1588 1588                          SET_ERROR(kmfh, ERR_get_error());
1589 1589                          rv = KMF_ERR_KEYGEN_FAILED;
1590 1590                          goto cleanup;
1591 1591                  }
1592 1592                  if ((sslDSAKey->q = BN_bin2bn(Q, sizeof (Q), sslDSAKey->q)) ==
1593 1593                      NULL) {
1594 1594                          SET_ERROR(kmfh, ERR_get_error());
1595 1595                          rv = KMF_ERR_KEYGEN_FAILED;
1596 1596                          goto cleanup;
1597 1597                  }
1598 1598                  if ((sslDSAKey->g = BN_bin2bn(G, sizeof (G), sslDSAKey->g)) ==
1599 1599                      NULL) {
1600 1600                          SET_ERROR(kmfh, ERR_get_error());
1601 1601                          rv = KMF_ERR_KEYGEN_FAILED;
1602 1602                          goto cleanup;
1603 1603                  }
1604 1604  
1605 1605                  if (!DSA_generate_key(sslDSAKey)) {
1606 1606                          SET_ERROR(kmfh, ERR_get_error());
1607 1607                          rv = KMF_ERR_KEYGEN_FAILED;
1608 1608                          goto cleanup;
1609 1609                  }
1610 1610  
1611 1611                  privkey->kstype = KMF_KEYSTORE_OPENSSL;
1612 1612                  privkey->keyalg = KMF_DSA;
1613 1613                  privkey->keyclass = KMF_ASYM_PRI;
1614 1614                  privkey->israw = FALSE;
1615 1615                  if (EVP_PKEY_set1_DSA(eprikey, sslDSAKey)) {
1616 1616                          privkey->keyp = (void *)eprikey;
1617 1617                  } else {
1618 1618                          SET_ERROR(kmfh, ERR_get_error());
1619 1619                          rv = KMF_ERR_KEYGEN_FAILED;
1620 1620                          goto cleanup;
1621 1621                  }
1622 1622                  dp = DSA_new();
1623 1623                  /* Make a copy for the public key */
1624 1624                  if (dp != NULL) {
1625 1625                          if ((dp->p = BN_new()) == NULL) {
1626 1626                                  SET_ERROR(kmfh, ERR_get_error());
1627 1627                                  rv = KMF_ERR_MEMORY;
1628 1628                                  DSA_free(dp);
1629 1629                                  goto cleanup;
1630 1630                          }
1631 1631                          if ((dp->q = BN_new()) == NULL) {
1632 1632                                  SET_ERROR(kmfh, ERR_get_error());
1633 1633                                  rv = KMF_ERR_MEMORY;
1634 1634                                  BN_free(dp->p);
1635 1635                                  DSA_free(dp);
1636 1636                                  goto cleanup;
1637 1637                          }
1638 1638                          if ((dp->g = BN_new()) == NULL) {
1639 1639                                  SET_ERROR(kmfh, ERR_get_error());
1640 1640                                  rv = KMF_ERR_MEMORY;
1641 1641                                  BN_free(dp->q);
1642 1642                                  BN_free(dp->p);
1643 1643                                  DSA_free(dp);
1644 1644                                  goto cleanup;
1645 1645                          }
1646 1646                          if ((dp->pub_key = BN_new()) == NULL) {
1647 1647                                  SET_ERROR(kmfh, ERR_get_error());
1648 1648                                  rv = KMF_ERR_MEMORY;
1649 1649                                  BN_free(dp->q);
1650 1650                                  BN_free(dp->p);
1651 1651                                  BN_free(dp->g);
1652 1652                                  DSA_free(dp);
1653 1653                                  goto cleanup;
1654 1654                          }
1655 1655                          (void) BN_copy(dp->p, sslDSAKey->p);
1656 1656                          (void) BN_copy(dp->q, sslDSAKey->q);
1657 1657                          (void) BN_copy(dp->g, sslDSAKey->g);
1658 1658                          (void) BN_copy(dp->pub_key, sslDSAKey->pub_key);
1659 1659  
1660 1660                          pubkey->kstype = KMF_KEYSTORE_OPENSSL;
1661 1661                          pubkey->keyalg = KMF_DSA;
1662 1662                          pubkey->keyclass = KMF_ASYM_PUB;
1663 1663                          pubkey->israw = FALSE;
1664 1664  
1665 1665                          if (EVP_PKEY_set1_DSA(epubkey, sslDSAKey)) {
1666 1666                                  pubkey->keyp = (void *)epubkey;
1667 1667                          } else {
1668 1668                                  SET_ERROR(kmfh, ERR_get_error());
1669 1669                                  rv = KMF_ERR_KEYGEN_FAILED;
1670 1670                                  goto cleanup;
1671 1671                          }
1672 1672                  }
1673 1673          }
1674 1674  
1675 1675          if (rv != KMF_OK) {
1676 1676                  goto cleanup;
1677 1677          }
1678 1678  
1679 1679          if (storekey) {
1680 1680                  KMF_ATTRIBUTE storeattrs[4]; /* max. 4 attributes needed */
1681 1681                  int i = 0;
1682 1682                  char *keyfile = NULL, *dirpath = NULL;
1683 1683                  KMF_ENCODE_FORMAT format;
1684 1684                  /*
1685 1685                   * Construct a new attribute arrray and call openssl_store_key
1686 1686                   */
1687 1687                  kmf_set_attr_at_index(storeattrs, i, KMF_PRIVKEY_HANDLE_ATTR,
1688 1688                      privkey, sizeof (privkey));
1689 1689                  i++;
1690 1690  
1691 1691                  dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
1692 1692                  if (dirpath != NULL) {
1693 1693                          storeattrs[i].type = KMF_DIRPATH_ATTR;
1694 1694                          storeattrs[i].pValue = dirpath;
1695 1695                          storeattrs[i].valueLen = strlen(dirpath);
1696 1696                          i++;
1697 1697                  } else {
1698 1698                          rv = KMF_OK; /* DIRPATH is optional */
1699 1699                  }
1700 1700                  keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR,
1701 1701                      attrlist, numattr);
1702 1702                  if (keyfile != NULL) {
1703 1703                          storeattrs[i].type = KMF_KEY_FILENAME_ATTR;
1704 1704                          storeattrs[i].pValue = keyfile;
1705 1705                          storeattrs[i].valueLen = strlen(keyfile);
1706 1706                          i++;
1707 1707                  } else {
1708 1708                          goto cleanup; /* KEYFILE is required */
1709 1709                  }
1710 1710                  rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
1711 1711                      (void *)&format, NULL);
1712 1712                  if (rv == KMF_OK) {
1713 1713                          storeattrs[i].type = KMF_ENCODE_FORMAT_ATTR;
1714 1714                          storeattrs[i].pValue = &format;
1715 1715                          storeattrs[i].valueLen = sizeof (format);
1716 1716                          i++;
1717 1717                  }
1718 1718  
1719 1719                  rv = OpenSSL_StoreKey(handle, i, storeattrs);
1720 1720          }
1721 1721  
1722 1722  cleanup:
1723 1723          if (rv != KMF_OK) {
1724 1724                  if (eprikey != NULL)
1725 1725                          EVP_PKEY_free(eprikey);
1726 1726  
1727 1727                  if (epubkey != NULL)
1728 1728                          EVP_PKEY_free(epubkey);
1729 1729  
1730 1730                  if (pubkey->keylabel) {
1731 1731                          free(pubkey->keylabel);
1732 1732                          pubkey->keylabel = NULL;
1733 1733                  }
1734 1734  
1735 1735                  if (privkey->keylabel) {
1736 1736                          free(privkey->keylabel);
1737 1737                          privkey->keylabel = NULL;
1738 1738                  }
1739 1739  
1740 1740                  pubkey->keyp = NULL;
1741 1741                  privkey->keyp = NULL;
1742 1742          }
1743 1743  
1744 1744          if (sslPrivKey)
1745 1745                  RSA_free(sslPrivKey);
1746 1746  
1747 1747          if (sslDSAKey)
1748 1748                  DSA_free(sslDSAKey);
1749 1749  
1750 1750          if (out != NULL)
1751 1751                  (void) BIO_free(out);
1752 1752  
1753 1753          return (rv);
1754 1754  }
1755 1755  
1756 1756  /*
1757 1757   * Make sure the BN conversion is properly padded with 0x00
1758 1758   * bytes.  If not, signature verification for DSA signatures
1759 1759   * may fail in the case where the bignum value does not use
1760 1760   * all of the bits.
1761 1761   */
1762 1762  static int
1763 1763  fixbnlen(BIGNUM *bn, unsigned char *buf, int len) {
1764 1764          int bytes = len - BN_num_bytes(bn);
1765 1765  
1766 1766          /* prepend with leading 0x00 if necessary */
1767 1767          while (bytes-- > 0)
1768 1768                  *buf++ = 0;
1769 1769  
1770 1770          (void) BN_bn2bin(bn, buf);
1771 1771          /*
1772 1772           * Return the desired length since we prepended it
1773 1773           * with the necessary 0x00 padding.
1774 1774           */
1775 1775          return (len);
1776 1776  }
1777 1777  
1778 1778  KMF_RETURN
1779 1779  OpenSSL_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
1780 1780          KMF_OID *AlgOID, KMF_DATA *tobesigned, KMF_DATA *output)
1781 1781  {
1782 1782          KMF_RETURN ret = KMF_OK;
1783 1783          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1784 1784          KMF_ALGORITHM_INDEX             AlgId;
1785 1785          EVP_MD_CTX ctx;
1786 1786          const EVP_MD *md;
1787 1787  
1788 1788          if (key == NULL || AlgOID == NULL ||
1789 1789              tobesigned == NULL || output == NULL ||
1790 1790              tobesigned->Data == NULL ||
1791 1791              output->Data == NULL)
1792 1792                  return (KMF_ERR_BAD_PARAMETER);
1793 1793  
1794 1794          /* Map the OID to an OpenSSL algorithm */
1795 1795          AlgId = x509_algoid_to_algid(AlgOID);
1796 1796          if (AlgId == KMF_ALGID_NONE)
1797 1797                  return (KMF_ERR_BAD_ALGORITHM);
1798 1798  
1799 1799          if (key->keyalg == KMF_RSA) {
1800 1800                  EVP_PKEY *pkey = (EVP_PKEY *)key->keyp;
1801 1801                  uchar_t *p;
1802 1802                  int len;
1803 1803                  if (AlgId == KMF_ALGID_MD5WithRSA)
1804 1804                          md = EVP_md5();
1805 1805                  else if (AlgId == KMF_ALGID_MD2WithRSA)
1806 1806                          md = EVP_md2();
1807 1807                  else if (AlgId == KMF_ALGID_SHA1WithRSA)
1808 1808                          md = EVP_sha1();
1809 1809                  else if (AlgId == KMF_ALGID_SHA256WithRSA)
1810 1810                          md = EVP_sha256();
1811 1811                  else if (AlgId == KMF_ALGID_SHA384WithRSA)
1812 1812                          md = EVP_sha384();
1813 1813                  else if (AlgId == KMF_ALGID_SHA512WithRSA)
1814 1814                          md = EVP_sha512();
1815 1815                  else if (AlgId == KMF_ALGID_RSA)
1816 1816                          md = NULL;
1817 1817                  else
1818 1818                          return (KMF_ERR_BAD_ALGORITHM);
1819 1819  
1820 1820                  if ((md == NULL) && (AlgId == KMF_ALGID_RSA)) {
1821 1821                          RSA *rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey);
1822 1822  
1823 1823                          p = output->Data;
1824 1824                          if ((len = RSA_private_encrypt(tobesigned->Length,
1825 1825                              tobesigned->Data, p, rsa,
1826 1826                              RSA_PKCS1_PADDING)) <= 0) {
1827 1827                                  SET_ERROR(kmfh, ERR_get_error());
1828 1828                                  ret = KMF_ERR_INTERNAL;
1829 1829                          }
1830 1830                          output->Length = len;
1831 1831                  } else {
1832 1832                          (void) EVP_MD_CTX_init(&ctx);
1833 1833                          (void) EVP_SignInit_ex(&ctx, md, NULL);
1834 1834                          (void) EVP_SignUpdate(&ctx, tobesigned->Data,
1835 1835                              (uint32_t)tobesigned->Length);
1836 1836                          len = (uint32_t)output->Length;
1837 1837                          p = output->Data;
1838 1838                          if (!EVP_SignFinal(&ctx, p, (uint32_t *)&len, pkey)) {
1839 1839                                  SET_ERROR(kmfh, ERR_get_error());
1840 1840                                  len = 0;
1841 1841                                  ret = KMF_ERR_INTERNAL;
1842 1842                          }
1843 1843                          output->Length = len;
1844 1844                          (void) EVP_MD_CTX_cleanup(&ctx);
1845 1845                  }
1846 1846          } else if (key->keyalg == KMF_DSA) {
1847 1847                  DSA *dsa = EVP_PKEY_get1_DSA(key->keyp);
1848 1848  
1849 1849                  uchar_t hash[EVP_MAX_MD_SIZE];
1850 1850                  uint32_t hashlen;
1851 1851                  DSA_SIG *dsasig;
1852 1852  
1853 1853                  if (AlgId == KMF_ALGID_DSA ||
1854 1854                      AlgId == KMF_ALGID_SHA1WithDSA)
1855 1855                          md = EVP_sha1();
1856 1856                  else if (AlgId == KMF_ALGID_SHA256WithDSA)
1857 1857                          md = EVP_sha256();
1858 1858                  else /* Bad algorithm */
1859 1859                          return (KMF_ERR_BAD_ALGORITHM);
1860 1860  
1861 1861                  /*
1862 1862                   * OpenSSL EVP_Sign operation automatically converts to
1863 1863                   * ASN.1 output so we do the operations separately so we
1864 1864                   * are assured of NOT getting ASN.1 output returned.
1865 1865                   * KMF does not want ASN.1 encoded results because
1866 1866                   * not all mechanisms return ASN.1 encodings (PKCS#11
1867 1867                   * and NSS return raw signature data).
1868 1868                   */
1869 1869                  EVP_MD_CTX_init(&ctx);
1870 1870                  (void) EVP_DigestInit_ex(&ctx, md, NULL);
1871 1871                  (void) EVP_DigestUpdate(&ctx, tobesigned->Data,
1872 1872                      tobesigned->Length);
1873 1873                  (void) EVP_DigestFinal_ex(&ctx, hash, &hashlen);
1874 1874  
1875 1875                  /* Only sign first 20 bytes for SHA2 */
1876 1876                  if (AlgId == KMF_ALGID_SHA256WithDSA)
1877 1877                          hashlen = 20;
1878 1878                  dsasig = DSA_do_sign(hash, hashlen, dsa);
1879 1879                  if (dsasig != NULL) {
1880 1880                          int i;
1881 1881                          output->Length = i = fixbnlen(dsasig->r, output->Data,
1882 1882                              hashlen);
1883 1883  
1884 1884                          output->Length += fixbnlen(dsasig->s, &output->Data[i],
1885 1885                              hashlen);
1886 1886  
1887 1887                          DSA_SIG_free(dsasig);
1888 1888                  } else {
1889 1889                          SET_ERROR(kmfh, ERR_get_error());
1890 1890                  }
1891 1891                  (void) EVP_MD_CTX_cleanup(&ctx);
1892 1892          } else {
1893 1893                  return (KMF_ERR_BAD_PARAMETER);
1894 1894          }
1895 1895  cleanup:
1896 1896          return (ret);
1897 1897  }
1898 1898  
1899 1899  KMF_RETURN
1900 1900  /*ARGSUSED*/
1901 1901  OpenSSL_DeleteKey(KMF_HANDLE_T handle,
1902 1902          int numattr, KMF_ATTRIBUTE *attrlist)
1903 1903  {
1904 1904          KMF_RETURN rv = KMF_OK;
1905 1905          KMF_KEY_HANDLE *key;
1906 1906          boolean_t destroy = B_TRUE;
1907 1907  
1908 1908          key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
1909 1909          if (key == NULL || key->keyp == NULL)
1910 1910                  return (KMF_ERR_BAD_PARAMETER);
1911 1911  
1912 1912          rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
1913 1913              (void *)&destroy, NULL);
1914 1914          if (rv != KMF_OK) {
1915 1915                  /* "destroy" is optional. Default is TRUE */
1916 1916                  rv = KMF_OK;
1917 1917          }
1918 1918  
1919 1919          if (key->keyclass != KMF_ASYM_PUB &&
1920 1920              key->keyclass != KMF_ASYM_PRI &&
1921 1921              key->keyclass != KMF_SYMMETRIC)
1922 1922                  return (KMF_ERR_BAD_KEY_CLASS);
1923 1923  
1924 1924          if (key->keyclass == KMF_SYMMETRIC) {
1925 1925                  kmf_free_raw_sym_key((KMF_RAW_SYM_KEY *)key->keyp);
1926 1926                  key->keyp = NULL;
1927 1927          } else {
1928 1928                  if (key->keyp != NULL) {
1929 1929                          EVP_PKEY_free(key->keyp);
1930 1930                          key->keyp = NULL;
1931 1931                  }
1932 1932          }
1933 1933  
1934 1934          if (key->keylabel != NULL) {
1935 1935                  EVP_PKEY *pkey = NULL;
1936 1936                  /* If the file exists, make sure it is a proper key. */
1937 1937                  pkey = openssl_load_key(handle, key->keylabel);
1938 1938                  if (pkey == NULL) {
1939 1939                          if (key->keylabel != NULL) {
1940 1940                                  free(key->keylabel);
1941 1941                                  key->keylabel = NULL;
1942 1942                          }
1943 1943                          return (KMF_ERR_KEY_NOT_FOUND);
1944 1944                  }
1945 1945                  EVP_PKEY_free(pkey);
1946 1946  
1947 1947                  if (destroy) {
1948 1948                          if (unlink(key->keylabel) != 0) {
1949 1949                                  KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1950 1950                                  SET_SYS_ERROR(kmfh, errno);
1951 1951                                  rv = KMF_ERR_INTERNAL;
1952 1952                          }
1953 1953                  }
1954 1954                  if (key->keylabel != NULL) {
1955 1955                          free(key->keylabel);
1956 1956                          key->keylabel = NULL;
1957 1957                  }
1958 1958          }
1959 1959          return (rv);
1960 1960  }
1961 1961  
1962 1962  KMF_RETURN
1963 1963  OpenSSL_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
1964 1964  {
1965 1965          KMF_RETURN ret = KMF_OK;
1966 1966          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
1967 1967          char str[256];  /* OpenSSL needs at least 120 byte buffer */
1968 1968  
1969 1969          ERR_error_string_n(kmfh->lasterr.errcode, str, sizeof (str));
1970 1970          if (strlen(str)) {
1971 1971                  *msgstr = (char *)strdup(str);
1972 1972                  if ((*msgstr) == NULL)
1973 1973                          ret = KMF_ERR_MEMORY;
1974 1974          } else {
1975 1975                  *msgstr = NULL;
1976 1976          }
1977 1977  
1978 1978          return (ret);
1979 1979  }
1980 1980  
1981 1981  static int
1982 1982  ext2NID(int kmfext)
1983 1983  {
1984 1984          switch (kmfext) {
1985 1985                  case KMF_X509_EXT_KEY_USAGE:
1986 1986                          return (NID_key_usage);
1987 1987                  case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
1988 1988                          return (NID_private_key_usage_period);
1989 1989                  case KMF_X509_EXT_CERT_POLICIES:
1990 1990                          return (NID_certificate_policies);
1991 1991                  case KMF_X509_EXT_SUBJ_ALTNAME:
1992 1992                          return (NID_subject_alt_name);
1993 1993                  case KMF_X509_EXT_ISSUER_ALTNAME:
1994 1994                          return (NID_issuer_alt_name);
1995 1995                  case KMF_X509_EXT_BASIC_CONSTRAINTS:
1996 1996                          return (NID_basic_constraints);
1997 1997                  case KMF_X509_EXT_EXT_KEY_USAGE:
1998 1998                          return (NID_ext_key_usage);
1999 1999                  case KMF_X509_EXT_AUTH_KEY_ID:
2000 2000                          return (NID_authority_key_identifier);
2001 2001                  case KMF_X509_EXT_CRL_DIST_POINTS:
2002 2002                          return (NID_crl_distribution_points);
2003 2003                  case KMF_X509_EXT_SUBJ_KEY_ID:
2004 2004                          return (NID_subject_key_identifier);
2005 2005                  case KMF_X509_EXT_POLICY_MAPPINGS:
2006 2006                          return (OBJ_sn2nid("policyMappings"));
2007 2007                  case KMF_X509_EXT_NAME_CONSTRAINTS:
2008 2008                          return (OBJ_sn2nid("nameConstraints"));
2009 2009                  case KMF_X509_EXT_POLICY_CONSTRAINTS:
2010 2010                          return (OBJ_sn2nid("policyConstraints"));
2011 2011                  case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2012 2012                          return (OBJ_sn2nid("inhibitAnyPolicy"));
2013 2013                  case KMF_X509_EXT_FRESHEST_CRL:
2014 2014                          return (OBJ_sn2nid("freshestCRL"));
2015 2015                  default:
2016 2016                          return (NID_undef);
2017 2017          }
2018 2018  }
2019 2019  
2020 2020  KMF_RETURN
2021 2021  OpenSSL_CertGetPrintable(KMF_HANDLE_T handle, const KMF_DATA *pcert,
2022 2022          KMF_PRINTABLE_ITEM flag, char *resultStr)
2023 2023  {
2024 2024          KMF_RETURN ret = KMF_OK;
2025 2025          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2026 2026          X509 *xcert = NULL;
2027 2027          unsigned char *outbuf = NULL;
2028 2028          unsigned char *outbuf_p;
2029 2029          char *tmpstr = NULL;
2030 2030          int j;
2031 2031          int ext_index, nid, len;
2032 2032          BIO *mem = NULL;
2033 2033  #if OPENSSL_VERSION_NUMBER < 0x10000000L
2034 2034          STACK *emlst = NULL;
2035 2035  #else
2036 2036          STACK_OF(OPENSSL_STRING) *emlst = NULL;
2037 2037  #endif
2038 2038          X509_EXTENSION *ex;
2039 2039          X509_CINF *ci;
2040 2040  
2041 2041          if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0) {
2042 2042                  return (KMF_ERR_BAD_PARAMETER);
2043 2043          }
2044 2044  
2045 2045          /* copy cert data to outbuf */
2046 2046          outbuf = malloc(pcert->Length);
2047 2047          if (outbuf == NULL) {
2048 2048                  return (KMF_ERR_MEMORY);
2049 2049          }
2050 2050          (void) memcpy(outbuf, pcert->Data, pcert->Length);
2051 2051  
2052 2052          outbuf_p = outbuf; /* use a temp pointer; required by openssl */
2053 2053          xcert = d2i_X509(NULL, (const uchar_t **)&outbuf_p, pcert->Length);
2054 2054          if (xcert == NULL) {
2055 2055                  SET_ERROR(kmfh, ERR_get_error());
2056 2056                  ret = KMF_ERR_ENCODING;
2057 2057                  goto out;
2058 2058          }
2059 2059  
2060 2060          mem = BIO_new(BIO_s_mem());
2061 2061          if (mem == NULL) {
2062 2062                  SET_ERROR(kmfh, ERR_get_error());
2063 2063                  ret = KMF_ERR_MEMORY;
2064 2064                  goto out;
2065 2065          }
2066 2066  
2067 2067          switch (flag) {
2068 2068          case KMF_CERT_ISSUER:
2069 2069                  (void) X509_NAME_print_ex(mem, X509_get_issuer_name(xcert), 0,
2070 2070                      XN_FLAG_SEP_CPLUS_SPC);
2071 2071                  len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2072 2072                  break;
2073 2073  
2074 2074          case KMF_CERT_SUBJECT:
2075 2075                  (void) X509_NAME_print_ex(mem, X509_get_subject_name(xcert), 0,
2076 2076                      XN_FLAG_SEP_CPLUS_SPC);
2077 2077                  len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2078 2078                  break;
2079 2079  
2080 2080          case KMF_CERT_VERSION:
2081 2081                  tmpstr = i2s_ASN1_INTEGER(NULL, xcert->cert_info->version);
2082 2082                  (void) strncpy(resultStr, tmpstr, KMF_CERT_PRINTABLE_LEN);
2083 2083                  OPENSSL_free(tmpstr);
2084 2084                  len = strlen(resultStr);
2085 2085                  break;
2086 2086  
2087 2087          case KMF_CERT_SERIALNUM:
2088 2088                  if (i2a_ASN1_INTEGER(mem, X509_get_serialNumber(xcert)) > 0) {
2089 2089                          (void) strcpy(resultStr, "0x");
2090 2090                          len = BIO_gets(mem, &resultStr[2],
2091 2091                              KMF_CERT_PRINTABLE_LEN - 2);
2092 2092                  }
2093 2093                  break;
2094 2094  
2095 2095          case KMF_CERT_NOTBEFORE:
2096 2096                  (void) ASN1_TIME_print(mem, X509_get_notBefore(xcert));
2097 2097                  len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2098 2098                  break;
2099 2099  
2100 2100          case KMF_CERT_NOTAFTER:
2101 2101                  (void) ASN1_TIME_print(mem, X509_get_notAfter(xcert));
2102 2102                  len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2103 2103                  break;
2104 2104  
2105 2105          case KMF_CERT_PUBKEY_DATA:
2106 2106                  {
2107 2107                          EVP_PKEY *pkey = X509_get_pubkey(xcert);
2108 2108                          if (pkey == NULL) {
2109 2109                                  SET_ERROR(kmfh, ERR_get_error());
2110 2110                                  ret = KMF_ERR_ENCODING;
2111 2111                                  goto out;
2112 2112                          }
2113 2113  
2114 2114                          if (pkey->type == EVP_PKEY_RSA) {
2115 2115                                  (void) BIO_printf(mem,
2116 2116                                      "RSA Public Key: (%d bit)\n",
2117 2117                                      BN_num_bits(pkey->pkey.rsa->n));
2118 2118                                  (void) RSA_print(mem, pkey->pkey.rsa, 0);
2119 2119                          } else if (pkey->type == EVP_PKEY_DSA) {
2120 2120                                  (void) BIO_printf(mem,
2121 2121                                      "%12sDSA Public Key:\n", "");
2122 2122                                  (void) DSA_print(mem, pkey->pkey.dsa, 0);
2123 2123                          } else {
2124 2124                                  (void) BIO_printf(mem,
2125 2125                                      "%12sUnknown Public Key:\n", "");
2126 2126                          }
2127 2127                          (void) BIO_printf(mem, "\n");
2128 2128                          EVP_PKEY_free(pkey);
2129 2129                  }
2130 2130                  len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2131 2131                  break;
2132 2132          case KMF_CERT_SIGNATURE_ALG:
2133 2133          case KMF_CERT_PUBKEY_ALG:
2134 2134                  if (flag == KMF_CERT_SIGNATURE_ALG) {
2135 2135                          len = i2a_ASN1_OBJECT(mem,
2136 2136                              xcert->sig_alg->algorithm);
2137 2137                  } else {
2138 2138                          len = i2a_ASN1_OBJECT(mem,
2139 2139                              xcert->cert_info->key->algor->algorithm);
2140 2140                  }
2141 2141  
2142 2142                  if (len > 0) {
2143 2143                          len = BIO_read(mem, resultStr,
2144 2144                              KMF_CERT_PRINTABLE_LEN);
2145 2145                  }
2146 2146                  break;
2147 2147  
2148 2148          case KMF_CERT_EMAIL:
2149 2149                  emlst = X509_get1_email(xcert);
2150 2150  #if OPENSSL_VERSION_NUMBER < 0x10000000L
2151 2151                  for (j = 0; j < sk_num(emlst); j++)
2152 2152                          (void) BIO_printf(mem, "%s\n", sk_value(emlst, j));
2153 2153  #else
2154 2154                  for (j = 0; j < sk_OPENSSL_STRING_num(emlst); j++)
2155 2155                          (void) BIO_printf(mem, "%s\n",
2156 2156                              sk_OPENSSL_STRING_value(emlst, j));
2157 2157  #endif
2158 2158  
2159 2159                  len = BIO_gets(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2160 2160                  X509_email_free(emlst);
2161 2161                  break;
2162 2162          case KMF_X509_EXT_ISSUER_ALTNAME:
2163 2163          case KMF_X509_EXT_SUBJ_ALTNAME:
2164 2164          case KMF_X509_EXT_KEY_USAGE:
2165 2165          case KMF_X509_EXT_PRIV_KEY_USAGE_PERIOD:
2166 2166          case KMF_X509_EXT_CERT_POLICIES:
2167 2167          case KMF_X509_EXT_BASIC_CONSTRAINTS:
2168 2168          case KMF_X509_EXT_NAME_CONSTRAINTS:
2169 2169          case KMF_X509_EXT_POLICY_CONSTRAINTS:
2170 2170          case KMF_X509_EXT_EXT_KEY_USAGE:
2171 2171          case KMF_X509_EXT_INHIBIT_ANY_POLICY:
2172 2172          case KMF_X509_EXT_AUTH_KEY_ID:
2173 2173          case KMF_X509_EXT_SUBJ_KEY_ID:
2174 2174          case KMF_X509_EXT_POLICY_MAPPINGS:
2175 2175          case KMF_X509_EXT_CRL_DIST_POINTS:
2176 2176          case KMF_X509_EXT_FRESHEST_CRL:
2177 2177                  nid = ext2NID(flag);
2178 2178                  if (nid == NID_undef) {
2179 2179                          ret = KMF_ERR_EXTENSION_NOT_FOUND;
2180 2180                          goto out;
2181 2181                  }
2182 2182                  ci = xcert->cert_info;
2183 2183  
2184 2184                  ext_index = X509v3_get_ext_by_NID(ci->extensions, nid, -1);
2185 2185                  if (ext_index == -1) {
2186 2186                          SET_ERROR(kmfh, ERR_get_error());
2187 2187  
2188 2188                          ret = KMF_ERR_EXTENSION_NOT_FOUND;
2189 2189                          goto out;
2190 2190                  }
2191 2191                  ex = X509v3_get_ext(ci->extensions, ext_index);
2192 2192  
2193 2193                  (void) i2a_ASN1_OBJECT(mem, X509_EXTENSION_get_object(ex));
2194 2194  
2195 2195                  if (BIO_printf(mem, ": %s\n",
2196 2196                      X509_EXTENSION_get_critical(ex) ? "critical" : "") <= 0) {
2197 2197                          SET_ERROR(kmfh, ERR_get_error());
2198 2198                          ret = KMF_ERR_ENCODING;
2199 2199                          goto out;
2200 2200                  }
2201 2201                  if (!X509V3_EXT_print(mem, ex, X509V3_EXT_DUMP_UNKNOWN, 4)) {
2202 2202                          (void) BIO_printf(mem, "%*s", 4, "");
2203 2203                          (void) M_ASN1_OCTET_STRING_print(mem, ex->value);
2204 2204                  }
2205 2205                  if (BIO_write(mem, "\n", 1) <= 0) {
2206 2206                          SET_ERROR(kmfh, ERR_get_error());
2207 2207                          ret = KMF_ERR_ENCODING;
2208 2208                          goto out;
2209 2209                  }
2210 2210                  len = BIO_read(mem, resultStr, KMF_CERT_PRINTABLE_LEN);
2211 2211          }
2212 2212          if (len <= 0) {
2213 2213                  SET_ERROR(kmfh, ERR_get_error());
2214 2214                  ret = KMF_ERR_ENCODING;
2215 2215          }
2216 2216  
2217 2217  out:
2218 2218          if (outbuf != NULL) {
2219 2219                  free(outbuf);
2220 2220          }
2221 2221  
2222 2222          if (xcert != NULL) {
2223 2223                  X509_free(xcert);
2224 2224          }
2225 2225  
2226 2226          if (mem != NULL) {
2227 2227                  (void) BIO_free(mem);
2228 2228          }
2229 2229  
2230 2230          return (ret);
2231 2231  }
2232 2232  
2233 2233  KMF_RETURN
2234 2234  /*ARGSUSED*/
2235 2235  OpenSSL_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
2236 2236      KMF_ATTRIBUTE *attrlist)
2237 2237  {
2238 2238          KMF_RETURN rv = KMF_OK;
2239 2239          KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
2240 2240          KMF_KEY_CLASS keyclass = KMF_ASYM_PRI;
2241 2241          KMF_KEY_HANDLE *key = NULL;
2242 2242          uint32_t numkeys = 1; /* 1 key only */
2243 2243          char *dirpath = NULL;
2244 2244          char *keyfile = NULL;
2245 2245          KMF_ATTRIBUTE new_attrlist[16];
2246 2246          int i = 0;
2247 2247  
2248 2248          /*
2249 2249           * This is really just a FindKey operation, reuse the
2250 2250           * FindKey function.
2251 2251           */
2252 2252          kmf_set_attr_at_index(new_attrlist, i,
2253 2253              KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
2254 2254          i++;
2255 2255  
2256 2256          kmf_set_attr_at_index(new_attrlist, i,
2257 2257              KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t));
2258 2258          i++;
2259 2259  
2260 2260          kmf_set_attr_at_index(new_attrlist, i,
2261 2261              KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass));
2262 2262          i++;
2263 2263  
2264 2264          key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2265 2265          if (key == NULL) {
2266 2266                  return (KMF_ERR_BAD_PARAMETER);
2267 2267          } else {
2268 2268                  kmf_set_attr_at_index(new_attrlist, i,
2269 2269                      KMF_KEY_HANDLE_ATTR, key, sizeof (KMF_KEY_HANDLE));
2270 2270                  i++;
2271 2271          }
2272 2272  
2273 2273          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2274 2274          if (dirpath != NULL) {
2275 2275                  kmf_set_attr_at_index(new_attrlist, i,
2276 2276                      KMF_DIRPATH_ATTR, dirpath, strlen(dirpath));
2277 2277                  i++;
2278 2278          }
2279 2279  
2280 2280          keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2281 2281          if (keyfile == NULL)
2282 2282                  return (KMF_ERR_BAD_PARAMETER);
2283 2283          else {
2284 2284                  kmf_set_attr_at_index(new_attrlist, i,
2285 2285                      KMF_KEY_FILENAME_ATTR, keyfile, strlen(keyfile));
2286 2286                  i++;
2287 2287          }
2288 2288  
2289 2289          rv = OpenSSL_FindKey(handle, i, new_attrlist);
2290 2290          return (rv);
2291 2291  }
2292 2292  
2293 2293  KMF_RETURN
2294 2294  /*ARGSUSED*/
2295 2295  OpenSSL_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
2296 2296          KMF_OID *AlgOID, KMF_DATA *ciphertext,
2297 2297          KMF_DATA *output)
2298 2298  {
2299 2299          KMF_RETURN              ret = KMF_OK;
2300 2300          RSA *rsa = NULL;
2301 2301          unsigned int in_len = 0, out_len = 0;
2302 2302          unsigned int total_decrypted = 0, modulus_len = 0;
2303 2303          uint8_t *in_data, *out_data;
2304 2304          int i, blocks;
2305 2305  
2306 2306          if (key == NULL || AlgOID == NULL ||
2307 2307              ciphertext == NULL || output == NULL ||
2308 2308              ciphertext->Data == NULL ||
2309 2309              output->Data == NULL)
2310 2310                  return (KMF_ERR_BAD_PARAMETER);
2311 2311  
2312 2312          if (key->keyalg == KMF_RSA) {
2313 2313                  rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)key->keyp);
2314 2314                  modulus_len = RSA_size(rsa);
2315 2315          } else {
2316 2316                  return (KMF_ERR_BAD_PARAMETER);
2317 2317          }
2318 2318  
2319 2319          blocks = ciphertext->Length/modulus_len;
2320 2320          out_data = output->Data;
2321 2321          in_data = ciphertext->Data;
2322 2322          out_len = modulus_len - 11;
2323 2323          in_len = modulus_len;
2324 2324  
2325 2325          for (i = 0; i < blocks; i++) {
2326 2326                  out_len  = RSA_private_decrypt(in_len,
2327 2327                      in_data, out_data, rsa, RSA_PKCS1_PADDING);
2328 2328  
2329 2329                  if (out_len == 0) {
2330 2330                          ret = KMF_ERR_INTERNAL;
2331 2331                          goto cleanup;
2332 2332                  }
2333 2333  
2334 2334                  out_data += out_len;
2335 2335                  total_decrypted += out_len;
2336 2336                  in_data += in_len;
2337 2337          }
2338 2338  
2339 2339          output->Length = total_decrypted;
2340 2340  
2341 2341  cleanup:
2342 2342          RSA_free(rsa);
2343 2343          if (ret != KMF_OK)
2344 2344                  output->Length = 0;
2345 2345  
2346 2346          return (ret);
2347 2347  
2348 2348  }
2349 2349  
2350 2350  /*
2351 2351   *  This function will create a certid from issuer_cert and user_cert.
2352 2352   *  The caller should use OCSP_CERTID_free(OCSP_CERTID *) to deallocate
2353 2353   *  certid memory after use.
2354 2354   */
2355 2355  static KMF_RETURN
2356 2356  create_certid(KMF_HANDLE_T handle, const KMF_DATA *issuer_cert,
2357 2357      const KMF_DATA *user_cert, OCSP_CERTID **certid)
2358 2358  {
2359 2359          KMF_RETURN ret = KMF_OK;
2360 2360          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2361 2361          X509   *issuer = NULL;
2362 2362          X509   *cert = NULL;
2363 2363          unsigned char *ptmp;
2364 2364  
2365 2365          if (issuer_cert == NULL || user_cert == NULL) {
2366 2366                  return (KMF_ERR_BAD_PARAMETER);
2367 2367          }
2368 2368  
2369 2369          /* convert the DER-encoded issuer cert to an internal X509 */
2370 2370          ptmp = issuer_cert->Data;
2371 2371          issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2372 2372              issuer_cert->Length);
2373 2373          if (issuer == NULL) {
2374 2374                  SET_ERROR(kmfh, ERR_get_error());
2375 2375                  ret = KMF_ERR_OCSP_BAD_ISSUER;
2376 2376                  goto end;
2377 2377          }
2378 2378  
2379 2379          /* convert the DER-encoded user cert to an internal X509 */
2380 2380          ptmp = user_cert->Data;
2381 2381          cert = d2i_X509(NULL, (const uchar_t **)&ptmp,
2382 2382              user_cert->Length);
2383 2383          if (cert == NULL) {
2384 2384                  SET_ERROR(kmfh, ERR_get_error());
2385 2385  
2386 2386                  ret = KMF_ERR_OCSP_BAD_CERT;
2387 2387                  goto end;
2388 2388          }
2389 2389  
2390 2390          /* create a CERTID */
2391 2391          *certid = OCSP_cert_to_id(NULL, cert, issuer);
2392 2392          if (*certid == NULL) {
2393 2393                  SET_ERROR(kmfh, ERR_get_error());
2394 2394                  ret = KMF_ERR_OCSP_CERTID;
2395 2395                  goto end;
2396 2396          }
2397 2397  
2398 2398  end:
2399 2399          if (issuer != NULL) {
2400 2400                  X509_free(issuer);
2401 2401          }
2402 2402  
2403 2403          if (cert != NULL) {
2404 2404                  X509_free(cert);
2405 2405          }
2406 2406  
2407 2407          return (ret);
2408 2408  }
2409 2409  
2410 2410  KMF_RETURN
2411 2411  OpenSSL_CreateOCSPRequest(KMF_HANDLE_T handle,
2412 2412          int numattr, KMF_ATTRIBUTE *attrlist)
2413 2413  {
2414 2414          KMF_RETURN ret = KMF_OK;
2415 2415          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2416 2416          OCSP_CERTID *id = NULL;
2417 2417          OCSP_REQUEST *req = NULL;
2418 2418          BIO *derbio = NULL;
2419 2419          char *reqfile;
2420 2420          KMF_DATA *issuer_cert;
2421 2421          KMF_DATA *user_cert;
2422 2422  
2423 2423          user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2424 2424              attrlist, numattr);
2425 2425          if (user_cert == NULL)
2426 2426                  return (KMF_ERR_BAD_PARAMETER);
2427 2427  
2428 2428          issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2429 2429              attrlist, numattr);
2430 2430          if (issuer_cert == NULL)
2431 2431                  return (KMF_ERR_BAD_PARAMETER);
2432 2432  
2433 2433          reqfile = kmf_get_attr_ptr(KMF_OCSP_REQUEST_FILENAME_ATTR,
2434 2434              attrlist, numattr);
2435 2435          if (reqfile == NULL)
2436 2436                  return (KMF_ERR_BAD_PARAMETER);
2437 2437  
2438 2438          ret = create_certid(handle, issuer_cert, user_cert, &id);
2439 2439          if (ret != KMF_OK) {
2440 2440                  return (ret);
2441 2441          }
2442 2442  
2443 2443          /* Create an OCSP request */
2444 2444          req = OCSP_REQUEST_new();
2445 2445          if (req == NULL) {
2446 2446                  SET_ERROR(kmfh, ERR_get_error());
2447 2447                  ret = KMF_ERR_OCSP_CREATE_REQUEST;
2448 2448                  goto end;
2449 2449          }
2450 2450  
2451 2451          if (!OCSP_request_add0_id(req, id)) {
2452 2452                  ret = KMF_ERR_OCSP_CREATE_REQUEST;
2453 2453                  goto end;
2454 2454          }
2455 2455  
2456 2456          /* Write the request to the output file with DER encoding */
2457 2457          derbio = BIO_new_file(reqfile, "wb");
2458 2458          if (!derbio) {
2459 2459                  SET_ERROR(kmfh, ERR_get_error());
2460 2460                  ret = KMF_ERR_OPEN_FILE;
2461 2461                  goto end;
2462 2462          }
2463 2463          if (i2d_OCSP_REQUEST_bio(derbio, req) <= 0) {
2464 2464                  ret = KMF_ERR_ENCODING;
2465 2465          }
2466 2466  
2467 2467  end:
2468 2468          /*
2469 2469           * We don't need to free "id" explicitely, because OCSP_REQUEST_free()
2470 2470           * will also deallocate certid's space.
2471 2471           */
2472 2472          if (req != NULL) {
2473 2473                  OCSP_REQUEST_free(req);
2474 2474          }
2475 2475  
2476 2476          if (derbio != NULL) {
2477 2477                  (void) BIO_free(derbio);
2478 2478          }
2479 2479  
2480 2480          return (ret);
2481 2481  }
2482 2482  
2483 2483  /* ocsp_find_signer_sk() is copied from openssl source */
2484 2484  static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id)
2485 2485  {
2486 2486          int i;
2487 2487          unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash;
2488 2488  
2489 2489          /* Easy if lookup by name */
2490 2490          if (id->type == V_OCSP_RESPID_NAME)
2491 2491                  return (X509_find_by_subject(certs, id->value.byName));
2492 2492  
2493 2493          /* Lookup by key hash */
2494 2494  
2495 2495          /* If key hash isn't SHA1 length then forget it */
2496 2496          if (id->value.byKey->length != SHA_DIGEST_LENGTH)
2497 2497                  return (NULL);
2498 2498  
2499 2499          keyhash = id->value.byKey->data;
2500 2500          /* Calculate hash of each key and compare */
2501 2501          for (i = 0; i < sk_X509_num(certs); i++) {
2502 2502                  /* LINTED E_BAD_PTR_CAST_ALIGN */
2503 2503                  X509 *x = sk_X509_value(certs, i);
2504 2504                  /* Use pubkey_digest to get the key ID value */
2505 2505                  (void) X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL);
2506 2506                  if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH))
2507 2507                          return (x);
2508 2508          }
2509 2509          return (NULL);
2510 2510  }
2511 2511  
2512 2512  /* ocsp_find_signer() is copied from openssl source */
2513 2513  /* ARGSUSED2 */
2514 2514  static int
2515 2515  ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, STACK_OF(X509) *certs,
2516 2516      X509_STORE *st, unsigned long flags)
2517 2517  {
2518 2518          X509 *signer;
2519 2519          OCSP_RESPID *rid = bs->tbsResponseData->responderId;
2520 2520          if ((signer = ocsp_find_signer_sk(certs, rid))) {
2521 2521                  *psigner = signer;
2522 2522                  return (2);
2523 2523          }
2524 2524          if (!(flags & OCSP_NOINTERN) &&
2525 2525              (signer = ocsp_find_signer_sk(bs->certs, rid))) {
2526 2526                  *psigner = signer;
2527 2527                  return (1);
2528 2528          }
2529 2529          /* Maybe lookup from store if by subject name */
2530 2530  
2531 2531          *psigner = NULL;
2532 2532          return (0);
2533 2533  }
2534 2534  
2535 2535  /*
2536 2536   * This function will verify the signature of a basic response, using
2537 2537   * the public key from the OCSP responder certificate.
2538 2538   */
2539 2539  static KMF_RETURN
2540 2540  check_response_signature(KMF_HANDLE_T handle, OCSP_BASICRESP *bs,
2541 2541      KMF_DATA *signer_cert, KMF_DATA *issuer_cert)
2542 2542  {
2543 2543          KMF_RETURN ret = KMF_OK;
2544 2544          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2545 2545          STACK_OF(X509) *cert_stack = NULL;
2546 2546          X509 *signer = NULL;
2547 2547          X509 *issuer = NULL;
2548 2548          EVP_PKEY *skey = NULL;
2549 2549          unsigned char *ptmp;
2550 2550  
2551 2551  
2552 2552          if (bs == NULL || issuer_cert == NULL)
2553 2553                  return (KMF_ERR_BAD_PARAMETER);
2554 2554  
2555 2555          /*
2556 2556           * Find the certificate that signed the basic response.
2557 2557           *
2558 2558           * If signer_cert is not NULL, we will use that as the signer cert.
2559 2559           * Otherwise, we will check if the issuer cert is actually the signer.
2560 2560           * If we still do not find a signer, we will look for it from the
2561 2561           * certificate list came with the response file.
2562 2562           */
2563 2563          if (signer_cert != NULL) {
2564 2564                  ptmp = signer_cert->Data;
2565 2565                  signer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2566 2566                      signer_cert->Length);
2567 2567                  if (signer == NULL) {
2568 2568                          SET_ERROR(kmfh, ERR_get_error());
2569 2569                          ret = KMF_ERR_OCSP_BAD_SIGNER;
2570 2570                          goto end;
2571 2571                  }
2572 2572          } else {
2573 2573                  /*
2574 2574                   * Convert the issuer cert into X509 and push it into a
2575 2575                   * stack to be used by ocsp_find_signer().
2576 2576                   */
2577 2577                  ptmp = issuer_cert->Data;
2578 2578                  issuer = d2i_X509(NULL, (const uchar_t **)&ptmp,
2579 2579                      issuer_cert->Length);
2580 2580                  if (issuer == NULL) {
2581 2581                          SET_ERROR(kmfh, ERR_get_error());
2582 2582                          ret = KMF_ERR_OCSP_BAD_ISSUER;
2583 2583                          goto end;
2584 2584                  }
2585 2585  
2586 2586                  if ((cert_stack = sk_X509_new_null()) == NULL) {
2587 2587                          ret = KMF_ERR_INTERNAL;
2588 2588                          goto end;
2589 2589                  }
2590 2590  
2591 2591                  if (sk_X509_push(cert_stack, issuer) == NULL) {
2592 2592                          ret = KMF_ERR_INTERNAL;
2593 2593                          goto end;
2594 2594                  }
2595 2595  
2596 2596                  ret = ocsp_find_signer(&signer, bs, cert_stack, NULL, 0);
2597 2597                  if (!ret) {
2598 2598                          /* can not find the signer */
2599 2599                          ret = KMF_ERR_OCSP_BAD_SIGNER;
2600 2600                          goto end;
2601 2601                  }
2602 2602          }
2603 2603  
2604 2604          /* Verify the signature of the response */
2605 2605          skey = X509_get_pubkey(signer);
2606 2606          if (skey == NULL) {
2607 2607                  ret = KMF_ERR_OCSP_BAD_SIGNER;
2608 2608                  goto end;
2609 2609          }
2610 2610  
2611 2611          ret = OCSP_BASICRESP_verify(bs, skey, 0);
2612 2612          if (ret == 0) {
2613 2613                  ret = KMF_ERR_OCSP_RESPONSE_SIGNATURE;
2614 2614                  goto end;
2615 2615          }
2616 2616  
2617 2617  end:
2618 2618          if (issuer != NULL) {
2619 2619                  X509_free(issuer);
2620 2620          }
2621 2621  
2622 2622          if (signer != NULL) {
2623 2623                  X509_free(signer);
2624 2624          }
2625 2625  
2626 2626          if (skey != NULL) {
2627 2627                  EVP_PKEY_free(skey);
2628 2628          }
2629 2629  
2630 2630          if (cert_stack != NULL) {
2631 2631                  sk_X509_free(cert_stack);
2632 2632          }
2633 2633  
2634 2634          return (ret);
2635 2635  }
2636 2636  
2637 2637  
2638 2638  
2639 2639  KMF_RETURN
2640 2640  OpenSSL_GetOCSPStatusForCert(KMF_HANDLE_T handle,
2641 2641          int numattr, KMF_ATTRIBUTE *attrlist)
2642 2642  {
2643 2643          KMF_RETURN ret = KMF_OK;
2644 2644          BIO *derbio = NULL;
2645 2645          OCSP_RESPONSE *resp = NULL;
2646 2646          OCSP_BASICRESP *bs = NULL;
2647 2647          OCSP_CERTID *id = NULL;
2648 2648          OCSP_SINGLERESP *single = NULL;
2649 2649          ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
2650 2650          int index, status, reason;
2651 2651          KMF_DATA *issuer_cert;
2652 2652          KMF_DATA *user_cert;
2653 2653          KMF_DATA *signer_cert;
2654 2654          KMF_DATA *response;
2655 2655          int *response_reason, *response_status, *cert_status;
2656 2656          boolean_t ignore_response_sign = B_FALSE;       /* default is FALSE */
2657 2657          uint32_t response_lifetime;
2658 2658  
2659 2659          issuer_cert = kmf_get_attr_ptr(KMF_ISSUER_CERT_DATA_ATTR,
2660 2660              attrlist, numattr);
2661 2661          if (issuer_cert == NULL)
2662 2662                  return (KMF_ERR_BAD_PARAMETER);
2663 2663  
2664 2664          user_cert = kmf_get_attr_ptr(KMF_USER_CERT_DATA_ATTR,
2665 2665              attrlist, numattr);
2666 2666          if (user_cert == NULL)
2667 2667                  return (KMF_ERR_BAD_PARAMETER);
2668 2668  
2669 2669          response = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_DATA_ATTR,
2670 2670              attrlist, numattr);
2671 2671          if (response == NULL)
2672 2672                  return (KMF_ERR_BAD_PARAMETER);
2673 2673  
2674 2674          response_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_STATUS_ATTR,
2675 2675              attrlist, numattr);
2676 2676          if (response_status == NULL)
2677 2677                  return (KMF_ERR_BAD_PARAMETER);
2678 2678  
2679 2679          response_reason = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_REASON_ATTR,
2680 2680              attrlist, numattr);
2681 2681          if (response_reason == NULL)
2682 2682                  return (KMF_ERR_BAD_PARAMETER);
2683 2683  
2684 2684          cert_status = kmf_get_attr_ptr(KMF_OCSP_RESPONSE_CERT_STATUS_ATTR,
2685 2685              attrlist, numattr);
2686 2686          if (cert_status == NULL)
2687 2687                  return (KMF_ERR_BAD_PARAMETER);
2688 2688  
2689 2689          /* Read in the response */
2690 2690          derbio = BIO_new_mem_buf(response->Data, response->Length);
2691 2691          if (!derbio) {
2692 2692                  ret = KMF_ERR_MEMORY;
2693 2693                  return (ret);
2694 2694          }
2695 2695  
2696 2696          resp = d2i_OCSP_RESPONSE_bio(derbio, NULL);
2697 2697          if (resp == NULL) {
2698 2698                  ret = KMF_ERR_OCSP_MALFORMED_RESPONSE;
2699 2699                  goto end;
2700 2700          }
2701 2701  
2702 2702          /* Check the response status */
2703 2703          status = OCSP_response_status(resp);
2704 2704          *response_status = status;
2705 2705          if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
2706 2706                  ret = KMF_ERR_OCSP_RESPONSE_STATUS;
2707 2707                  goto end;
2708 2708          }
2709 2709  
2710 2710  #ifdef DEBUG
2711 2711          printf("Successfully checked the response file status.\n");
2712 2712  #endif /* DEBUG */
2713 2713  
2714 2714          /* Extract basic response */
2715 2715          bs = OCSP_response_get1_basic(resp);
2716 2716          if (bs == NULL) {
2717 2717                  ret = KMF_ERR_OCSP_NO_BASIC_RESPONSE;
2718 2718                  goto end;
2719 2719          }
2720 2720  
2721 2721  #ifdef DEBUG
2722 2722          printf("Successfully retrieved the basic response.\n");
2723 2723  #endif /* DEBUG */
2724 2724  
2725 2725          /* Check the basic response signature if required */
2726 2726          ret = kmf_get_attr(KMF_IGNORE_RESPONSE_SIGN_ATTR, attrlist, numattr,
2727 2727              (void *)&ignore_response_sign, NULL);
2728 2728          if (ret != KMF_OK)
2729 2729                  ret = KMF_OK;
2730 2730  
2731 2731          signer_cert = kmf_get_attr_ptr(KMF_SIGNER_CERT_DATA_ATTR,
2732 2732              attrlist, numattr);
2733 2733  
2734 2734          if (ignore_response_sign == B_FALSE) {
2735 2735                  ret = check_response_signature(handle, bs,
2736 2736                      signer_cert, issuer_cert);
2737 2737                  if (ret != KMF_OK)
2738 2738                          goto end;
2739 2739          }
2740 2740  
2741 2741  #ifdef DEBUG
2742 2742          printf("Successfully verified the response signature.\n");
2743 2743  #endif /* DEBUG */
2744 2744  
2745 2745          /* Create a certid for the certificate in question */
2746 2746          ret = create_certid(handle, issuer_cert, user_cert, &id);
2747 2747          if (ret != KMF_OK) {
2748 2748                  ret = KMF_ERR_OCSP_CERTID;
2749 2749                  goto end;
2750 2750          }
2751 2751  
2752 2752  #ifdef DEBUG
2753 2753          printf("successfully created a certid for the cert.\n");
2754 2754  #endif /* DEBUG */
2755 2755  
2756 2756          /* Find the index of the single response for the certid */
2757 2757          index = OCSP_resp_find(bs, id, -1);
2758 2758          if (index < 0) {
2759 2759                  /* cound not find this certificate in the response */
2760 2760                  ret = KMF_ERR_OCSP_UNKNOWN_CERT;
2761 2761                  goto end;
2762 2762          }
2763 2763  
2764 2764  #ifdef DEBUG
2765 2765          printf("Successfully found the single response index for the cert.\n");
2766 2766  #endif /* DEBUG */
2767 2767  
2768 2768          /* Retrieve the single response and get the cert status */
2769 2769          single = OCSP_resp_get0(bs, index);
2770 2770          status = OCSP_single_get0_status(single, &reason, &rev, &thisupd,
2771 2771              &nextupd);
2772 2772          if (status == V_OCSP_CERTSTATUS_GOOD) {
2773 2773                  *cert_status = OCSP_GOOD;
2774 2774          } else if (status == V_OCSP_CERTSTATUS_UNKNOWN) {
2775 2775                  *cert_status = OCSP_UNKNOWN;
2776 2776          } else { /* revoked */
2777 2777                  *cert_status = OCSP_REVOKED;
2778 2778                  *response_reason = reason;
2779 2779          }
2780 2780          ret = KMF_OK;
2781 2781  
2782 2782          /* resp. time is optional, so we don't care about the return code. */
2783 2783          (void) kmf_get_attr(KMF_RESPONSE_LIFETIME_ATTR, attrlist, numattr,
2784 2784              (void *)&response_lifetime, NULL);
2785 2785  
2786 2786          if (!OCSP_check_validity(thisupd, nextupd, 300,
2787 2787              response_lifetime)) {
2788 2788                  ret = KMF_ERR_OCSP_STATUS_TIME_INVALID;
2789 2789                  goto end;
2790 2790          }
2791 2791  
2792 2792  #ifdef DEBUG
2793 2793          printf("Successfully verify the time.\n");
2794 2794  #endif /* DEBUG */
2795 2795  
2796 2796  end:
2797 2797          if (derbio != NULL)
2798 2798                  (void) BIO_free(derbio);
2799 2799  
2800 2800          if (resp != NULL)
2801 2801                  OCSP_RESPONSE_free(resp);
2802 2802  
2803 2803          if (bs != NULL)
2804 2804                  OCSP_BASICRESP_free(bs);
2805 2805  
2806 2806          if (id != NULL)
2807 2807                  OCSP_CERTID_free(id);
2808 2808  
2809 2809          return (ret);
2810 2810  }
2811 2811  
2812 2812  static KMF_RETURN
2813 2813  fetch_key(KMF_HANDLE_T handle, char *path,
2814 2814          KMF_KEY_CLASS keyclass, KMF_KEY_HANDLE *key)
2815 2815  {
2816 2816          KMF_RETURN rv = KMF_OK;
2817 2817          EVP_PKEY *pkey = NULL;
2818 2818          KMF_RAW_SYM_KEY *rkey = NULL;
2819 2819  
2820 2820          if (keyclass == KMF_ASYM_PRI ||
2821 2821              keyclass == KMF_ASYM_PUB) {
2822 2822                  pkey = openssl_load_key(handle, path);
2823 2823                  if (pkey == NULL) {
2824 2824                          return (KMF_ERR_KEY_NOT_FOUND);
2825 2825                  }
2826 2826                  if (key != NULL) {
2827 2827                          if (pkey->type == EVP_PKEY_RSA)
2828 2828                                  key->keyalg = KMF_RSA;
2829 2829                          else if (pkey->type == EVP_PKEY_DSA)
2830 2830                                  key->keyalg = KMF_DSA;
2831 2831  
2832 2832                          key->kstype = KMF_KEYSTORE_OPENSSL;
2833 2833                          key->keyclass = keyclass;
2834 2834                          key->keyp = (void *)pkey;
2835 2835                          key->israw = FALSE;
2836 2836                          if (path != NULL &&
2837 2837                              ((key->keylabel = strdup(path)) == NULL)) {
2838 2838                                  EVP_PKEY_free(pkey);
2839 2839                                  return (KMF_ERR_MEMORY);
2840 2840                          }
2841 2841                  } else {
2842 2842                          EVP_PKEY_free(pkey);
2843 2843                          pkey = NULL;
2844 2844                  }
2845 2845          } else if (keyclass == KMF_SYMMETRIC) {
2846 2846                  KMF_ENCODE_FORMAT fmt;
2847 2847                  /*
2848 2848                   * If the file is a recognized format,
2849 2849                   * then it is NOT a symmetric key.
2850 2850                   */
2851 2851                  rv = kmf_get_file_format(path, &fmt);
2852 2852                  if (rv == KMF_OK || fmt != 0) {
2853 2853                          return (KMF_ERR_KEY_NOT_FOUND);
2854 2854                  } else if (rv == KMF_ERR_ENCODING) {
2855 2855                          /*
2856 2856                           * If we don't know the encoding,
2857 2857                           * it is probably  a symmetric key.
2858 2858                           */
2859 2859                          rv = KMF_OK;
2860 2860                  } else if (rv == KMF_ERR_OPEN_FILE) {
2861 2861                          return (KMF_ERR_KEY_NOT_FOUND);
2862 2862                  }
2863 2863  
2864 2864                  if (key != NULL) {
2865 2865                          KMF_DATA keyvalue;
2866 2866                          rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
2867 2867                          if (rkey == NULL) {
2868 2868                                  rv = KMF_ERR_MEMORY;
2869 2869                                  goto out;
2870 2870                          }
2871 2871  
2872 2872                          (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
2873 2873                          rv = kmf_read_input_file(handle, path, &keyvalue);
2874 2874                          if (rv != KMF_OK)
2875 2875                                  goto out;
2876 2876  
2877 2877                          rkey->keydata.len = keyvalue.Length;
2878 2878                          rkey->keydata.val = keyvalue.Data;
2879 2879  
2880 2880                          key->kstype = KMF_KEYSTORE_OPENSSL;
2881 2881                          key->keyclass = keyclass;
2882 2882                          key->israw = TRUE;
2883 2883                          key->keyp = (void *)rkey;
2884 2884                          if (path != NULL &&
2885 2885                              ((key->keylabel = strdup(path)) == NULL)) {
2886 2886                                  rv = KMF_ERR_MEMORY;
2887 2887                          }
2888 2888                  }
2889 2889          }
2890 2890  out:
2891 2891          if (rv != KMF_OK) {
2892 2892                  if (rkey != NULL) {
2893 2893                          kmf_free_raw_sym_key(rkey);
2894 2894                  }
2895 2895                  if (pkey != NULL)
2896 2896                          EVP_PKEY_free(pkey);
2897 2897  
2898 2898                  if (key != NULL) {
2899 2899                          key->keyalg = KMF_KEYALG_NONE;
2900 2900                          key->keyclass = KMF_KEYCLASS_NONE;
2901 2901                          key->keyp = NULL;
2902 2902                  }
2903 2903          }
2904 2904  
2905 2905          return (rv);
2906 2906  }
2907 2907  
2908 2908  KMF_RETURN
2909 2909  OpenSSL_FindKey(KMF_HANDLE_T handle,
2910 2910          int numattr, KMF_ATTRIBUTE *attrlist)
2911 2911  {
2912 2912          KMF_RETURN rv = KMF_OK;
2913 2913          char *fullpath = NULL;
2914 2914          uint32_t maxkeys;
2915 2915          KMF_KEY_HANDLE *key;
2916 2916          uint32_t *numkeys;
2917 2917          KMF_KEY_CLASS keyclass;
2918 2918          KMF_RAW_KEY_DATA *rawkey;
2919 2919          char *dirpath;
2920 2920          char *keyfile;
2921 2921  
2922 2922          if (handle == NULL)
2923 2923                  return (KMF_ERR_BAD_PARAMETER);
2924 2924  
2925 2925          numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
2926 2926          if (numkeys == NULL)
2927 2927                  return (KMF_ERR_BAD_PARAMETER);
2928 2928  
2929 2929          rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
2930 2930              (void *)&keyclass, NULL);
2931 2931          if (rv != KMF_OK)
2932 2932                  return (KMF_ERR_BAD_PARAMETER);
2933 2933  
2934 2934          if (keyclass != KMF_ASYM_PUB &&
2935 2935              keyclass != KMF_ASYM_PRI &&
2936 2936              keyclass != KMF_SYMMETRIC)
2937 2937                  return (KMF_ERR_BAD_KEY_CLASS);
2938 2938  
2939 2939          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2940 2940          keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
2941 2941  
2942 2942          fullpath = get_fullpath(dirpath, keyfile);
2943 2943  
2944 2944          if (fullpath == NULL)
2945 2945                  return (KMF_ERR_BAD_PARAMETER);
2946 2946  
2947 2947          maxkeys = *numkeys;
2948 2948          if (maxkeys == 0)
2949 2949                  maxkeys = 0xFFFFFFFF;
2950 2950          *numkeys = 0;
2951 2951  
2952 2952          key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
2953 2953          /* it is okay to have "keys" contains NULL */
2954 2954  
2955 2955          /*
2956 2956           * The caller may want a list of the raw key data as well.
2957 2957           * Useful for importing keys from a file into other keystores.
2958 2958           */
2959 2959          rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
2960 2960  
2961 2961          if (isdir(fullpath)) {
2962 2962                  DIR *dirp;
2963 2963                  struct dirent *dp;
2964 2964                  int n = 0;
2965 2965  
2966 2966                  /* open all files in the directory and attempt to read them */
2967 2967                  if ((dirp = opendir(fullpath)) == NULL) {
2968 2968                          return (KMF_ERR_BAD_PARAMETER);
2969 2969                  }
2970 2970                  rewinddir(dirp);
2971 2971                  while ((dp = readdir(dirp)) != NULL && n < maxkeys) {
2972 2972                          if (strcmp(dp->d_name, ".") &&
2973 2973                              strcmp(dp->d_name, "..")) {
2974 2974                                  char *fname;
2975 2975  
2976 2976                                  fname = get_fullpath(fullpath,
2977 2977                                      (char *)&dp->d_name);
2978 2978  
2979 2979                                  rv = fetch_key(handle, fname,
2980 2980                                      keyclass, key ? &key[n] : NULL);
2981 2981  
2982 2982                                  if (rv == KMF_OK) {
2983 2983                                          if (key != NULL && rawkey != NULL)
2984 2984                                                  rv = convertToRawKey(
2985 2985                                                      key[n].keyp, &rawkey[n]);
2986 2986                                          n++;
2987 2987                                  }
2988 2988  
2989 2989                                  if (rv != KMF_OK || key == NULL)
2990 2990                                          free(fname);
2991 2991                          }
2992 2992                  }
2993 2993                  (void) closedir(dirp);
2994 2994                  free(fullpath);
2995 2995                  (*numkeys) = n;
2996 2996          } else {
2997 2997                  rv = fetch_key(handle, fullpath, keyclass, key);
2998 2998                  if (rv == KMF_OK)
2999 2999                          (*numkeys) = 1;
3000 3000  
3001 3001                  if (rv != KMF_OK || key == NULL)
3002 3002                          free(fullpath);
3003 3003  
3004 3004                  if (rv == KMF_OK && key != NULL && rawkey != NULL) {
3005 3005                          rv = convertToRawKey(key->keyp, rawkey);
3006 3006                  }
3007 3007          }
3008 3008  
3009 3009          if (rv == KMF_OK && (*numkeys) == 0)
3010 3010                  rv = KMF_ERR_KEY_NOT_FOUND;
3011 3011          else if (rv == KMF_ERR_KEY_NOT_FOUND && (*numkeys) > 0)
3012 3012                  rv = KMF_OK;
3013 3013  
3014 3014          return (rv);
3015 3015  }
3016 3016  
3017 3017  #define HANDLE_PK12_ERROR { \
3018 3018          SET_ERROR(kmfh, ERR_get_error()); \
3019 3019          rv = KMF_ERR_ENCODING; \
3020 3020          goto out; \
3021 3021  }
3022 3022  
3023 3023  static int
3024 3024  add_alias_to_bag(PKCS12_SAFEBAG *bag, X509 *xcert)
3025 3025  {
3026 3026          if (xcert != NULL && xcert->aux != NULL &&
3027 3027              xcert->aux->alias != NULL) {
3028 3028                  if (PKCS12_add_friendlyname_asc(bag,
3029 3029                      (const char *)xcert->aux->alias->data,
3030 3030                      xcert->aux->alias->length) == 0)
3031 3031                          return (0);
3032 3032          }
3033 3033          return (1);
3034 3034  }
3035 3035  
3036 3036  static PKCS7 *
3037 3037  add_cert_to_safe(X509 *sslcert, KMF_CREDENTIAL *cred,
3038 3038          uchar_t *keyid, unsigned int keyidlen)
3039 3039  {
3040 3040          PKCS12_SAFEBAG *bag = NULL;
3041 3041          PKCS7 *cert_authsafe = NULL;
3042 3042          STACK_OF(PKCS12_SAFEBAG) *bag_stack;
3043 3043  
3044 3044          bag_stack = sk_PKCS12_SAFEBAG_new_null();
3045 3045          if (bag_stack == NULL)
3046 3046                  return (NULL);
3047 3047  
3048 3048          /* Convert cert from X509 struct to PKCS#12 bag */
3049 3049          bag = PKCS12_x5092certbag(sslcert);
3050 3050          if (bag == NULL) {
3051 3051                  goto out;
3052 3052          }
3053 3053  
3054 3054          /* Add the key id to the certificate bag. */
3055 3055          if (keyidlen > 0 && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) {
3056 3056                  goto out;
3057 3057          }
3058 3058  
3059 3059          if (!add_alias_to_bag(bag, sslcert))
3060 3060                  goto out;
3061 3061  
3062 3062          /* Pile it on the bag_stack. */
3063 3063          if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag)) {
3064 3064                  goto out;
3065 3065          }
3066 3066          /* Turn bag_stack of certs into encrypted authsafe. */
3067 3067          cert_authsafe = PKCS12_pack_p7encdata(
3068 3068              NID_pbe_WithSHA1And40BitRC2_CBC,
3069 3069              cred->cred, cred->credlen, NULL, 0,
3070 3070              PKCS12_DEFAULT_ITER, bag_stack);
3071 3071  
3072 3072  out:
3073 3073          if (bag_stack != NULL)
3074 3074                  sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3075 3075  
3076 3076          return (cert_authsafe);
3077 3077  }
3078 3078  
3079 3079  static PKCS7 *
3080 3080  add_key_to_safe(EVP_PKEY *pkey, KMF_CREDENTIAL *cred,
3081 3081          uchar_t *keyid,  unsigned int keyidlen,
3082 3082          char *label, int label_len)
3083 3083  {
3084 3084          PKCS8_PRIV_KEY_INFO *p8 = NULL;
3085 3085          STACK_OF(PKCS12_SAFEBAG) *bag_stack = NULL;
3086 3086          PKCS12_SAFEBAG *bag = NULL;
3087 3087          PKCS7 *key_authsafe = NULL;
3088 3088  
3089 3089          p8 = EVP_PKEY2PKCS8(pkey);
3090 3090          if (p8 == NULL) {
3091 3091                  return (NULL);
3092 3092          }
3093 3093          /* Put the shrouded key into a PKCS#12 bag. */
3094 3094          bag = PKCS12_MAKE_SHKEYBAG(
3095 3095              NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
3096 3096              cred->cred, cred->credlen,
3097 3097              NULL, 0, PKCS12_DEFAULT_ITER, p8);
3098 3098  
3099 3099          /* Clean up the PKCS#8 shrouded key, don't need it now. */
3100 3100          PKCS8_PRIV_KEY_INFO_free(p8);
3101 3101          p8 = NULL;
3102 3102  
3103 3103          if (bag == NULL) {
3104 3104                  return (NULL);
3105 3105          }
3106 3106          if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen))
3107 3107                  goto out;
3108 3108          if (label != NULL && !PKCS12_add_friendlyname(bag, label, label_len))
3109 3109                  goto out;
3110 3110  
3111 3111          /* Start a PKCS#12 safebag container for the private key. */
3112 3112          bag_stack = sk_PKCS12_SAFEBAG_new_null();
3113 3113          if (bag_stack == NULL)
3114 3114                  goto out;
3115 3115  
3116 3116          /* Pile on the private key on the bag_stack. */
3117 3117          if (!sk_PKCS12_SAFEBAG_push(bag_stack, bag))
3118 3118                  goto out;
3119 3119  
3120 3120          key_authsafe = PKCS12_pack_p7data(bag_stack);
3121 3121  
3122 3122  out:
3123 3123          if (bag_stack != NULL)
3124 3124                  sk_PKCS12_SAFEBAG_pop_free(bag_stack, PKCS12_SAFEBAG_free);
3125 3125          bag_stack = NULL;
3126 3126          return (key_authsafe);
3127 3127  }
3128 3128  
3129 3129  static EVP_PKEY *
3130 3130  ImportRawRSAKey(KMF_RAW_RSA_KEY *key)
3131 3131  {
3132 3132          RSA             *rsa = NULL;
3133 3133          EVP_PKEY        *newkey = NULL;
3134 3134  
3135 3135          if ((rsa = RSA_new()) == NULL)
3136 3136                  return (NULL);
3137 3137  
3138 3138          if ((rsa->n = BN_bin2bn(key->mod.val, key->mod.len, rsa->n)) == NULL)
3139 3139                  return (NULL);
3140 3140  
3141 3141          if ((rsa->e = BN_bin2bn(key->pubexp.val, key->pubexp.len, rsa->e)) ==
3142 3142              NULL)
3143 3143                  return (NULL);
3144 3144  
3145 3145          if (key->priexp.val != NULL)
3146 3146                  if ((rsa->d = BN_bin2bn(key->priexp.val, key->priexp.len,
3147 3147                      rsa->d)) == NULL)
3148 3148                          return (NULL);
3149 3149  
3150 3150          if (key->prime1.val != NULL)
3151 3151                  if ((rsa->p = BN_bin2bn(key->prime1.val, key->prime1.len,
3152 3152                      rsa->p)) == NULL)
3153 3153                          return (NULL);
3154 3154  
3155 3155          if (key->prime2.val != NULL)
3156 3156                  if ((rsa->q = BN_bin2bn(key->prime2.val, key->prime2.len,
3157 3157                      rsa->q)) == NULL)
3158 3158                          return (NULL);
3159 3159  
3160 3160          if (key->exp1.val != NULL)
3161 3161                  if ((rsa->dmp1 = BN_bin2bn(key->exp1.val, key->exp1.len,
3162 3162                      rsa->dmp1)) == NULL)
3163 3163                          return (NULL);
3164 3164  
3165 3165          if (key->exp2.val != NULL)
3166 3166                  if ((rsa->dmq1 = BN_bin2bn(key->exp2.val, key->exp2.len,
3167 3167                      rsa->dmq1)) == NULL)
3168 3168                          return (NULL);
3169 3169  
3170 3170          if (key->coef.val != NULL)
3171 3171                  if ((rsa->iqmp = BN_bin2bn(key->coef.val, key->coef.len,
3172 3172                      rsa->iqmp)) == NULL)
3173 3173                          return (NULL);
3174 3174  
3175 3175          if ((newkey = EVP_PKEY_new()) == NULL)
3176 3176                  return (NULL);
3177 3177  
3178 3178          (void) EVP_PKEY_set1_RSA(newkey, rsa);
3179 3179  
3180 3180          /* The original key must be freed once here or it leaks memory */
3181 3181          RSA_free(rsa);
3182 3182  
3183 3183          return (newkey);
3184 3184  }
3185 3185  
3186 3186  static EVP_PKEY *
3187 3187  ImportRawDSAKey(KMF_RAW_DSA_KEY *key)
3188 3188  {
3189 3189          DSA             *dsa = NULL;
3190 3190          EVP_PKEY        *newkey = NULL;
3191 3191  
3192 3192          if ((dsa = DSA_new()) == NULL)
3193 3193                  return (NULL);
3194 3194  
3195 3195          if ((dsa->p = BN_bin2bn(key->prime.val, key->prime.len,
3196 3196              dsa->p)) == NULL)
3197 3197                  return (NULL);
3198 3198  
3199 3199          if ((dsa->q = BN_bin2bn(key->subprime.val, key->subprime.len,
3200 3200              dsa->q)) == NULL)
3201 3201                  return (NULL);
3202 3202  
3203 3203          if ((dsa->g = BN_bin2bn(key->base.val, key->base.len,
3204 3204              dsa->g)) == NULL)
3205 3205                  return (NULL);
3206 3206  
3207 3207          if ((dsa->priv_key = BN_bin2bn(key->value.val, key->value.len,
3208 3208              dsa->priv_key)) == NULL)
3209 3209                  return (NULL);
3210 3210  
3211 3211          if (key->pubvalue.val != NULL) {
3212 3212                  if ((dsa->pub_key = BN_bin2bn(key->pubvalue.val,
3213 3213                      key->pubvalue.len, dsa->pub_key)) == NULL)
3214 3214                          return (NULL);
3215 3215          }
3216 3216  
3217 3217          if ((newkey = EVP_PKEY_new()) == NULL)
3218 3218                  return (NULL);
3219 3219  
3220 3220          (void) EVP_PKEY_set1_DSA(newkey, dsa);
3221 3221  
3222 3222          /* The original key must be freed once here or it leaks memory */
3223 3223          DSA_free(dsa);
3224 3224          return (newkey);
3225 3225  }
3226 3226  
3227 3227  static EVP_PKEY *
3228 3228  raw_key_to_pkey(KMF_KEY_HANDLE *key)
3229 3229  {
3230 3230          EVP_PKEY *pkey = NULL;
3231 3231          KMF_RAW_KEY_DATA *rawkey;
3232 3232          ASN1_TYPE *attr = NULL;
3233 3233          KMF_RETURN ret;
3234 3234  
3235 3235          if (key == NULL || !key->israw)
3236 3236                  return (NULL);
3237 3237  
3238 3238          rawkey = (KMF_RAW_KEY_DATA *)key->keyp;
3239 3239          if (rawkey->keytype == KMF_RSA) {
3240 3240                  pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
3241 3241          } else if (rawkey->keytype == KMF_DSA) {
3242 3242                  pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
3243 3243          } else if (rawkey->keytype == KMF_ECDSA) {
3244 3244                  /*
3245 3245                   * OpenSSL in Solaris does not support EC for
3246 3246                   * legal reasons
3247 3247                   */
3248 3248                  return (NULL);
3249 3249          } else {
3250 3250                  /* wrong kind of key */
3251 3251                  return (NULL);
3252 3252          }
3253 3253  
3254 3254          if (rawkey->label != NULL) {
3255 3255                  if ((attr = ASN1_TYPE_new()) == NULL) {
3256 3256                          EVP_PKEY_free(pkey);
3257 3257                          return (NULL);
3258 3258                  }
3259 3259                  attr->value.bmpstring = ASN1_STRING_type_new(V_ASN1_BMPSTRING);
3260 3260                  (void) ASN1_STRING_set(attr->value.bmpstring, rawkey->label,
3261 3261                      strlen(rawkey->label));
3262 3262                  attr->type = V_ASN1_BMPSTRING;
3263 3263                  attr->value.ptr = (char *)attr->value.bmpstring;
3264 3264                  ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3265 3265                  if (ret != KMF_OK) {
3266 3266                          EVP_PKEY_free(pkey);
3267 3267                          ASN1_TYPE_free(attr);
3268 3268                          return (NULL);
3269 3269                  }
3270 3270          }
3271 3271          if (rawkey->id.Data != NULL) {
3272 3272                  if ((attr = ASN1_TYPE_new()) == NULL) {
3273 3273                          EVP_PKEY_free(pkey);
3274 3274                          return (NULL);
3275 3275                  }
3276 3276                  attr->value.octet_string =
3277 3277                      ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
3278 3278                  attr->type = V_ASN1_OCTET_STRING;
3279 3279                  (void) ASN1_STRING_set(attr->value.octet_string,
3280 3280                      rawkey->id.Data, rawkey->id.Length);
3281 3281                  attr->value.ptr = (char *)attr->value.octet_string;
3282 3282                  ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3283 3283                  if (ret != KMF_OK) {
3284 3284                          EVP_PKEY_free(pkey);
3285 3285                          ASN1_TYPE_free(attr);
3286 3286                          return (NULL);
3287 3287                  }
3288 3288          }
3289 3289          return (pkey);
3290 3290  }
3291 3291  
3292 3292  /*
3293 3293   * Search a list of private keys to find one that goes with the certificate.
3294 3294   */
3295 3295  static EVP_PKEY *
3296 3296  find_matching_key(X509 *xcert, int numkeys, KMF_KEY_HANDLE *keylist)
3297 3297  {
3298 3298          int i;
3299 3299          EVP_PKEY *pkey = NULL;
3300 3300  
3301 3301          if (numkeys == 0 || keylist == NULL || xcert == NULL)
3302 3302                  return (NULL);
3303 3303          for (i = 0; i < numkeys; i++) {
3304 3304                  if (keylist[i].israw)
3305 3305                          pkey = raw_key_to_pkey(&keylist[i]);
3306 3306                  else
3307 3307                          pkey = (EVP_PKEY *)keylist[i].keyp;
3308 3308                  if (pkey != NULL) {
3309 3309                          if (X509_check_private_key(xcert, pkey)) {
3310 3310                                  return (pkey);
3311 3311                          } else {
3312 3312                                  EVP_PKEY_free(pkey);
3313 3313                                  pkey = NULL;
3314 3314                          }
3315 3315                  }
3316 3316          }
3317 3317          return (pkey);
3318 3318  }
3319 3319  
3320 3320  static KMF_RETURN
3321 3321  local_export_pk12(KMF_HANDLE_T handle,
3322 3322          KMF_CREDENTIAL *cred,
3323 3323          int numcerts, KMF_X509_DER_CERT *certlist,
3324 3324          int numkeys, KMF_KEY_HANDLE *keylist,
3325 3325          char *filename)
3326 3326  {
3327 3327          KMF_RETURN rv = KMF_OK;
3328 3328          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3329 3329          BIO *bio = NULL;
3330 3330          PKCS7 *cert_authsafe = NULL;
3331 3331          PKCS7 *key_authsafe = NULL;
3332 3332          STACK_OF(PKCS7) *authsafe_stack = NULL;
3333 3333          PKCS12 *p12_elem = NULL;
3334 3334          int i;
3335 3335  
3336 3336          if (numcerts == 0 && numkeys == 0)
3337 3337                  return (KMF_ERR_BAD_PARAMETER);
3338 3338  
3339 3339          /*
3340 3340           * Open the output file.
3341 3341           */
3342 3342          if ((bio = BIO_new_file(filename, "wb")) == NULL) {
3343 3343                  SET_ERROR(kmfh, ERR_get_error());
3344 3344                  rv = KMF_ERR_OPEN_FILE;
3345 3345                  goto cleanup;
3346 3346          }
3347 3347  
3348 3348          /* Start a PKCS#7 stack. */
3349 3349          authsafe_stack = sk_PKCS7_new_null();
3350 3350          if (authsafe_stack == NULL) {
3351 3351                  rv = KMF_ERR_MEMORY;
3352 3352                  goto cleanup;
3353 3353          }
3354 3354          if (numcerts > 0) {
3355 3355                  for (i = 0; rv == KMF_OK && i < numcerts; i++) {
3356 3356                          const uchar_t *p = certlist[i].certificate.Data;
3357 3357                          long len = certlist[i].certificate.Length;
3358 3358                          X509 *xcert = NULL;
3359 3359                          EVP_PKEY *pkey = NULL;
3360 3360                          unsigned char keyid[EVP_MAX_MD_SIZE];
3361 3361                          unsigned int keyidlen = 0;
3362 3362  
3363 3363                          xcert = d2i_X509(NULL, &p, len);
3364 3364                          if (xcert == NULL) {
3365 3365                                  SET_ERROR(kmfh, ERR_get_error());
3366 3366                                  rv = KMF_ERR_ENCODING;
3367 3367                          }
3368 3368                          if (certlist[i].kmf_private.label != NULL) {
3369 3369                                  /* Set alias attribute */
3370 3370                                  (void) X509_alias_set1(xcert,
3371 3371                                      (uchar_t *)certlist[i].kmf_private.label,
3372 3372                                      strlen(certlist[i].kmf_private.label));
3373 3373                          }
3374 3374                          /* Check if there is a key corresponding to this cert */
3375 3375                          pkey = find_matching_key(xcert, numkeys, keylist);
3376 3376  
3377 3377                          /*
3378 3378                           * If key is found, get fingerprint and create a
3379 3379                           * safebag.
3380 3380                           */
3381 3381                          if (pkey != NULL) {
3382 3382                                  (void) X509_digest(xcert, EVP_sha1(),
3383 3383                                      keyid, &keyidlen);
3384 3384                                  key_authsafe = add_key_to_safe(pkey, cred,
3385 3385                                      keyid, keyidlen,
3386 3386                                      certlist[i].kmf_private.label,
3387 3387                                      (certlist[i].kmf_private.label ?
3388 3388                                      strlen(certlist[i].kmf_private.label) : 0));
3389 3389  
3390 3390                                  if (key_authsafe == NULL) {
3391 3391                                          X509_free(xcert);
3392 3392                                          EVP_PKEY_free(pkey);
3393 3393                                          goto cleanup;
3394 3394                                  }
3395 3395                                  /* Put the key safe into the Auth Safe */
3396 3396                                  if (!sk_PKCS7_push(authsafe_stack,
3397 3397                                      key_authsafe)) {
3398 3398                                          X509_free(xcert);
3399 3399                                          EVP_PKEY_free(pkey);
3400 3400                                          goto cleanup;
3401 3401                                  }
3402 3402                          }
3403 3403  
3404 3404                          /* create a certificate safebag */
3405 3405                          cert_authsafe = add_cert_to_safe(xcert, cred, keyid,
3406 3406                              keyidlen);
3407 3407                          if (cert_authsafe == NULL) {
3408 3408                                  X509_free(xcert);
3409 3409                                  EVP_PKEY_free(pkey);
3410 3410                                  goto cleanup;
3411 3411                          }
3412 3412                          if (!sk_PKCS7_push(authsafe_stack, cert_authsafe)) {
3413 3413                                  X509_free(xcert);
3414 3414                                  EVP_PKEY_free(pkey);
3415 3415                                  goto cleanup;
3416 3416                          }
3417 3417  
3418 3418                          X509_free(xcert);
3419 3419                          if (pkey)
3420 3420                                  EVP_PKEY_free(pkey);
3421 3421                  }
3422 3422          } else if (numcerts == 0 && numkeys > 0) {
3423 3423                  /*
3424 3424                   * If only adding keys to the file.
3425 3425                   */
3426 3426                  for (i = 0; i < numkeys; i++) {
3427 3427                          EVP_PKEY *pkey = NULL;
3428 3428  
3429 3429                          if (keylist[i].israw)
3430 3430                                  pkey = raw_key_to_pkey(&keylist[i]);
3431 3431                          else
3432 3432                                  pkey = (EVP_PKEY *)keylist[i].keyp;
3433 3433  
3434 3434                          if (pkey == NULL)
3435 3435                                  continue;
3436 3436  
3437 3437                          key_authsafe = add_key_to_safe(pkey, cred,
3438 3438                              NULL, 0, NULL, 0);
3439 3439  
3440 3440                          if (key_authsafe == NULL) {
3441 3441                                  EVP_PKEY_free(pkey);
3442 3442                                  goto cleanup;
3443 3443                          }
3444 3444                          if (!sk_PKCS7_push(authsafe_stack, key_authsafe)) {
3445 3445                                  EVP_PKEY_free(pkey);
3446 3446                                  goto cleanup;
3447 3447                          }
3448 3448                  }
3449 3449          }
3450 3450          p12_elem = PKCS12_init(NID_pkcs7_data);
3451 3451          if (p12_elem == NULL) {
3452 3452                  goto cleanup;
3453 3453          }
3454 3454  
3455 3455          /* Put the PKCS#7 stack into the PKCS#12 element. */
3456 3456          if (!PKCS12_pack_authsafes(p12_elem, authsafe_stack)) {
3457 3457                  goto cleanup;
3458 3458          }
3459 3459  
3460 3460          /* Set the integrity MAC on the PKCS#12 element. */
3461 3461          if (!PKCS12_set_mac(p12_elem, cred->cred, cred->credlen,
3462 3462              NULL, 0, PKCS12_DEFAULT_ITER, NULL)) {
3463 3463                  goto cleanup;
3464 3464          }
3465 3465  
3466 3466          /* Write the PKCS#12 element to the export file. */
3467 3467          if (!i2d_PKCS12_bio(bio, p12_elem)) {
3468 3468                  goto cleanup;
3469 3469          }
3470 3470          PKCS12_free(p12_elem);
3471 3471  
3472 3472  cleanup:
3473 3473          /* Clear away the PKCS#7 stack, we're done with it. */
3474 3474          if (authsafe_stack)
3475 3475                  sk_PKCS7_pop_free(authsafe_stack, PKCS7_free);
3476 3476  
3477 3477          if (bio != NULL)
3478 3478                  (void) BIO_free_all(bio);
3479 3479  
3480 3480          return (rv);
3481 3481  }
3482 3482  
3483 3483  KMF_RETURN
3484 3484  openssl_build_pk12(KMF_HANDLE_T handle, int numcerts,
3485 3485      KMF_X509_DER_CERT *certlist, int numkeys, KMF_KEY_HANDLE *keylist,
3486 3486      KMF_CREDENTIAL *p12cred, char *filename)
3487 3487  {
3488 3488          KMF_RETURN rv;
3489 3489  
3490 3490          if (certlist == NULL && keylist == NULL)
3491 3491                  return (KMF_ERR_BAD_PARAMETER);
3492 3492  
3493 3493          rv = local_export_pk12(handle, p12cred, numcerts, certlist,
3494 3494              numkeys, keylist, filename);
3495 3495  
3496 3496          return (rv);
3497 3497  }
3498 3498  
3499 3499  KMF_RETURN
3500 3500  OpenSSL_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
3501 3501  {
3502 3502          KMF_RETURN rv;
3503 3503          KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
3504 3504          char *fullpath = NULL;
3505 3505          char *dirpath = NULL;
3506 3506          char *certfile = NULL;
3507 3507          char *keyfile = NULL;
3508 3508          char *filename = NULL;
3509 3509          KMF_CREDENTIAL *p12cred = NULL;
3510 3510          KMF_X509_DER_CERT certdata;
3511 3511          KMF_KEY_HANDLE key;
3512 3512          int gotkey = 0;
3513 3513          int gotcert = 0;
3514 3514  
3515 3515          if (handle == NULL)
3516 3516                  return (KMF_ERR_BAD_PARAMETER);
3517 3517  
3518 3518          /*
3519 3519           *  First, find the certificate.
3520 3520           */
3521 3521          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
3522 3522          certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
3523 3523          if (certfile != NULL) {
3524 3524                  fullpath = get_fullpath(dirpath, certfile);
3525 3525                  if (fullpath == NULL)
3526 3526                          return (KMF_ERR_BAD_PARAMETER);
3527 3527  
3528 3528                  if (isdir(fullpath)) {
3529 3529                          free(fullpath);
3530 3530                          return (KMF_ERR_AMBIGUOUS_PATHNAME);
3531 3531                  }
3532 3532  
3533 3533                  (void) memset(&certdata, 0, sizeof (certdata));
3534 3534                  rv = kmf_load_cert(kmfh, NULL, NULL, NULL, NULL,
3535 3535                      fullpath, &certdata.certificate);
3536 3536                  if (rv != KMF_OK)
3537 3537                          goto end;
3538 3538  
3539 3539                  gotcert++;
3540 3540                  certdata.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
3541 3541                  free(fullpath);
3542 3542          }
3543 3543  
3544 3544          /*
3545 3545           * Now find the private key.
3546 3546           */
3547 3547          keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
3548 3548          if (keyfile != NULL) {
3549 3549                  fullpath = get_fullpath(dirpath, keyfile);
3550 3550                  if (fullpath == NULL)
3551 3551                          return (KMF_ERR_BAD_PARAMETER);
3552 3552  
3553 3553                  if (isdir(fullpath)) {
3554 3554                          free(fullpath);
3555 3555                          return (KMF_ERR_AMBIGUOUS_PATHNAME);
3556 3556                  }
3557 3557  
3558 3558                  (void) memset(&key, 0, sizeof (KMF_KEY_HANDLE));
3559 3559                  rv = fetch_key(handle, fullpath, KMF_ASYM_PRI, &key);
3560 3560                  if (rv != KMF_OK)
3561 3561                          goto end;
3562 3562                  gotkey++;
3563 3563          }
3564 3564  
3565 3565          /*
3566 3566           * Open the output file.
3567 3567           */
3568 3568          filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
3569 3569              numattr);
3570 3570          if (filename == NULL) {
3571 3571                  rv = KMF_ERR_BAD_PARAMETER;
3572 3572                  goto end;
3573 3573          }
3574 3574  
3575 3575          /* Stick the key and the cert into a PKCS#12 file */
3576 3576          p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
3577 3577          if (p12cred == NULL) {
3578 3578                  rv = KMF_ERR_BAD_PARAMETER;
3579 3579                  goto end;
3580 3580          }
3581 3581  
3582 3582          rv = local_export_pk12(handle, p12cred, 1, &certdata,
3583 3583              1, &key, filename);
3584 3584  
3585 3585  end:
3586 3586          if (fullpath)
3587 3587                  free(fullpath);
3588 3588  
3589 3589          if (gotcert)
3590 3590                  kmf_free_kmf_cert(handle, &certdata);
3591 3591          if (gotkey)
3592 3592                  kmf_free_kmf_key(handle, &key);
3593 3593          return (rv);
3594 3594  }
3595 3595  
3596 3596  /*
3597 3597   * Helper function to extract keys and certificates from
3598 3598   * a single PEM file.  Typically the file should contain a
3599 3599   * private key and an associated public key wrapped in an x509 cert.
3600 3600   * However, the file may be just a list of X509 certs with no keys.
3601 3601   */
3602 3602  static KMF_RETURN
3603 3603  extract_pem(KMF_HANDLE *kmfh,
3604 3604          char *issuer, char *subject, KMF_BIGINT *serial,
3605 3605          char *filename, CK_UTF8CHAR *pin,
3606 3606          CK_ULONG pinlen, EVP_PKEY **priv_key, KMF_DATA **certs,
3607 3607          int *numcerts)
3608 3608  /* ARGSUSED6 */
3609 3609  {
3610 3610          KMF_RETURN rv = KMF_OK;
3611 3611          FILE *fp;
3612 3612          STACK_OF(X509_INFO) *x509_info_stack = NULL;
3613 3613          int i, ncerts = 0, matchcerts = 0;
3614 3614          EVP_PKEY *pkey = NULL;
3615 3615          X509_INFO *info;
3616 3616          X509 *x;
3617 3617          X509_INFO **cert_infos = NULL;
3618 3618          KMF_DATA *certlist = NULL;
3619 3619  
3620 3620          if (priv_key)
3621 3621                  *priv_key = NULL;
3622 3622          if (certs)
3623 3623                  *certs = NULL;
3624 3624          fp = fopen(filename, "r");
3625 3625          if (fp == NULL)
3626 3626                  return (KMF_ERR_OPEN_FILE);
3627 3627  
3628 3628          x509_info_stack = PEM_X509_INFO_read(fp, NULL, NULL, pin);
3629 3629          if (x509_info_stack == NULL) {
3630 3630                  (void) fclose(fp);
3631 3631                  return (KMF_ERR_ENCODING);
3632 3632          }
3633 3633          cert_infos = (X509_INFO **)malloc(sk_X509_INFO_num(x509_info_stack) *
3634 3634              sizeof (X509_INFO *));
3635 3635          if (cert_infos == NULL) {
3636 3636                  (void) fclose(fp);
3637 3637                  rv = KMF_ERR_MEMORY;
3638 3638                  goto err;
3639 3639          }
3640 3640  
3641 3641          for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3642 3642                  /* LINTED E_BAD_PTR_CAST_ALIGN */
3643 3643                  cert_infos[ncerts] = sk_X509_INFO_value(x509_info_stack, i);
3644 3644                  ncerts++;
3645 3645          }
3646 3646  
3647 3647          if (ncerts == 0) {
3648 3648                  (void) fclose(fp);
3649 3649                  rv = KMF_ERR_CERT_NOT_FOUND;
3650 3650                  goto err;
3651 3651          }
3652 3652  
3653 3653          if (priv_key != NULL) {
3654 3654                  rewind(fp);
3655 3655                  pkey = PEM_read_PrivateKey(fp, NULL, NULL, pin);
3656 3656          }
3657 3657          (void) fclose(fp);
3658 3658  
3659 3659          x = cert_infos[ncerts - 1]->x509;
3660 3660          /*
3661 3661           * Make sure the private key matchs the last cert in the file.
3662 3662           */
3663 3663          if (pkey != NULL && !X509_check_private_key(x, pkey)) {
3664 3664                  EVP_PKEY_free(pkey);
3665 3665                  rv = KMF_ERR_KEY_MISMATCH;
3666 3666                  goto err;
3667 3667          }
3668 3668  
3669 3669          certlist = (KMF_DATA *)calloc(ncerts, sizeof (KMF_DATA));
3670 3670          if (certlist == NULL) {
3671 3671                  if (pkey != NULL)
3672 3672                          EVP_PKEY_free(pkey);
3673 3673                  rv = KMF_ERR_MEMORY;
3674 3674                  goto err;
3675 3675          }
3676 3676  
3677 3677          /*
3678 3678           * Convert all of the certs to DER format.
3679 3679           */
3680 3680          matchcerts = 0;
3681 3681          for (i = 0; rv == KMF_OK && certs != NULL && i < ncerts; i++) {
3682 3682                  boolean_t match = FALSE;
3683 3683                  info =  cert_infos[ncerts - 1 - i];
3684 3684  
3685 3685                  rv = check_cert(info->x509, issuer, subject, serial, &match);
3686 3686                  if (rv != KMF_OK || match != TRUE) {
3687 3687                          rv = KMF_OK;
3688 3688                          continue;
3689 3689                  }
3690 3690  
3691 3691                  rv = ssl_cert2KMFDATA(kmfh, info->x509,
3692 3692                          &certlist[matchcerts++]);
3693 3693  
3694 3694                  if (rv != KMF_OK) {
3695 3695                          int j;
3696 3696                          for (j = 0; j < matchcerts; j++)
3697 3697                                  kmf_free_data(&certlist[j]);
3698 3698                          free(certlist);
3699 3699                          certlist = NULL;
3700 3700                          ncerts = matchcerts = 0;
3701 3701                  }
3702 3702          }
3703 3703  
3704 3704          if (numcerts != NULL)
3705 3705                  *numcerts = matchcerts;
3706 3706  
3707 3707          if (certs != NULL)
3708 3708                  *certs = certlist;
3709 3709          else if (certlist != NULL) {
3710 3710                  for (i = 0; i < ncerts; i++)
3711 3711                          kmf_free_data(&certlist[i]);
3712 3712                  free(certlist);
3713 3713                  certlist = NULL;
3714 3714          }
3715 3715  
3716 3716          if (priv_key == NULL && pkey != NULL)
3717 3717                  EVP_PKEY_free(pkey);
3718 3718          else if (priv_key != NULL && pkey != NULL)
3719 3719                  *priv_key = pkey;
3720 3720  
3721 3721  err:
3722 3722          /* Cleanup the stack of X509 info records */
3723 3723          for (i = 0; i < sk_X509_INFO_num(x509_info_stack); i++) {
3724 3724                  /* LINTED E_BAD_PTR_CAST_ALIGN */
3725 3725                  info = (X509_INFO *)sk_X509_INFO_value(x509_info_stack, i);
3726 3726                  X509_INFO_free(info);
3727 3727          }
3728 3728          if (x509_info_stack)
3729 3729                  sk_X509_INFO_free(x509_info_stack);
3730 3730  
3731 3731          if (cert_infos != NULL)
3732 3732                  free(cert_infos);
3733 3733  
3734 3734          return (rv);
3735 3735  }
3736 3736  
3737 3737  static KMF_RETURN
3738 3738  openssl_parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *pin,
3739 3739          STACK_OF(EVP_PKEY) *keys, STACK_OF(X509) *certs)
3740 3740  {
3741 3741          KMF_RETURN ret;
3742 3742          int i;
3743 3743  
3744 3744          for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
3745 3745                  /* LINTED E_BAD_PTR_CAST_ALIGN */
3746 3746                  PKCS12_SAFEBAG *bag = sk_PKCS12_SAFEBAG_value(bags, i);
3747 3747                  ret = openssl_parse_bag(bag, pin, (pin ? strlen(pin) : 0),
3748 3748                      keys, certs);
3749 3749  
3750 3750                  if (ret != KMF_OK)
3751 3751                          return (ret);
3752 3752          }
3753 3753  
3754 3754          return (ret);
3755 3755  }
3756 3756  
3757 3757  static KMF_RETURN
3758 3758  set_pkey_attrib(EVP_PKEY *pkey, ASN1_TYPE *attrib, int nid)
3759 3759  {
3760 3760          X509_ATTRIBUTE *attr = NULL;
3761 3761  
3762 3762          if (pkey == NULL || attrib == NULL)
3763 3763                  return (KMF_ERR_BAD_PARAMETER);
3764 3764  
3765 3765          if (pkey->attributes == NULL) {
3766 3766                  pkey->attributes = sk_X509_ATTRIBUTE_new_null();
3767 3767                  if (pkey->attributes == NULL)
3768 3768                          return (KMF_ERR_MEMORY);
3769 3769          }
3770 3770          attr = X509_ATTRIBUTE_create(nid, attrib->type, attrib->value.ptr);
  
    | 
      ↓ open down ↓ | 
    3770 lines elided | 
    
      ↑ open up ↑ | 
  
3771 3771          if (attr != NULL) {
3772 3772                  int i;
3773 3773                  X509_ATTRIBUTE *a;
3774 3774                  for (i = 0;
3775 3775                      i < sk_X509_ATTRIBUTE_num(pkey->attributes); i++) {
3776 3776                          /* LINTED E_BAD_PTR_CASE_ALIGN */
3777 3777                          a = sk_X509_ATTRIBUTE_value(pkey->attributes, i);
3778 3778                          if (OBJ_obj2nid(a->object) == nid) {
3779 3779                                  X509_ATTRIBUTE_free(a);
3780 3780                                  /* LINTED E_BAD_PTR_CAST_ALIGN */
3781      -                                sk_X509_ATTRIBUTE_set(pkey->attributes,
     3781 +                                (void) sk_X509_ATTRIBUTE_set(pkey->attributes,
3782 3782                                      i, attr);
3783 3783                                  return (KMF_OK);
3784 3784                          }
3785 3785                  }
3786 3786                  if (sk_X509_ATTRIBUTE_push(pkey->attributes, attr) == NULL) {
3787 3787                          X509_ATTRIBUTE_free(attr);
3788 3788                          return (KMF_ERR_MEMORY);
3789 3789                  }
3790 3790          } else {
3791 3791                  return (KMF_ERR_MEMORY);
3792 3792          }
3793 3793  
3794 3794          return (KMF_OK);
3795 3795  }
3796 3796  
3797 3797  static KMF_RETURN
3798 3798  openssl_parse_bag(PKCS12_SAFEBAG *bag, char *pass, int passlen,
3799 3799          STACK_OF(EVP_PKEY) *keylist, STACK_OF(X509) *certlist)
3800 3800  {
3801 3801          KMF_RETURN ret = KMF_OK;
3802 3802          PKCS8_PRIV_KEY_INFO *p8 = NULL;
3803 3803          EVP_PKEY *pkey = NULL;
3804 3804          X509 *xcert = NULL;
3805 3805          ASN1_TYPE *keyid = NULL;
3806 3806          ASN1_TYPE *fname = NULL;
3807 3807          uchar_t *data = NULL;
3808 3808  
3809 3809          keyid = PKCS12_get_attr(bag, NID_localKeyID);
3810 3810          fname = PKCS12_get_attr(bag, NID_friendlyName);
3811 3811  
3812 3812          switch (M_PKCS12_bag_type(bag)) {
3813 3813                  case NID_keyBag:
3814 3814                          if (keylist == NULL)
3815 3815                                  goto end;
3816 3816                          pkey = EVP_PKCS82PKEY(bag->value.keybag);
3817 3817                          if (pkey == NULL)
3818 3818                                  ret = KMF_ERR_PKCS12_FORMAT;
3819 3819  
3820 3820                          break;
3821 3821                  case NID_pkcs8ShroudedKeyBag:
3822 3822                          if (keylist == NULL)
3823 3823                                  goto end;
3824 3824                          p8 = M_PKCS12_decrypt_skey(bag, pass, passlen);
3825 3825                          if (p8 == NULL)
3826 3826                                  return (KMF_ERR_AUTH_FAILED);
3827 3827                          pkey = EVP_PKCS82PKEY(p8);
3828 3828                          PKCS8_PRIV_KEY_INFO_free(p8);
3829 3829                          if (pkey == NULL)
3830 3830                                  ret = KMF_ERR_PKCS12_FORMAT;
3831 3831                          break;
3832 3832                  case NID_certBag:
3833 3833                          if (certlist == NULL)
3834 3834                                  goto end;
3835 3835                          if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate)
3836 3836                                  return (KMF_ERR_PKCS12_FORMAT);
3837 3837                          xcert = M_PKCS12_certbag2x509(bag);
3838 3838                          if (xcert == NULL) {
3839 3839                                  ret = KMF_ERR_PKCS12_FORMAT;
3840 3840                                  goto end;
3841 3841                          }
3842 3842                          if (keyid != NULL) {
3843 3843                                  if (X509_keyid_set1(xcert,
3844 3844                                      keyid->value.octet_string->data,
3845 3845                                      keyid->value.octet_string->length) == 0) {
3846 3846                                          ret = KMF_ERR_PKCS12_FORMAT;
3847 3847                                          goto end;
3848 3848                                  }
3849 3849                          }
3850 3850                          if (fname != NULL) {
3851 3851                                  int len, r;
3852 3852                                  len = ASN1_STRING_to_UTF8(&data,
3853 3853                                      fname->value.asn1_string);
3854 3854                                  if (len > 0 && data != NULL) {
3855 3855                                          r = X509_alias_set1(xcert, data, len);
3856 3856                                          if (r == NULL) {
3857 3857                                                  ret = KMF_ERR_PKCS12_FORMAT;
3858 3858                                                  goto end;
3859 3859                                          }
3860 3860                                  } else {
3861 3861                                          ret = KMF_ERR_PKCS12_FORMAT;
3862 3862                                          goto end;
3863 3863                                  }
3864 3864                          }
3865 3865                          if (sk_X509_push(certlist, xcert) == 0)
3866 3866                                  ret = KMF_ERR_MEMORY;
3867 3867                          else
3868 3868                                  xcert = NULL;
3869 3869                          break;
3870 3870                  case NID_safeContentsBag:
3871 3871                          return (openssl_parse_bags(bag->value.safes, pass,
3872 3872                              keylist, certlist));
3873 3873                  default:
3874 3874                          ret = KMF_ERR_PKCS12_FORMAT;
3875 3875                          break;
3876 3876          }
3877 3877  
3878 3878          /*
3879 3879           * Set the ID and/or FriendlyName attributes on the key.
3880 3880           * If converting to PKCS11 objects, these can translate to CKA_ID
3881 3881           * and CKA_LABEL values.
3882 3882           */
3883 3883          if (pkey != NULL && ret == KMF_OK) {
3884 3884                  ASN1_TYPE *attr = NULL;
3885 3885                  if (keyid != NULL && keyid->type == V_ASN1_OCTET_STRING) {
3886 3886                          if ((attr = ASN1_TYPE_new()) == NULL)
3887 3887                                  return (KMF_ERR_MEMORY);
3888 3888                          attr->value.octet_string =
3889 3889                              ASN1_STRING_dup(keyid->value.octet_string);
3890 3890                          attr->type = V_ASN1_OCTET_STRING;
3891 3891                          attr->value.ptr = (char *)attr->value.octet_string;
3892 3892                          ret = set_pkey_attrib(pkey, attr, NID_localKeyID);
3893 3893                          OPENSSL_free(attr);
3894 3894                  }
3895 3895  
3896 3896                  if (ret == KMF_OK && fname != NULL &&
3897 3897                      fname->type == V_ASN1_BMPSTRING) {
3898 3898                          if ((attr = ASN1_TYPE_new()) == NULL)
3899 3899                                  return (KMF_ERR_MEMORY);
3900 3900                          attr->value.bmpstring =
3901 3901                              ASN1_STRING_dup(fname->value.bmpstring);
3902 3902                          attr->type = V_ASN1_BMPSTRING;
3903 3903                          attr->value.ptr = (char *)attr->value.bmpstring;
3904 3904                          ret = set_pkey_attrib(pkey, attr, NID_friendlyName);
3905 3905                          OPENSSL_free(attr);
3906 3906                  }
3907 3907  
3908 3908                  if (ret == KMF_OK && keylist != NULL &&
3909 3909                      sk_EVP_PKEY_push(keylist, pkey) == 0)
3910 3910                          ret = KMF_ERR_MEMORY;
3911 3911          }
3912 3912          if (ret == KMF_OK && keylist != NULL)
3913 3913                  pkey = NULL;
3914 3914  end:
3915 3915          if (pkey != NULL)
3916 3916                  EVP_PKEY_free(pkey);
3917 3917          if (xcert != NULL)
3918 3918                  X509_free(xcert);
3919 3919          if (data != NULL)
3920 3920                  OPENSSL_free(data);
3921 3921  
3922 3922          return (ret);
3923 3923  }
3924 3924  
3925 3925  static KMF_RETURN
3926 3926  openssl_pkcs12_parse(PKCS12 *p12, char *pin,
3927 3927          STACK_OF(EVP_PKEY) *keys,
3928 3928          STACK_OF(X509) *certs,
3929 3929          STACK_OF(X509) *ca)
3930 3930  /* ARGSUSED3 */
3931 3931  {
3932 3932          KMF_RETURN ret = KMF_OK;
3933 3933          STACK_OF(PKCS7) *asafes = NULL;
3934 3934          STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
3935 3935          int i, bagnid;
3936 3936          PKCS7 *p7;
3937 3937  
3938 3938          if (p12 == NULL || (keys == NULL && certs == NULL))
3939 3939                  return (KMF_ERR_BAD_PARAMETER);
3940 3940  
3941 3941          if (pin == NULL || *pin == NULL) {
3942 3942                  if (PKCS12_verify_mac(p12, NULL, 0)) {
3943 3943                          pin = NULL;
3944 3944                  } else if (PKCS12_verify_mac(p12, "", 0)) {
3945 3945                          pin = "";
3946 3946                  } else {
3947 3947                          return (KMF_ERR_AUTH_FAILED);
3948 3948                  }
3949 3949          } else if (!PKCS12_verify_mac(p12, pin, -1)) {
3950 3950                  return (KMF_ERR_AUTH_FAILED);
3951 3951          }
3952 3952  
3953 3953          if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
3954 3954                  return (KMF_ERR_PKCS12_FORMAT);
3955 3955  
3956 3956          for (i = 0; ret == KMF_OK && i < sk_PKCS7_num(asafes); i++) {
3957 3957                  bags = NULL;
3958 3958                  /* LINTED E_BAD_PTR_CAST_ALIGN */
3959 3959                  p7 = sk_PKCS7_value(asafes, i);
3960 3960                  bagnid = OBJ_obj2nid(p7->type);
3961 3961  
3962 3962                  if (bagnid == NID_pkcs7_data) {
3963 3963                          bags = PKCS12_unpack_p7data(p7);
3964 3964                  } else if (bagnid == NID_pkcs7_encrypted) {
3965 3965                          bags = PKCS12_unpack_p7encdata(p7, pin,
3966 3966                              (pin ? strlen(pin) : 0));
3967 3967                  } else {
3968 3968                          continue;
3969 3969                  }
3970 3970                  if (bags == NULL) {
3971 3971                          ret = KMF_ERR_PKCS12_FORMAT;
3972 3972                          goto out;
3973 3973                  }
3974 3974  
3975 3975                  if (openssl_parse_bags(bags, pin, keys, certs) != KMF_OK)
3976 3976                          ret = KMF_ERR_PKCS12_FORMAT;
3977 3977  
3978 3978                  sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
3979 3979          }
3980 3980  out:
3981 3981          if (asafes != NULL)
3982 3982                  sk_PKCS7_pop_free(asafes, PKCS7_free);
3983 3983  
3984 3984          return (ret);
3985 3985  }
3986 3986  
3987 3987  /*
3988 3988   * Helper function to decrypt and parse PKCS#12 import file.
3989 3989   */
3990 3990  static KMF_RETURN
3991 3991  extract_pkcs12(BIO *fbio, CK_UTF8CHAR *pin, CK_ULONG pinlen,
3992 3992          STACK_OF(EVP_PKEY) **priv_key, STACK_OF(X509) **certs,
3993 3993          STACK_OF(X509) **ca)
3994 3994  /* ARGSUSED2 */
3995 3995  {
3996 3996          PKCS12                  *pk12, *pk12_tmp;
3997 3997          STACK_OF(EVP_PKEY)      *pkeylist = NULL;
3998 3998          STACK_OF(X509)          *xcertlist = NULL;
3999 3999          STACK_OF(X509)          *cacertlist = NULL;
4000 4000  
4001 4001          if ((pk12 = PKCS12_new()) == NULL) {
4002 4002                  return (KMF_ERR_MEMORY);
4003 4003          }
4004 4004  
4005 4005          if ((pk12_tmp = d2i_PKCS12_bio(fbio, &pk12)) == NULL) {
4006 4006                  /* This is ok; it seems to mean there is no more to read. */
4007 4007                  if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_ASN1 &&
4008 4008                      ERR_GET_REASON(ERR_peek_error()) == ASN1_R_HEADER_TOO_LONG)
4009 4009                          goto end_extract_pkcs12;
4010 4010  
4011 4011                  PKCS12_free(pk12);
4012 4012                  return (KMF_ERR_PKCS12_FORMAT);
4013 4013          }
4014 4014          pk12 = pk12_tmp;
4015 4015  
4016 4016          xcertlist = sk_X509_new_null();
4017 4017          if (xcertlist == NULL) {
4018 4018                  PKCS12_free(pk12);
4019 4019                  return (KMF_ERR_MEMORY);
4020 4020          }
4021 4021          pkeylist = sk_EVP_PKEY_new_null();
4022 4022          if (pkeylist == NULL) {
4023 4023                  sk_X509_pop_free(xcertlist, X509_free);
4024 4024                  PKCS12_free(pk12);
4025 4025                  return (KMF_ERR_MEMORY);
4026 4026          }
4027 4027  
4028 4028          if (openssl_pkcs12_parse(pk12, (char *)pin, pkeylist, xcertlist,
4029 4029              cacertlist) != KMF_OK) {
4030 4030                  sk_X509_pop_free(xcertlist, X509_free);
4031 4031                  sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4032 4032                  PKCS12_free(pk12);
4033 4033                  return (KMF_ERR_PKCS12_FORMAT);
4034 4034          }
4035 4035  
4036 4036          if (priv_key && pkeylist)
4037 4037                  *priv_key = pkeylist;
4038 4038          else if (pkeylist)
4039 4039                  sk_EVP_PKEY_pop_free(pkeylist, EVP_PKEY_free);
4040 4040          if (certs && xcertlist)
4041 4041                  *certs = xcertlist;
4042 4042          else if (xcertlist)
4043 4043                  sk_X509_pop_free(xcertlist, X509_free);
4044 4044          if (ca && cacertlist)
4045 4045                  *ca = cacertlist;
4046 4046          else if (cacertlist)
4047 4047                  sk_X509_pop_free(cacertlist, X509_free);
4048 4048  
4049 4049  end_extract_pkcs12:
4050 4050  
4051 4051          PKCS12_free(pk12);
4052 4052          return (KMF_OK);
4053 4053  }
4054 4054  
4055 4055  static KMF_RETURN
4056 4056  sslBN2KMFBN(BIGNUM *from, KMF_BIGINT *to)
4057 4057  {
4058 4058          KMF_RETURN rv = KMF_OK;
4059 4059          uint32_t sz;
4060 4060  
4061 4061          sz = BN_num_bytes(from);
4062 4062          to->val = (uchar_t *)malloc(sz);
4063 4063          if (to->val == NULL)
4064 4064                  return (KMF_ERR_MEMORY);
4065 4065  
4066 4066          if ((to->len = BN_bn2bin(from, to->val)) != sz) {
4067 4067                  free(to->val);
4068 4068                  to->val = NULL;
4069 4069                  to->len = 0;
4070 4070                  rv = KMF_ERR_MEMORY;
4071 4071          }
4072 4072  
4073 4073          return (rv);
4074 4074  }
4075 4075  
4076 4076  static KMF_RETURN
4077 4077  exportRawRSAKey(RSA *rsa, KMF_RAW_KEY_DATA *key)
4078 4078  {
4079 4079          KMF_RETURN rv;
4080 4080          KMF_RAW_RSA_KEY *kmfkey = &key->rawdata.rsa;
4081 4081  
4082 4082          (void) memset(kmfkey, 0, sizeof (KMF_RAW_RSA_KEY));
4083 4083          if ((rv = sslBN2KMFBN(rsa->n, &kmfkey->mod)) != KMF_OK)
4084 4084                  goto cleanup;
4085 4085  
4086 4086          if ((rv = sslBN2KMFBN(rsa->e, &kmfkey->pubexp)) != KMF_OK)
4087 4087                  goto cleanup;
4088 4088  
4089 4089          if (rsa->d != NULL)
4090 4090                  if ((rv = sslBN2KMFBN(rsa->d, &kmfkey->priexp)) != KMF_OK)
4091 4091                          goto cleanup;
4092 4092  
4093 4093          if (rsa->p != NULL)
4094 4094                  if ((rv = sslBN2KMFBN(rsa->p, &kmfkey->prime1)) != KMF_OK)
4095 4095                          goto cleanup;
4096 4096  
4097 4097          if (rsa->q != NULL)
4098 4098                  if ((rv = sslBN2KMFBN(rsa->q, &kmfkey->prime2)) != KMF_OK)
4099 4099                          goto cleanup;
4100 4100  
4101 4101          if (rsa->dmp1 != NULL)
4102 4102                  if ((rv = sslBN2KMFBN(rsa->dmp1, &kmfkey->exp1)) != KMF_OK)
4103 4103                          goto cleanup;
4104 4104  
4105 4105          if (rsa->dmq1 != NULL)
4106 4106                  if ((rv = sslBN2KMFBN(rsa->dmq1, &kmfkey->exp2)) != KMF_OK)
4107 4107                          goto cleanup;
4108 4108  
4109 4109          if (rsa->iqmp != NULL)
4110 4110                  if ((rv = sslBN2KMFBN(rsa->iqmp, &kmfkey->coef)) != KMF_OK)
4111 4111                          goto cleanup;
4112 4112  cleanup:
4113 4113          if (rv != KMF_OK)
4114 4114                  kmf_free_raw_key(key);
4115 4115          else
4116 4116                  key->keytype = KMF_RSA;
4117 4117  
4118 4118          /*
4119 4119           * Free the reference to this key, SSL will not actually free
4120 4120           * the memory until the refcount == 0, so this is safe.
4121 4121           */
4122 4122          RSA_free(rsa);
4123 4123  
4124 4124          return (rv);
4125 4125  }
4126 4126  
4127 4127  static KMF_RETURN
4128 4128  exportRawDSAKey(DSA *dsa, KMF_RAW_KEY_DATA *key)
4129 4129  {
4130 4130          KMF_RETURN rv;
4131 4131          KMF_RAW_DSA_KEY *kmfkey = &key->rawdata.dsa;
4132 4132  
4133 4133          (void) memset(kmfkey, 0, sizeof (KMF_RAW_DSA_KEY));
4134 4134          if ((rv = sslBN2KMFBN(dsa->p, &kmfkey->prime)) != KMF_OK)
4135 4135                  goto cleanup;
4136 4136  
4137 4137          if ((rv = sslBN2KMFBN(dsa->q, &kmfkey->subprime)) != KMF_OK)
4138 4138                  goto cleanup;
4139 4139  
4140 4140          if ((rv = sslBN2KMFBN(dsa->g, &kmfkey->base)) != KMF_OK)
4141 4141                  goto cleanup;
4142 4142  
4143 4143          if ((rv = sslBN2KMFBN(dsa->priv_key, &kmfkey->value)) != KMF_OK)
4144 4144                  goto cleanup;
4145 4145  
4146 4146  cleanup:
4147 4147          if (rv != KMF_OK)
4148 4148                  kmf_free_raw_key(key);
4149 4149          else
4150 4150                  key->keytype = KMF_DSA;
4151 4151  
4152 4152          /*
4153 4153           * Free the reference to this key, SSL will not actually free
4154 4154           * the memory until the refcount == 0, so this is safe.
4155 4155           */
4156 4156          DSA_free(dsa);
4157 4157  
4158 4158          return (rv);
4159 4159  }
4160 4160  
4161 4161  static KMF_RETURN
4162 4162  add_cert_to_list(KMF_HANDLE *kmfh, X509 *sslcert,
4163 4163          KMF_X509_DER_CERT **certlist, int *ncerts)
4164 4164  {
4165 4165          KMF_RETURN rv = KMF_OK;
4166 4166          KMF_X509_DER_CERT *list = (*certlist);
4167 4167          KMF_X509_DER_CERT cert;
4168 4168          int n = (*ncerts);
4169 4169  
4170 4170          if (list == NULL) {
4171 4171                  list = (KMF_X509_DER_CERT *)malloc(sizeof (KMF_X509_DER_CERT));
4172 4172          } else {
4173 4173                  list = (KMF_X509_DER_CERT *)realloc(list,
4174 4174                      sizeof (KMF_X509_DER_CERT) * (n + 1));
4175 4175          }
4176 4176  
4177 4177          if (list == NULL)
4178 4178                  return (KMF_ERR_MEMORY);
4179 4179  
4180 4180          (void) memset(&cert, 0, sizeof (cert));
4181 4181          rv = ssl_cert2KMFDATA(kmfh, sslcert, &cert.certificate);
4182 4182          if (rv == KMF_OK) {
4183 4183                  int len = 0;
4184 4184                  /* Get the alias name for the cert if there is one */
4185 4185                  char *a = (char *)X509_alias_get0(sslcert, &len);
4186 4186                  if (a != NULL)
4187 4187                          cert.kmf_private.label = strdup(a);
4188 4188                  cert.kmf_private.keystore_type = KMF_KEYSTORE_OPENSSL;
4189 4189  
4190 4190                  list[n] = cert;
4191 4191                  (*ncerts) = n + 1;
4192 4192  
4193 4193                  *certlist = list;
4194 4194          } else {
4195 4195                  free(list);
4196 4196          }
4197 4197  
4198 4198          return (rv);
4199 4199  }
4200 4200  
4201 4201  static KMF_RETURN
4202 4202  add_key_to_list(KMF_RAW_KEY_DATA **keylist,
4203 4203          KMF_RAW_KEY_DATA *newkey, int *nkeys)
4204 4204  {
4205 4205          KMF_RAW_KEY_DATA *list = (*keylist);
4206 4206          int n = (*nkeys);
4207 4207  
4208 4208          if (list == NULL) {
4209 4209                  list = (KMF_RAW_KEY_DATA *)malloc(sizeof (KMF_RAW_KEY_DATA));
4210 4210          } else {
4211 4211                  list = (KMF_RAW_KEY_DATA *)realloc(list,
4212 4212                      sizeof (KMF_RAW_KEY_DATA) * (n + 1));
4213 4213          }
4214 4214  
4215 4215          if (list == NULL)
4216 4216                  return (KMF_ERR_MEMORY);
4217 4217  
4218 4218          list[n] = *newkey;
4219 4219          (*nkeys) = n + 1;
4220 4220  
4221 4221          *keylist = list;
4222 4222  
4223 4223          return (KMF_OK);
4224 4224  }
4225 4225  
4226 4226  static X509_ATTRIBUTE *
4227 4227  find_attr(STACK_OF(X509_ATTRIBUTE) *attrs, int nid)
4228 4228  {
4229 4229          X509_ATTRIBUTE *a;
4230 4230          int i;
4231 4231  
4232 4232          if (attrs == NULL)
4233 4233                  return (NULL);
4234 4234  
4235 4235          for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) {
4236 4236                  /* LINTED E_BAD_PTR_CAST_ALIGN */
4237 4237                  a = sk_X509_ATTRIBUTE_value(attrs, i);
4238 4238                  if (OBJ_obj2nid(a->object) == nid)
4239 4239                          return (a);
4240 4240          }
4241 4241          return (NULL);
4242 4242  }
4243 4243  
4244 4244  static KMF_RETURN
4245 4245  convertToRawKey(EVP_PKEY *pkey, KMF_RAW_KEY_DATA *key)
4246 4246  {
4247 4247          KMF_RETURN rv = KMF_OK;
4248 4248          X509_ATTRIBUTE *attr;
4249 4249  
4250 4250          if (pkey == NULL || key == NULL)
4251 4251                  return (KMF_ERR_BAD_PARAMETER);
4252 4252          /* Convert SSL key to raw key */
4253 4253          switch (pkey->type) {
4254 4254                  case EVP_PKEY_RSA:
4255 4255                          rv = exportRawRSAKey(EVP_PKEY_get1_RSA(pkey),
4256 4256                              key);
4257 4257                          if (rv != KMF_OK)
4258 4258                                  return (rv);
4259 4259                          break;
4260 4260                  case EVP_PKEY_DSA:
4261 4261                          rv = exportRawDSAKey(EVP_PKEY_get1_DSA(pkey),
4262 4262                              key);
4263 4263                          if (rv != KMF_OK)
4264 4264                                  return (rv);
4265 4265                          break;
4266 4266                  default:
4267 4267                          return (KMF_ERR_BAD_PARAMETER);
4268 4268          }
4269 4269          /*
4270 4270           * If friendlyName, add it to record.
4271 4271           */
4272 4272          attr = find_attr(pkey->attributes, NID_friendlyName);
4273 4273          if (attr != NULL) {
4274 4274                  ASN1_TYPE *ty = NULL;
4275 4275                  int numattr = sk_ASN1_TYPE_num(attr->value.set);
4276 4276                  if (attr->single == 0 && numattr > 0) {
4277 4277                          /* LINTED E_BAD_PTR_CAST_ALIGN */
4278 4278                          ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4279 4279                  }
4280 4280                  if (ty != NULL) {
4281 4281  #if OPENSSL_VERSION_NUMBER < 0x10000000L
4282 4282                          key->label = uni2asc(ty->value.bmpstring->data,
4283 4283                              ty->value.bmpstring->length);
4284 4284  #else
4285 4285                          key->label = OPENSSL_uni2asc(ty->value.bmpstring->data,
4286 4286                              ty->value.bmpstring->length);
4287 4287  #endif
4288 4288                  }
4289 4289          } else {
4290 4290                  key->label = NULL;
4291 4291          }
4292 4292  
4293 4293          /*
4294 4294           * If KeyID, add it to record as a KMF_DATA object.
4295 4295           */
4296 4296          attr = find_attr(pkey->attributes, NID_localKeyID);
4297 4297          if (attr != NULL) {
4298 4298                  ASN1_TYPE *ty = NULL;
4299 4299                  int numattr = sk_ASN1_TYPE_num(attr->value.set);
4300 4300                  if (attr->single == 0 && numattr > 0) {
4301 4301                          /* LINTED E_BAD_PTR_CAST_ALIGN */
4302 4302                          ty = sk_ASN1_TYPE_value(attr->value.set, 0);
4303 4303                  }
4304 4304                  key->id.Data = (uchar_t *)malloc(
4305 4305                      ty->value.octet_string->length);
4306 4306                  if (key->id.Data == NULL)
4307 4307                          return (KMF_ERR_MEMORY);
4308 4308                  (void) memcpy(key->id.Data, ty->value.octet_string->data,
4309 4309                      ty->value.octet_string->length);
4310 4310                  key->id.Length = ty->value.octet_string->length;
4311 4311          } else {
4312 4312                  (void) memset(&key->id, 0, sizeof (KMF_DATA));
4313 4313          }
4314 4314  
4315 4315          return (rv);
4316 4316  }
4317 4317  
4318 4318  static KMF_RETURN
4319 4319  convertPK12Objects(
4320 4320          KMF_HANDLE *kmfh,
4321 4321          STACK_OF(EVP_PKEY) *sslkeys,
4322 4322          STACK_OF(X509) *sslcert,
4323 4323          STACK_OF(X509) *sslcacerts,
4324 4324          KMF_RAW_KEY_DATA **keylist, int *nkeys,
4325 4325          KMF_X509_DER_CERT **certlist, int *ncerts)
4326 4326  {
4327 4327          KMF_RETURN rv = KMF_OK;
4328 4328          KMF_RAW_KEY_DATA key;
4329 4329          int i;
4330 4330  
4331 4331          for (i = 0; sslkeys != NULL && i < sk_EVP_PKEY_num(sslkeys); i++) {
4332 4332                  /* LINTED E_BAD_PTR_CAST_ALIGN */
4333 4333                  EVP_PKEY *pkey = sk_EVP_PKEY_value(sslkeys, i);
4334 4334                  rv = convertToRawKey(pkey, &key);
4335 4335                  if (rv == KMF_OK)
4336 4336                          rv = add_key_to_list(keylist, &key, nkeys);
4337 4337  
4338 4338                  if (rv != KMF_OK)
4339 4339                          return (rv);
4340 4340          }
4341 4341  
4342 4342          /* Now add the certificate to the certlist */
4343 4343          for (i = 0; sslcert != NULL && i < sk_X509_num(sslcert); i++) {
4344 4344                  /* LINTED E_BAD_PTR_CAST_ALIGN */
4345 4345                  X509 *cert = sk_X509_value(sslcert, i);
4346 4346                  rv = add_cert_to_list(kmfh, cert, certlist, ncerts);
4347 4347                  if (rv != KMF_OK)
4348 4348                          return (rv);
4349 4349          }
4350 4350  
4351 4351          /* Also add any included CA certs to the list */
4352 4352          for (i = 0; sslcacerts != NULL && i < sk_X509_num(sslcacerts); i++) {
4353 4353                  X509 *c;
4354 4354                  /*
4355 4355                   * sk_X509_value() is macro that embeds a cast to (X509 *).
4356 4356                   * Here it translates into ((X509 *)sk_value((ca), (i))).
4357 4357                   * Lint is complaining about the embedded casting, and
4358 4358                   * to fix it, you need to fix openssl header files.
4359 4359                   */
4360 4360                  /* LINTED E_BAD_PTR_CAST_ALIGN */
4361 4361                  c = sk_X509_value(sslcacerts, i);
4362 4362  
4363 4363                  /* Now add the ca cert to the certlist */
4364 4364                  rv = add_cert_to_list(kmfh, c, certlist, ncerts);
4365 4365                  if (rv != KMF_OK)
4366 4366                          return (rv);
4367 4367          }
4368 4368          return (rv);
4369 4369  }
4370 4370  
4371 4371  KMF_RETURN
4372 4372  openssl_import_objects(KMF_HANDLE *kmfh,
4373 4373          char *filename, KMF_CREDENTIAL *cred,
4374 4374          KMF_X509_DER_CERT **certlist, int *ncerts,
4375 4375          KMF_RAW_KEY_DATA **keylist, int *nkeys)
4376 4376  {
4377 4377          KMF_RETURN      rv = KMF_OK;
4378 4378          KMF_ENCODE_FORMAT format;
4379 4379          BIO             *bio = NULL;
4380 4380          STACK_OF(EVP_PKEY)      *privkeys = NULL;
4381 4381          STACK_OF(X509)          *certs = NULL;
4382 4382          STACK_OF(X509)          *cacerts = NULL;
4383 4383  
4384 4384          /*
4385 4385           * auto-detect the file format, regardless of what
4386 4386           * the 'format' parameters in the params say.
4387 4387           */
4388 4388          rv = kmf_get_file_format(filename, &format);
4389 4389          if (rv != KMF_OK) {
4390 4390                  return (rv);
4391 4391          }
4392 4392  
4393 4393          /* This function only works for PEM or PKCS#12 files */
4394 4394          if (format != KMF_FORMAT_PEM &&
4395 4395              format != KMF_FORMAT_PEM_KEYPAIR &&
4396 4396              format != KMF_FORMAT_PKCS12)
4397 4397                  return (KMF_ERR_ENCODING);
4398 4398  
4399 4399          *certlist = NULL;
4400 4400          *keylist = NULL;
4401 4401          *ncerts = 0;
4402 4402          *nkeys = 0;
4403 4403  
4404 4404          if (format == KMF_FORMAT_PKCS12) {
4405 4405                  bio = BIO_new_file(filename, "rb");
4406 4406                  if (bio == NULL) {
4407 4407                          SET_ERROR(kmfh, ERR_get_error());
4408 4408                          rv = KMF_ERR_OPEN_FILE;
4409 4409                          goto end;
4410 4410                  }
4411 4411  
4412 4412                  rv = extract_pkcs12(bio, (uchar_t *)cred->cred,
4413 4413                      (uint32_t)cred->credlen, &privkeys, &certs, &cacerts);
4414 4414  
4415 4415                  if (rv  == KMF_OK)
4416 4416                          /* Convert keys and certs to exportable format */
4417 4417                          rv = convertPK12Objects(kmfh, privkeys, certs, cacerts,
4418 4418                              keylist, nkeys, certlist, ncerts);
4419 4419          } else {
4420 4420                  EVP_PKEY *pkey;
4421 4421                  KMF_DATA *certdata = NULL;
4422 4422                  KMF_X509_DER_CERT *kmfcerts = NULL;
4423 4423                  int i;
4424 4424                  rv = extract_pem(kmfh, NULL, NULL, NULL, filename,
4425 4425                      (uchar_t *)cred->cred, (uint32_t)cred->credlen,
4426 4426                      &pkey, &certdata, ncerts);
4427 4427  
4428 4428                  /* Reached end of import file? */
4429 4429                  if (rv == KMF_OK && pkey != NULL) {
4430 4430                          privkeys = sk_EVP_PKEY_new_null();
4431 4431                          if (privkeys == NULL) {
4432 4432                                  rv = KMF_ERR_MEMORY;
4433 4433                                  goto end;
4434 4434                          }
4435 4435                          (void) sk_EVP_PKEY_push(privkeys, pkey);
4436 4436                          /* convert the certificate list here */
4437 4437                          if (*ncerts > 0 && certlist != NULL) {
4438 4438                                  kmfcerts = (KMF_X509_DER_CERT *)calloc(*ncerts,
4439 4439                                      sizeof (KMF_X509_DER_CERT));
4440 4440                                  if (kmfcerts == NULL) {
4441 4441                                          rv = KMF_ERR_MEMORY;
4442 4442                                          goto end;
4443 4443                                  }
4444 4444                                  for (i = 0; i < *ncerts; i++) {
4445 4445                                          kmfcerts[i].certificate = certdata[i];
4446 4446                                          kmfcerts[i].kmf_private.keystore_type =
4447 4447                                              KMF_KEYSTORE_OPENSSL;
4448 4448                                  }
4449 4449                                  *certlist = kmfcerts;
4450 4450                          }
4451 4451                          /*
4452 4452                           * Convert keys to exportable format, the certs
4453 4453                           * are already OK.
4454 4454                           */
4455 4455                          rv = convertPK12Objects(kmfh, privkeys, NULL, NULL,
4456 4456                              keylist, nkeys, NULL, NULL);
4457 4457                  }
4458 4458          }
4459 4459  end:
4460 4460          if (bio != NULL)
4461 4461                  (void) BIO_free(bio);
4462 4462  
4463 4463          if (privkeys)
4464 4464                  sk_EVP_PKEY_pop_free(privkeys, EVP_PKEY_free);
4465 4465          if (certs)
4466 4466                  sk_X509_pop_free(certs, X509_free);
4467 4467          if (cacerts)
4468 4468                  sk_X509_pop_free(cacerts, X509_free);
4469 4469  
4470 4470          return (rv);
4471 4471  }
4472 4472  
4473 4473  static KMF_RETURN
4474 4474  create_deskey(DES_cblock **deskey)
4475 4475  {
4476 4476          DES_cblock *key;
4477 4477  
4478 4478          key = (DES_cblock *) malloc(sizeof (DES_cblock));
4479 4479          if (key == NULL) {
4480 4480                  return (KMF_ERR_MEMORY);
4481 4481          }
4482 4482  
4483 4483          if (DES_random_key(key) == 0) {
4484 4484                  free(key);
4485 4485                  return (KMF_ERR_KEYGEN_FAILED);
4486 4486          }
4487 4487  
4488 4488          *deskey = key;
4489 4489          return (KMF_OK);
4490 4490  }
4491 4491  
4492 4492  #define KEYGEN_RETRY 3
4493 4493  #define DES3_KEY_SIZE 24
4494 4494  
4495 4495  static KMF_RETURN
4496 4496  create_des3key(unsigned char **des3key)
4497 4497  {
4498 4498          KMF_RETURN ret = KMF_OK;
4499 4499          DES_cblock *deskey1 = NULL;
4500 4500          DES_cblock *deskey2 = NULL;
4501 4501          DES_cblock *deskey3 = NULL;
4502 4502          unsigned char *newkey = NULL;
4503 4503          int retry;
4504 4504  
4505 4505          if ((newkey = malloc(DES3_KEY_SIZE)) == NULL) {
4506 4506                  return (KMF_ERR_MEMORY);
4507 4507          }
4508 4508  
4509 4509          /* create the 1st DES key */
4510 4510          if ((ret = create_deskey(&deskey1)) != KMF_OK) {
4511 4511                  goto out;
4512 4512          }
4513 4513  
4514 4514          /*
4515 4515           * Create the 2nd DES key and make sure its value is different
4516 4516           * from the 1st DES key.
4517 4517           */
4518 4518          retry = 0;
4519 4519          do {
4520 4520                  if (deskey2 != NULL) {
4521 4521                          free(deskey2);
4522 4522                          deskey2 = NULL;
4523 4523                  }
4524 4524  
4525 4525                  if ((ret = create_deskey(&deskey2)) != KMF_OK) {
4526 4526                          goto out;
4527 4527                  }
4528 4528  
4529 4529                  if (memcmp((const void *) deskey1, (const void *) deskey2, 8)
4530 4530                      == 0) {
4531 4531                          ret = KMF_ERR_KEYGEN_FAILED;
4532 4532                          retry++;
4533 4533                  }
4534 4534          } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4535 4535  
4536 4536          if (ret != KMF_OK) {
4537 4537                  goto out;
4538 4538          }
4539 4539  
4540 4540          /*
4541 4541           * Create the 3rd DES key and make sure its value is different
4542 4542           * from the 2nd DES key.
4543 4543           */
4544 4544          retry = 0;
4545 4545          do {
4546 4546                  if (deskey3 != NULL) {
4547 4547                          free(deskey3);
4548 4548                          deskey3 = NULL;
4549 4549                  }
4550 4550  
4551 4551                  if ((ret = create_deskey(&deskey3)) != KMF_OK) {
4552 4552                          goto out;
4553 4553                  }
4554 4554  
4555 4555                  if (memcmp((const void *)deskey2, (const void *)deskey3, 8)
4556 4556                      == 0) {
4557 4557                          ret = KMF_ERR_KEYGEN_FAILED;
4558 4558                          retry++;
4559 4559                  }
4560 4560          } while (ret == KMF_ERR_KEYGEN_FAILED && retry < KEYGEN_RETRY);
4561 4561  
4562 4562          if (ret != KMF_OK) {
4563 4563                  goto out;
4564 4564          }
4565 4565  
4566 4566          /* Concatenate 3 DES keys into a DES3 key */
4567 4567          (void) memcpy((void *)newkey, (const void *)deskey1, 8);
4568 4568          (void) memcpy((void *)(newkey + 8), (const void *)deskey2, 8);
4569 4569          (void) memcpy((void *)(newkey + 16), (const void *)deskey3, 8);
4570 4570          *des3key = newkey;
4571 4571  
4572 4572  out:
4573 4573          if (deskey1 != NULL)
4574 4574                  free(deskey1);
4575 4575  
4576 4576          if (deskey2 != NULL)
4577 4577                  free(deskey2);
4578 4578  
4579 4579          if (deskey3 != NULL)
4580 4580                  free(deskey3);
4581 4581  
4582 4582          if (ret != KMF_OK && newkey != NULL)
4583 4583                  free(newkey);
4584 4584  
4585 4585          return (ret);
4586 4586  }
4587 4587  
4588 4588  KMF_RETURN
4589 4589  OpenSSL_CreateSymKey(KMF_HANDLE_T handle,
4590 4590          int numattr, KMF_ATTRIBUTE *attrlist)
4591 4591  {
4592 4592          KMF_RETURN ret = KMF_OK;
4593 4593          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4594 4594          char *fullpath = NULL;
4595 4595          KMF_RAW_SYM_KEY *rkey = NULL;
4596 4596          DES_cblock *deskey = NULL;
4597 4597          unsigned char *des3key = NULL;
4598 4598          unsigned char *random = NULL;
4599 4599          int fd = -1;
4600 4600          KMF_KEY_HANDLE *symkey;
4601 4601          KMF_KEY_ALG keytype;
4602 4602          uint32_t keylen;
4603 4603          uint32_t keylen_size = sizeof (keylen);
4604 4604          char *dirpath;
4605 4605          char *keyfile;
4606 4606  
4607 4607          if (kmfh == NULL)
4608 4608                  return (KMF_ERR_UNINITIALIZED);
4609 4609  
4610 4610          symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
4611 4611          if (symkey == NULL)
4612 4612                  return (KMF_ERR_BAD_PARAMETER);
4613 4613  
4614 4614          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4615 4615  
4616 4616          keyfile = kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist, numattr);
4617 4617          if (keyfile == NULL)
4618 4618                  return (KMF_ERR_BAD_PARAMETER);
4619 4619  
4620 4620          ret = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
4621 4621              (void *)&keytype, NULL);
4622 4622          if (ret != KMF_OK)
4623 4623                  return (KMF_ERR_BAD_PARAMETER);
4624 4624  
4625 4625          ret = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
4626 4626              &keylen, &keylen_size);
4627 4627          if (ret == KMF_ERR_ATTR_NOT_FOUND &&
4628 4628              (keytype == KMF_DES || keytype == KMF_DES3))
4629 4629                  /* keylength is not required for DES and 3DES */
4630 4630                  ret = KMF_OK;
4631 4631          if (ret != KMF_OK)
4632 4632                  return (KMF_ERR_BAD_PARAMETER);
4633 4633  
4634 4634          fullpath = get_fullpath(dirpath, keyfile);
4635 4635          if (fullpath == NULL)
4636 4636                  return (KMF_ERR_BAD_PARAMETER);
4637 4637  
4638 4638          /* If the requested file exists, return an error */
4639 4639          if (test_for_file(fullpath, 0400) == 1) {
4640 4640                  free(fullpath);
4641 4641                  return (KMF_ERR_DUPLICATE_KEYFILE);
4642 4642          }
4643 4643  
4644 4644          fd = open(fullpath, O_CREAT|O_TRUNC|O_RDWR, 0400);
4645 4645          if (fd == -1) {
4646 4646                  ret = KMF_ERR_OPEN_FILE;
4647 4647                  goto out;
4648 4648          }
4649 4649  
4650 4650          rkey = malloc(sizeof (KMF_RAW_SYM_KEY));
4651 4651          if (rkey == NULL) {
4652 4652                  ret = KMF_ERR_MEMORY;
4653 4653                  goto out;
4654 4654          }
4655 4655          (void) memset(rkey, 0, sizeof (KMF_RAW_SYM_KEY));
4656 4656  
4657 4657          if (keytype == KMF_DES) {
4658 4658                  if ((ret = create_deskey(&deskey)) != KMF_OK) {
4659 4659                          goto out;
4660 4660                  }
4661 4661                  rkey->keydata.val = (uchar_t *)deskey;
4662 4662                  rkey->keydata.len = 8;
4663 4663  
4664 4664                  symkey->keyalg = KMF_DES;
4665 4665  
4666 4666          } else if (keytype == KMF_DES3) {
4667 4667                  if ((ret = create_des3key(&des3key)) != KMF_OK) {
4668 4668                          goto out;
4669 4669                  }
4670 4670                  rkey->keydata.val = (uchar_t *)des3key;
4671 4671                  rkey->keydata.len = DES3_KEY_SIZE;
4672 4672                  symkey->keyalg = KMF_DES3;
4673 4673  
4674 4674          } else if (keytype == KMF_AES || keytype == KMF_RC4 ||
4675 4675              keytype == KMF_GENERIC_SECRET) {
4676 4676                  int bytes;
4677 4677  
4678 4678                  if (keylen % 8 != 0) {
4679 4679                          ret = KMF_ERR_BAD_KEY_SIZE;
4680 4680                          goto out;
4681 4681                  }
4682 4682  
4683 4683                  if (keytype == KMF_AES) {
4684 4684                          if (keylen != 128 &&
4685 4685                              keylen != 192 &&
4686 4686                              keylen != 256) {
4687 4687                                  ret = KMF_ERR_BAD_KEY_SIZE;
4688 4688                                  goto out;
4689 4689                          }
4690 4690                  }
4691 4691  
4692 4692                  bytes = keylen/8;
4693 4693                  random = malloc(bytes);
4694 4694                  if (random == NULL) {
4695 4695                          ret = KMF_ERR_MEMORY;
4696 4696                          goto out;
4697 4697                  }
4698 4698                  if (RAND_bytes(random, bytes) != 1) {
4699 4699                          ret = KMF_ERR_KEYGEN_FAILED;
4700 4700                          goto out;
4701 4701                  }
4702 4702  
4703 4703                  rkey->keydata.val = (uchar_t *)random;
4704 4704                  rkey->keydata.len = bytes;
4705 4705                  symkey->keyalg = keytype;
4706 4706  
4707 4707          } else {
4708 4708                  ret = KMF_ERR_BAD_KEY_TYPE;
4709 4709                  goto out;
4710 4710          }
4711 4711  
4712 4712          (void) write(fd, (const void *) rkey->keydata.val, rkey->keydata.len);
4713 4713  
4714 4714          symkey->kstype = KMF_KEYSTORE_OPENSSL;
4715 4715          symkey->keyclass = KMF_SYMMETRIC;
4716 4716          symkey->keylabel = (char *)fullpath;
4717 4717          symkey->israw = TRUE;
4718 4718          symkey->keyp = rkey;
4719 4719  
4720 4720  out:
4721 4721          if (fd != -1)
4722 4722                  (void) close(fd);
4723 4723  
4724 4724          if (ret != KMF_OK && fullpath != NULL) {
4725 4725                  free(fullpath);
4726 4726          }
4727 4727          if (ret != KMF_OK) {
4728 4728                  kmf_free_raw_sym_key(rkey);
4729 4729                  symkey->keyp = NULL;
4730 4730                  symkey->keyalg = KMF_KEYALG_NONE;
4731 4731          }
4732 4732  
4733 4733          return (ret);
4734 4734  }
4735 4735  
4736 4736  /*
4737 4737   * Check a file to see if it is a CRL file with PEM or DER format.
4738 4738   * If success, return its format in the "pformat" argument.
4739 4739   */
4740 4740  KMF_RETURN
4741 4741  OpenSSL_IsCRLFile(KMF_HANDLE_T handle, char *filename, int *pformat)
4742 4742  {
4743 4743          KMF_RETURN      ret = KMF_OK;
4744 4744          KMF_HANDLE      *kmfh = (KMF_HANDLE *)handle;
4745 4745          BIO             *bio = NULL;
4746 4746          X509_CRL        *xcrl = NULL;
4747 4747  
4748 4748          if (filename == NULL) {
4749 4749                  return (KMF_ERR_BAD_PARAMETER);
4750 4750          }
4751 4751  
4752 4752          bio = BIO_new_file(filename, "rb");
4753 4753          if (bio == NULL)        {
4754 4754                  SET_ERROR(kmfh, ERR_get_error());
4755 4755                  ret = KMF_ERR_OPEN_FILE;
4756 4756                  goto out;
4757 4757          }
4758 4758  
4759 4759          if ((xcrl = PEM_read_bio_X509_CRL(bio, NULL, NULL, NULL)) != NULL) {
4760 4760                  *pformat = KMF_FORMAT_PEM;
4761 4761                  goto out;
4762 4762          }
4763 4763          (void) BIO_free(bio);
4764 4764  
4765 4765          /*
4766 4766           * Now try to read it as raw DER data.
4767 4767           */
4768 4768          bio = BIO_new_file(filename, "rb");
4769 4769          if (bio == NULL)        {
4770 4770                  SET_ERROR(kmfh, ERR_get_error());
4771 4771                  ret = KMF_ERR_OPEN_FILE;
4772 4772                  goto out;
4773 4773          }
4774 4774  
4775 4775          if ((xcrl = d2i_X509_CRL_bio(bio, NULL)) != NULL) {
4776 4776                  *pformat = KMF_FORMAT_ASN1;
4777 4777          } else {
4778 4778                  ret = KMF_ERR_BAD_CRLFILE;
4779 4779          }
4780 4780  
4781 4781  out:
4782 4782          if (bio != NULL)
4783 4783                  (void) BIO_free(bio);
4784 4784  
4785 4785          if (xcrl != NULL)
4786 4786                  X509_CRL_free(xcrl);
4787 4787  
4788 4788          return (ret);
4789 4789  }
4790 4790  
4791 4791  KMF_RETURN
4792 4792  OpenSSL_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
4793 4793      KMF_RAW_SYM_KEY *rkey)
4794 4794  {
4795 4795          KMF_RETURN      rv = KMF_OK;
4796 4796          KMF_HANDLE      *kmfh = (KMF_HANDLE *)handle;
4797 4797          KMF_DATA        keyvalue;
4798 4798  
4799 4799          if (kmfh == NULL)
4800 4800                  return (KMF_ERR_UNINITIALIZED);
4801 4801  
4802 4802          if (symkey == NULL || rkey == NULL)
4803 4803                  return (KMF_ERR_BAD_PARAMETER);
4804 4804          else if (symkey->keyclass != KMF_SYMMETRIC)
4805 4805                  return (KMF_ERR_BAD_KEY_CLASS);
4806 4806  
4807 4807          if (symkey->israw) {
4808 4808                  KMF_RAW_SYM_KEY *rawkey = (KMF_RAW_SYM_KEY *)symkey->keyp;
4809 4809  
4810 4810                  if (rawkey == NULL ||
4811 4811                      rawkey->keydata.val == NULL ||
4812 4812                      rawkey->keydata.len == 0)
4813 4813                          return (KMF_ERR_BAD_KEYHANDLE);
4814 4814  
4815 4815                  rkey->keydata.len = rawkey->keydata.len;
4816 4816                  if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
4817 4817                          return (KMF_ERR_MEMORY);
4818 4818                  (void) memcpy(rkey->keydata.val, rawkey->keydata.val,
4819 4819                      rkey->keydata.len);
4820 4820          } else {
4821 4821                  rv = kmf_read_input_file(handle, symkey->keylabel, &keyvalue);
4822 4822                  if (rv != KMF_OK)
4823 4823                          return (rv);
4824 4824                  rkey->keydata.len = keyvalue.Length;
4825 4825                  rkey->keydata.val = keyvalue.Data;
4826 4826          }
4827 4827  
4828 4828          return (rv);
4829 4829  }
4830 4830  
4831 4831  /*
4832 4832   * substitute for the unsafe access(2) function.
4833 4833   * If the file in question already exists, return 1.
4834 4834   * else 0.  If an error occurs during testing (other
4835 4835   * than EEXIST), return -1.
4836 4836   */
4837 4837  static int
4838 4838  test_for_file(char *filename, mode_t mode)
4839 4839  {
4840 4840          int fd;
4841 4841  
4842 4842          /*
4843 4843           * Try to create the file with the EXCL flag.
4844 4844           * The call should fail if the file exists.
4845 4845           */
4846 4846          fd = open(filename, O_WRONLY|O_CREAT|O_EXCL, mode);
4847 4847          if (fd == -1 && errno == EEXIST)
4848 4848                  return (1);
4849 4849          else if (fd == -1) /* some other error */
4850 4850                  return (-1);
4851 4851  
4852 4852          /* The file did NOT exist.  Delete the testcase. */
4853 4853          (void) close(fd);
4854 4854          (void) unlink(filename);
4855 4855          return (0);
4856 4856  }
4857 4857  
4858 4858  KMF_RETURN
4859 4859  OpenSSL_StoreKey(KMF_HANDLE_T handle, int numattr,
4860 4860          KMF_ATTRIBUTE *attrlist)
4861 4861  {
4862 4862          KMF_RETURN rv = KMF_OK;
4863 4863          KMF_HANDLE      *kmfh = (KMF_HANDLE *)handle;
4864 4864          KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
4865 4865          KMF_RAW_KEY_DATA *rawkey;
4866 4866          EVP_PKEY *pkey = NULL;
4867 4867          KMF_ENCODE_FORMAT format = KMF_FORMAT_PEM;
4868 4868          KMF_CREDENTIAL cred = { NULL, 0 };
4869 4869          BIO *out = NULL;
4870 4870          int keys = 0;
4871 4871          char *fullpath = NULL;
4872 4872          char *keyfile = NULL;
4873 4873          char *dirpath = NULL;
4874 4874  
4875 4875          pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
4876 4876          if (pubkey != NULL)
4877 4877                  keys++;
4878 4878  
4879 4879          prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
4880 4880          if (prikey != NULL)
4881 4881                  keys++;
4882 4882  
4883 4883          rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attrlist, numattr);
4884 4884          if (rawkey != NULL)
4885 4885                  keys++;
4886 4886  
4887 4887          /*
4888 4888           * Exactly 1 type of key must be passed to this function.
4889 4889           */
4890 4890          if (keys != 1)
4891 4891                  return (KMF_ERR_BAD_PARAMETER);
4892 4892  
4893 4893          keyfile = (char *)kmf_get_attr_ptr(KMF_KEY_FILENAME_ATTR, attrlist,
4894 4894              numattr);
4895 4895          if (keyfile == NULL)
4896 4896                  return (KMF_ERR_BAD_PARAMETER);
4897 4897  
4898 4898          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
4899 4899  
4900 4900          fullpath = get_fullpath(dirpath, keyfile);
4901 4901  
4902 4902          /* Once we have the full path, we don't need the pieces */
4903 4903          if (fullpath == NULL)
4904 4904                  return (KMF_ERR_BAD_PARAMETER);
4905 4905  
4906 4906          /* If the requested file exists, return an error */
4907 4907          if (test_for_file(fullpath, 0400) == 1) {
4908 4908                  free(fullpath);
4909 4909                  return (KMF_ERR_DUPLICATE_KEYFILE);
4910 4910          }
4911 4911  
4912 4912          rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
4913 4913              &format, NULL);
4914 4914          if (rv != KMF_OK)
4915 4915                  /* format is optional. */
4916 4916                  rv = KMF_OK;
4917 4917  
4918 4918          /* CRED is not required for OpenSSL files */
4919 4919          (void) kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
4920 4920              &cred, NULL);
4921 4921  
4922 4922          /* Store the private key to the keyfile */
4923 4923          out = BIO_new_file(fullpath, "wb");
4924 4924          if (out == NULL) {
4925 4925                  SET_ERROR(kmfh, ERR_get_error());
4926 4926                  rv = KMF_ERR_OPEN_FILE;
4927 4927                  goto end;
4928 4928          }
4929 4929  
4930 4930          if (prikey != NULL && prikey->keyp != NULL) {
4931 4931                  if (prikey->keyalg == KMF_RSA ||
4932 4932                      prikey->keyalg == KMF_DSA) {
4933 4933                          pkey = (EVP_PKEY *)prikey->keyp;
4934 4934  
4935 4935                          rv = ssl_write_key(kmfh, format,
4936 4936                              out, &cred, pkey, TRUE);
4937 4937  
4938 4938                          if (rv == KMF_OK && prikey->keylabel == NULL) {
4939 4939                                  prikey->keylabel = strdup(fullpath);
4940 4940                                  if (prikey->keylabel == NULL)
4941 4941                                          rv = KMF_ERR_MEMORY;
4942 4942                          }
4943 4943                  }
4944 4944          } else if (pubkey != NULL && pubkey->keyp != NULL) {
4945 4945                  if (pubkey->keyalg == KMF_RSA ||
4946 4946                      pubkey->keyalg == KMF_DSA) {
4947 4947                          pkey = (EVP_PKEY *)pubkey->keyp;
4948 4948  
4949 4949                          rv = ssl_write_key(kmfh, format,
4950 4950                              out, &cred, pkey, FALSE);
4951 4951  
4952 4952                          if (rv == KMF_OK && pubkey->keylabel == NULL) {
4953 4953                                  pubkey->keylabel = strdup(fullpath);
4954 4954                                  if (pubkey->keylabel == NULL)
4955 4955                                          rv = KMF_ERR_MEMORY;
4956 4956                          }
4957 4957                  }
4958 4958          } else if (rawkey != NULL) {
4959 4959                  if (rawkey->keytype == KMF_RSA) {
4960 4960                          pkey = ImportRawRSAKey(&rawkey->rawdata.rsa);
4961 4961                  } else if (rawkey->keytype == KMF_DSA) {
4962 4962                          pkey = ImportRawDSAKey(&rawkey->rawdata.dsa);
4963 4963                  } else {
4964 4964                          rv = KMF_ERR_BAD_PARAMETER;
4965 4965                  }
4966 4966                  if (pkey != NULL) {
4967 4967                          KMF_KEY_CLASS kclass = KMF_ASYM_PRI;
4968 4968  
4969 4969                          rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
4970 4970                              (void *)&kclass, NULL);
4971 4971                          if (rv != KMF_OK)
4972 4972                                  rv = KMF_OK;
4973 4973                          rv = ssl_write_key(kmfh, format, out,
4974 4974                              &cred, pkey, (kclass == KMF_ASYM_PRI));
4975 4975                          EVP_PKEY_free(pkey);
4976 4976                  }
4977 4977          }
4978 4978  
4979 4979  end:
4980 4980  
4981 4981          if (out)
4982 4982                  (void) BIO_free(out);
4983 4983  
4984 4984  
4985 4985          if (rv == KMF_OK)
4986 4986                  (void) chmod(fullpath, 0400);
4987 4987  
4988 4988          free(fullpath);
4989 4989          return (rv);
4990 4990  }
4991 4991  
4992 4992  KMF_RETURN
4993 4993  OpenSSL_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
4994 4994  {
4995 4995          KMF_RETURN ret = KMF_OK;
4996 4996          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4997 4997          X509_CRL *xcrl = NULL;
4998 4998          X509 *xcert = NULL;
4999 4999          EVP_PKEY *pkey;
5000 5000          KMF_ENCODE_FORMAT format;
5001 5001          BIO *in = NULL, *out = NULL;
5002 5002          int openssl_ret = 0;
5003 5003          KMF_ENCODE_FORMAT outformat;
5004 5004          boolean_t crlcheck = FALSE;
5005 5005          char *certfile, *dirpath, *crlfile, *incrl, *outcrl, *outcrlfile;
5006 5006  
5007 5007          if (numattr == 0 || attrlist == NULL) {
5008 5008                  return (KMF_ERR_BAD_PARAMETER);
5009 5009          }
5010 5010  
5011 5011          /* CRL check is optional */
5012 5012          (void) kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
5013 5013              &crlcheck, NULL);
5014 5014  
5015 5015          certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5016 5016          if (crlcheck == B_TRUE && certfile == NULL) {
5017 5017                  return (KMF_ERR_BAD_CERTFILE);
5018 5018          }
5019 5019  
5020 5020          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5021 5021          incrl = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist, numattr);
5022 5022          outcrl = kmf_get_attr_ptr(KMF_CRL_OUTFILE_ATTR, attrlist, numattr);
5023 5023  
5024 5024          crlfile = get_fullpath(dirpath, incrl);
5025 5025  
5026 5026          if (crlfile == NULL)
5027 5027                  return (KMF_ERR_BAD_CRLFILE);
5028 5028  
5029 5029          outcrlfile = get_fullpath(dirpath, outcrl);
5030 5030          if (outcrlfile == NULL)
5031 5031                  return (KMF_ERR_BAD_CRLFILE);
5032 5032  
5033 5033          if (isdir(outcrlfile)) {
5034 5034                  free(outcrlfile);
5035 5035                  return (KMF_ERR_BAD_CRLFILE);
5036 5036          }
5037 5037  
5038 5038          ret = kmf_is_crl_file(handle, crlfile, &format);
5039 5039          if (ret != KMF_OK) {
5040 5040                  free(outcrlfile);
5041 5041                  return (ret);
5042 5042          }
5043 5043  
5044 5044          in = BIO_new_file(crlfile, "rb");
5045 5045          if (in == NULL) {
5046 5046                  SET_ERROR(kmfh, ERR_get_error());
5047 5047                  ret = KMF_ERR_OPEN_FILE;
5048 5048                  goto end;
5049 5049          }
5050 5050  
5051 5051          if (format == KMF_FORMAT_ASN1) {
5052 5052                  xcrl = d2i_X509_CRL_bio(in, NULL);
5053 5053          } else if (format == KMF_FORMAT_PEM) {
5054 5054                  xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5055 5055          }
5056 5056  
5057 5057          if (xcrl == NULL) {
5058 5058                  SET_ERROR(kmfh, ERR_get_error());
5059 5059                  ret = KMF_ERR_BAD_CRLFILE;
5060 5060                  goto end;
5061 5061          }
5062 5062  
5063 5063          /* If bypasscheck is specified, no need to verify. */
5064 5064          if (crlcheck == B_FALSE)
5065 5065                  goto output;
5066 5066  
5067 5067          ret = kmf_is_cert_file(handle, certfile, &format);
5068 5068          if (ret != KMF_OK)
5069 5069                  goto end;
5070 5070  
5071 5071          /* Read in the CA cert file and convert to X509 */
5072 5072          if (BIO_read_filename(in, certfile) <= 0) {
5073 5073                  SET_ERROR(kmfh, ERR_get_error());
5074 5074                  ret = KMF_ERR_OPEN_FILE;
5075 5075                  goto end;
5076 5076          }
5077 5077  
5078 5078          if (format == KMF_FORMAT_ASN1) {
5079 5079                  xcert = d2i_X509_bio(in, NULL);
5080 5080          } else if (format == KMF_FORMAT_PEM) {
5081 5081                  xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5082 5082          } else {
5083 5083                  ret = KMF_ERR_BAD_CERT_FORMAT;
5084 5084                  goto end;
5085 5085          }
5086 5086  
5087 5087          if (xcert == NULL) {
5088 5088                  SET_ERROR(kmfh, ERR_get_error());
5089 5089                  ret = KMF_ERR_BAD_CERT_FORMAT;
5090 5090                  goto end;
5091 5091          }
5092 5092          /* Now get the public key from the CA cert */
5093 5093          pkey = X509_get_pubkey(xcert);
5094 5094          if (pkey == NULL) {
5095 5095                  SET_ERROR(kmfh, ERR_get_error());
5096 5096                  ret = KMF_ERR_BAD_CERTFILE;
5097 5097                  goto end;
5098 5098          }
5099 5099  
5100 5100          /* Verify the CRL with the CA's public key */
5101 5101          openssl_ret = X509_CRL_verify(xcrl, pkey);
5102 5102          EVP_PKEY_free(pkey);
5103 5103          if (openssl_ret > 0) {
5104 5104                  ret = KMF_OK;  /* verify succeed */
5105 5105          } else {
5106 5106                  SET_ERROR(kmfh, openssl_ret);
5107 5107                  ret = KMF_ERR_BAD_CRLFILE;
5108 5108          }
5109 5109  
5110 5110  output:
5111 5111          ret = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
5112 5112              &outformat, NULL);
5113 5113          if (ret != KMF_OK) {
5114 5114                  ret = KMF_OK;
5115 5115                  outformat = KMF_FORMAT_PEM;
5116 5116          }
5117 5117  
5118 5118          out = BIO_new_file(outcrlfile, "wb");
5119 5119          if (out == NULL) {
5120 5120                  SET_ERROR(kmfh, ERR_get_error());
5121 5121                  ret = KMF_ERR_OPEN_FILE;
5122 5122                  goto end;
5123 5123          }
5124 5124  
5125 5125          if (outformat == KMF_FORMAT_ASN1) {
5126 5126                  openssl_ret = (int)i2d_X509_CRL_bio(out, xcrl);
5127 5127          } else if (outformat == KMF_FORMAT_PEM) {
5128 5128                  openssl_ret = PEM_write_bio_X509_CRL(out, xcrl);
5129 5129          } else {
5130 5130                  ret = KMF_ERR_BAD_PARAMETER;
5131 5131                  goto end;
5132 5132          }
5133 5133  
5134 5134          if (openssl_ret <= 0) {
5135 5135                  SET_ERROR(kmfh, ERR_get_error());
5136 5136                  ret = KMF_ERR_WRITE_FILE;
5137 5137          } else {
5138 5138                  ret = KMF_OK;
5139 5139          }
5140 5140  
5141 5141  end:
5142 5142          if (xcrl != NULL)
5143 5143                  X509_CRL_free(xcrl);
5144 5144  
5145 5145          if (xcert != NULL)
5146 5146                  X509_free(xcert);
5147 5147  
5148 5148          if (in != NULL)
5149 5149                  (void) BIO_free(in);
5150 5150  
5151 5151          if (out != NULL)
5152 5152                  (void) BIO_free(out);
5153 5153  
5154 5154          if (outcrlfile != NULL)
5155 5155                  free(outcrlfile);
5156 5156  
5157 5157          return (ret);
5158 5158  }
5159 5159  
5160 5160  KMF_RETURN
5161 5161  OpenSSL_ListCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5162 5162  {
5163 5163          KMF_RETURN ret = KMF_OK;
5164 5164          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5165 5165          X509_CRL   *x = NULL;
5166 5166          KMF_ENCODE_FORMAT format;
5167 5167          char *crlfile = NULL;
5168 5168          BIO *in = NULL;
5169 5169          BIO *mem = NULL;
5170 5170          long len;
5171 5171          char *memptr;
5172 5172          char *data = NULL;
5173 5173          char **crldata;
5174 5174          char *crlfilename, *dirpath;
5175 5175  
5176 5176          if (numattr == 0 || attrlist == NULL) {
5177 5177                  return (KMF_ERR_BAD_PARAMETER);
5178 5178          }
5179 5179          crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5180 5180              attrlist, numattr);
5181 5181          if (crlfilename == NULL)
5182 5182                  return (KMF_ERR_BAD_CRLFILE);
5183 5183  
5184 5184          crldata = (char **)kmf_get_attr_ptr(KMF_CRL_DATA_ATTR,
5185 5185              attrlist, numattr);
5186 5186  
5187 5187          if (crldata == NULL)
5188 5188                  return (KMF_ERR_BAD_PARAMETER);
5189 5189  
5190 5190          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5191 5191  
5192 5192          crlfile = get_fullpath(dirpath, crlfilename);
5193 5193  
5194 5194          if (crlfile == NULL)
5195 5195                  return (KMF_ERR_BAD_CRLFILE);
5196 5196  
5197 5197          if (isdir(crlfile)) {
5198 5198                  free(crlfile);
5199 5199                  return (KMF_ERR_BAD_CRLFILE);
5200 5200          }
5201 5201  
5202 5202          ret = kmf_is_crl_file(handle, crlfile, &format);
5203 5203          if (ret != KMF_OK) {
5204 5204                  free(crlfile);
5205 5205                  return (ret);
5206 5206          }
5207 5207  
5208 5208          if (bio_err == NULL)
5209 5209                  bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
5210 5210  
5211 5211          in = BIO_new_file(crlfile, "rb");
5212 5212          if (in == NULL) {
5213 5213                  SET_ERROR(kmfh, ERR_get_error());
5214 5214                  ret = KMF_ERR_OPEN_FILE;
5215 5215                  goto end;
5216 5216          }
5217 5217  
5218 5218          if (format == KMF_FORMAT_ASN1) {
5219 5219                  x = d2i_X509_CRL_bio(in, NULL);
5220 5220          } else if (format == KMF_FORMAT_PEM) {
5221 5221                  x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5222 5222          }
5223 5223  
5224 5224          if (x == NULL) { /* should not happen */
5225 5225                  SET_ERROR(kmfh, ERR_get_error());
5226 5226                  ret = KMF_ERR_OPEN_FILE;
5227 5227                  goto end;
5228 5228          }
5229 5229  
5230 5230          mem = BIO_new(BIO_s_mem());
5231 5231          if (mem == NULL) {
5232 5232                  SET_ERROR(kmfh, ERR_get_error());
5233 5233                  ret = KMF_ERR_MEMORY;
5234 5234                  goto end;
5235 5235          }
5236 5236  
5237 5237          (void) X509_CRL_print(mem, x);
5238 5238          len = BIO_get_mem_data(mem, &memptr);
5239 5239          if (len <= 0) {
5240 5240                  SET_ERROR(kmfh, ERR_get_error());
5241 5241                  ret = KMF_ERR_MEMORY;
5242 5242                  goto end;
5243 5243          }
5244 5244  
5245 5245          data = malloc(len + 1);
5246 5246          if (data == NULL) {
5247 5247                  ret = KMF_ERR_MEMORY;
5248 5248                  goto end;
5249 5249          }
5250 5250  
5251 5251          (void) memcpy(data, memptr, len);
5252 5252          data[len] = '\0';
5253 5253          *crldata = data;
5254 5254  
5255 5255  end:
5256 5256          if (x != NULL)
5257 5257                  X509_CRL_free(x);
5258 5258  
5259 5259          if (crlfile != NULL)
5260 5260                  free(crlfile);
5261 5261  
5262 5262          if (in != NULL)
5263 5263                  (void) BIO_free(in);
5264 5264  
5265 5265          if (mem != NULL)
5266 5266                  (void) BIO_free(mem);
5267 5267  
5268 5268          return (ret);
5269 5269  }
5270 5270  
5271 5271  KMF_RETURN
5272 5272  OpenSSL_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5273 5273  {
5274 5274          KMF_RETURN ret = KMF_OK;
5275 5275          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5276 5276          KMF_ENCODE_FORMAT format;
5277 5277          char *crlfile = NULL;
5278 5278          BIO *in = NULL;
5279 5279          char *crlfilename, *dirpath;
5280 5280  
5281 5281          if (numattr == 0 || attrlist == NULL) {
5282 5282                  return (KMF_ERR_BAD_PARAMETER);
5283 5283          }
5284 5284  
5285 5285          crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5286 5286              attrlist, numattr);
5287 5287  
5288 5288          if (crlfilename == NULL)
5289 5289                  return (KMF_ERR_BAD_CRLFILE);
5290 5290  
5291 5291          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5292 5292  
5293 5293          crlfile = get_fullpath(dirpath, crlfilename);
5294 5294  
5295 5295          if (crlfile == NULL)
5296 5296                  return (KMF_ERR_BAD_CRLFILE);
5297 5297  
5298 5298          if (isdir(crlfile)) {
5299 5299                  ret = KMF_ERR_BAD_CRLFILE;
5300 5300                  goto end;
5301 5301          }
5302 5302  
5303 5303          ret = kmf_is_crl_file(handle, crlfile, &format);
5304 5304          if (ret != KMF_OK)
5305 5305                  goto end;
5306 5306  
5307 5307          if (unlink(crlfile) != 0) {
5308 5308                  SET_SYS_ERROR(kmfh, errno);
5309 5309                  ret = KMF_ERR_INTERNAL;
5310 5310                  goto end;
5311 5311          }
5312 5312  
5313 5313  end:
5314 5314          if (in != NULL)
5315 5315                  (void) BIO_free(in);
5316 5316          if (crlfile != NULL)
5317 5317                  free(crlfile);
5318 5318  
5319 5319          return (ret);
5320 5320  }
5321 5321  
5322 5322  KMF_RETURN
5323 5323  OpenSSL_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5324 5324  {
5325 5325          KMF_RETURN ret = KMF_OK;
5326 5326          KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5327 5327          KMF_ENCODE_FORMAT format;
5328 5328          BIO *in = NULL;
5329 5329          X509   *xcert = NULL;
5330 5330          X509_CRL   *xcrl = NULL;
5331 5331          STACK_OF(X509_REVOKED) *revoke_stack = NULL;
5332 5332          X509_REVOKED *revoke;
5333 5333          int i;
5334 5334          char *crlfilename, *crlfile, *dirpath, *certfile;
5335 5335  
5336 5336          if (numattr == 0 || attrlist == NULL) {
5337 5337                  return (KMF_ERR_BAD_PARAMETER);
5338 5338          }
5339 5339  
5340 5340          crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR,
5341 5341              attrlist, numattr);
5342 5342  
5343 5343          if (crlfilename == NULL)
5344 5344                  return (KMF_ERR_BAD_CRLFILE);
5345 5345  
5346 5346          certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
5347 5347          if (certfile == NULL)
5348 5348                  return (KMF_ERR_BAD_CRLFILE);
5349 5349  
5350 5350          dirpath = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
5351 5351  
5352 5352          crlfile = get_fullpath(dirpath, crlfilename);
5353 5353  
5354 5354          if (crlfile == NULL)
5355 5355                  return (KMF_ERR_BAD_CRLFILE);
5356 5356  
5357 5357          if (isdir(crlfile)) {
5358 5358                  ret = KMF_ERR_BAD_CRLFILE;
5359 5359                  goto end;
5360 5360          }
5361 5361  
5362 5362          ret = kmf_is_crl_file(handle, crlfile, &format);
5363 5363          if (ret != KMF_OK)
5364 5364                  goto end;
5365 5365  
5366 5366          /* Read the CRL file and load it into a X509_CRL structure */
5367 5367          in = BIO_new_file(crlfilename, "rb");
5368 5368          if (in == NULL) {
5369 5369                  SET_ERROR(kmfh, ERR_get_error());
5370 5370                  ret = KMF_ERR_OPEN_FILE;
5371 5371                  goto end;
5372 5372          }
5373 5373  
5374 5374          if (format == KMF_FORMAT_ASN1) {
5375 5375                  xcrl = d2i_X509_CRL_bio(in, NULL);
5376 5376          } else if (format == KMF_FORMAT_PEM) {
5377 5377                  xcrl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
5378 5378          }
5379 5379  
5380 5380          if (xcrl == NULL) {
5381 5381                  SET_ERROR(kmfh, ERR_get_error());
5382 5382                  ret = KMF_ERR_BAD_CRLFILE;
5383 5383                  goto end;
5384 5384          }
5385 5385          (void) BIO_free(in);
5386 5386  
5387 5387          /* Read the Certificate file and load it into a X509 structure */
5388 5388          ret = kmf_is_cert_file(handle, certfile, &format);
5389 5389          if (ret != KMF_OK)
5390 5390                  goto end;
5391 5391  
5392 5392          in = BIO_new_file(certfile, "rb");
5393 5393          if (in == NULL) {
5394 5394                  SET_ERROR(kmfh, ERR_get_error());
5395 5395                  ret = KMF_ERR_OPEN_FILE;
5396 5396                  goto end;
5397 5397          }
5398 5398  
5399 5399          if (format == KMF_FORMAT_ASN1) {
5400 5400                  xcert = d2i_X509_bio(in, NULL);
5401 5401          } else if (format == KMF_FORMAT_PEM) {
5402 5402                  xcert = PEM_read_bio_X509(in, NULL, NULL, NULL);
5403 5403          }
5404 5404  
5405 5405          if (xcert == NULL) {
5406 5406                  SET_ERROR(kmfh, ERR_get_error());
5407 5407                  ret = KMF_ERR_BAD_CERTFILE;
5408 5408                  goto end;
5409 5409          }
5410 5410  
5411 5411          /* Check if the certificate and the CRL have same issuer */
5412 5412          if (X509_NAME_cmp(xcert->cert_info->issuer, xcrl->crl->issuer) != 0) {
5413 5413                  ret = KMF_ERR_ISSUER;
5414 5414                  goto end;
5415 5415          }
5416 5416  
5417 5417          /* Check to see if the certificate serial number is revoked */
5418 5418          revoke_stack = X509_CRL_get_REVOKED(xcrl);
5419 5419          if (sk_X509_REVOKED_num(revoke_stack) <= 0) {
5420 5420                  /* No revoked certificates in the CRL file */
5421 5421                  SET_ERROR(kmfh, ERR_get_error());
5422 5422                  ret = KMF_ERR_EMPTY_CRL;
5423 5423                  goto end;
5424 5424          }
5425 5425  
5426 5426          for (i = 0; i < sk_X509_REVOKED_num(revoke_stack); i++) {
5427 5427                  /* LINTED E_BAD_PTR_CAST_ALIGN */
5428 5428                  revoke = sk_X509_REVOKED_value(revoke_stack, i);
5429 5429                  if (ASN1_INTEGER_cmp(xcert->cert_info->serialNumber,
5430 5430                      revoke->serialNumber) == 0) {
5431 5431                          break;
5432 5432                  }
5433 5433          }
5434 5434  
5435 5435          if (i < sk_X509_REVOKED_num(revoke_stack)) {
5436 5436                  ret = KMF_OK;
5437 5437          } else {
5438 5438                  ret = KMF_ERR_NOT_REVOKED;
5439 5439          }
5440 5440  
5441 5441  end:
5442 5442          if (in != NULL)
5443 5443                  (void) BIO_free(in);
5444 5444          if (xcrl != NULL)
5445 5445                  X509_CRL_free(xcrl);
5446 5446          if (xcert != NULL)
5447 5447                  X509_free(xcert);
5448 5448  
5449 5449          return (ret);
5450 5450  }
5451 5451  
5452 5452  KMF_RETURN
5453 5453  OpenSSL_VerifyCRLFile(KMF_HANDLE_T handle, char *crlname, KMF_DATA *tacert)
5454 5454  {
5455 5455          KMF_RETURN      ret = KMF_OK;
5456 5456          KMF_HANDLE      *kmfh = (KMF_HANDLE *)handle;
5457 5457          BIO             *bcrl = NULL;
5458 5458          X509_CRL        *xcrl = NULL;
5459 5459          X509            *xcert = NULL;
5460 5460          EVP_PKEY        *pkey;
5461 5461          int             sslret;
5462 5462          KMF_ENCODE_FORMAT crl_format;
5463 5463          unsigned char   *p;
5464 5464          long            len;
5465 5465  
5466 5466          if (handle == NULL || crlname == NULL || tacert == NULL) {
5467 5467                  return (KMF_ERR_BAD_PARAMETER);
5468 5468          }
5469 5469  
5470 5470          ret = kmf_get_file_format(crlname, &crl_format);
5471 5471          if (ret != KMF_OK)
5472 5472                  return (ret);
5473 5473  
5474 5474          bcrl = BIO_new_file(crlname, "rb");
5475 5475          if (bcrl == NULL)       {
5476 5476                  SET_ERROR(kmfh, ERR_get_error());
5477 5477                  ret = KMF_ERR_OPEN_FILE;
5478 5478                  goto cleanup;
5479 5479          }
5480 5480  
5481 5481          if (crl_format == KMF_FORMAT_ASN1) {
5482 5482                  xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5483 5483          } else if (crl_format == KMF_FORMAT_PEM) {
5484 5484                  xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5485 5485          } else {
5486 5486                  ret = KMF_ERR_BAD_PARAMETER;
5487 5487                  goto cleanup;
5488 5488          }
5489 5489  
5490 5490          if (xcrl == NULL) {
5491 5491                  SET_ERROR(kmfh, ERR_get_error());
5492 5492                  ret = KMF_ERR_BAD_CRLFILE;
5493 5493                  goto cleanup;
5494 5494          }
5495 5495  
5496 5496          p = tacert->Data;
5497 5497          len = tacert->Length;
5498 5498          xcert = d2i_X509(NULL, (const uchar_t **)&p, len);
5499 5499  
5500 5500          if (xcert == NULL) {
5501 5501                  SET_ERROR(kmfh, ERR_get_error());
5502 5502                  ret = KMF_ERR_BAD_CERTFILE;
5503 5503                  goto cleanup;
5504 5504          }
5505 5505  
5506 5506          /* Get issuer certificate public key */
5507 5507          pkey = X509_get_pubkey(xcert);
5508 5508          if (pkey == NULL) {
5509 5509                  SET_ERROR(kmfh, ERR_get_error());
5510 5510                  ret = KMF_ERR_BAD_CERT_FORMAT;
5511 5511                  goto cleanup;
5512 5512          }
5513 5513  
5514 5514          /* Verify CRL signature */
5515 5515          sslret = X509_CRL_verify(xcrl, pkey);
5516 5516          EVP_PKEY_free(pkey);
5517 5517          if (sslret > 0) {
5518 5518                  ret = KMF_OK;
5519 5519          } else {
5520 5520                  SET_ERROR(kmfh, sslret);
5521 5521                  ret = KMF_ERR_BAD_CRLFILE;
5522 5522          }
5523 5523  
5524 5524  cleanup:
5525 5525          if (bcrl != NULL)
5526 5526                  (void) BIO_free(bcrl);
5527 5527  
5528 5528          if (xcrl != NULL)
5529 5529                  X509_CRL_free(xcrl);
5530 5530  
5531 5531          if (xcert != NULL)
5532 5532                  X509_free(xcert);
5533 5533  
5534 5534          return (ret);
5535 5535  
5536 5536  }
5537 5537  
5538 5538  KMF_RETURN
5539 5539  OpenSSL_CheckCRLDate(KMF_HANDLE_T handle, char *crlname)
5540 5540  {
5541 5541          KMF_RETURN      ret = KMF_OK;
5542 5542          KMF_HANDLE      *kmfh = (KMF_HANDLE *)handle;
5543 5543          KMF_ENCODE_FORMAT crl_format;
5544 5544          BIO             *bcrl = NULL;
5545 5545          X509_CRL        *xcrl = NULL;
5546 5546          int             i;
5547 5547  
5548 5548          if (handle == NULL || crlname == NULL) {
5549 5549                  return (KMF_ERR_BAD_PARAMETER);
5550 5550          }
5551 5551  
5552 5552          ret = kmf_is_crl_file(handle, crlname, &crl_format);
5553 5553          if (ret != KMF_OK)
5554 5554                  return (ret);
5555 5555  
5556 5556          bcrl = BIO_new_file(crlname, "rb");
5557 5557          if (bcrl == NULL) {
5558 5558                  SET_ERROR(kmfh, ERR_get_error());
5559 5559                  ret = KMF_ERR_OPEN_FILE;
5560 5560                  goto cleanup;
5561 5561          }
5562 5562  
5563 5563          if (crl_format == KMF_FORMAT_ASN1)
5564 5564                  xcrl = d2i_X509_CRL_bio(bcrl, NULL);
5565 5565          else if (crl_format == KMF_FORMAT_PEM)
5566 5566                  xcrl = PEM_read_bio_X509_CRL(bcrl, NULL, NULL, NULL);
5567 5567  
5568 5568          if (xcrl == NULL) {
5569 5569                  SET_ERROR(kmfh, ERR_get_error());
5570 5570                  ret = KMF_ERR_BAD_CRLFILE;
5571 5571                  goto cleanup;
5572 5572          }
5573 5573          i = X509_cmp_time(X509_CRL_get_lastUpdate(xcrl), NULL);
5574 5574          if (i >= 0) {
5575 5575                  ret = KMF_ERR_VALIDITY_PERIOD;
5576 5576                  goto cleanup;
5577 5577          }
5578 5578          if (X509_CRL_get_nextUpdate(xcrl)) {
5579 5579                  i = X509_cmp_time(X509_CRL_get_nextUpdate(xcrl), NULL);
5580 5580  
5581 5581                  if (i <= 0) {
5582 5582                          ret = KMF_ERR_VALIDITY_PERIOD;
5583 5583                          goto cleanup;
5584 5584                  }
5585 5585          }
5586 5586  
5587 5587          ret = KMF_OK;
5588 5588  
5589 5589  cleanup:
5590 5590          if (bcrl != NULL)
5591 5591                  (void) BIO_free(bcrl);
5592 5592  
5593 5593          if (xcrl != NULL)
5594 5594                  X509_CRL_free(xcrl);
5595 5595  
5596 5596          return (ret);
5597 5597  }
  
    | 
      ↓ open down ↓ | 
    1806 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX