(linenum→info "unix/slp.c:2238")

openssl/0.9.8g/apps/pkcs8.c

    1: /* pkcs8.c */
    2: /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
    3:  * project 1999-2004.
    4:  */
    5: /* ====================================================================
    6:  * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
    7:  *
    8:  * Redistribution and use in source and binary forms, with or without
    9:  * modification, are permitted provided that the following conditions
   10:  * are met:
   11:  *
   12:  * 1. Redistributions of source code must retain the above copyright
   13:  *    notice, this list of conditions and the following disclaimer. 
   14:  *
   15:  * 2. Redistributions in binary form must reproduce the above copyright
   16:  *    notice, this list of conditions and the following disclaimer in
   17:  *    the documentation and/or other materials provided with the
   18:  *    distribution.
   19:  *
   20:  * 3. All advertising materials mentioning features or use of this
   21:  *    software must display the following acknowledgment:
   22:  *    "This product includes software developed by the OpenSSL Project
   23:  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
   24:  *
   25:  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
   26:  *    endorse or promote products derived from this software without
   27:  *    prior written permission. For written permission, please contact
   28:  *    licensing@OpenSSL.org.
   29:  *
   30:  * 5. Products derived from this software may not be called "OpenSSL"
   31:  *    nor may "OpenSSL" appear in their names without prior written
   32:  *    permission of the OpenSSL Project.
   33:  *
   34:  * 6. Redistributions of any form whatsoever must retain the following
   35:  *    acknowledgment:
   36:  *    "This product includes software developed by the OpenSSL Project
   37:  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
   38:  *
   39:  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
   40:  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   41:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   42:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
   43:  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   44:  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   45:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
   46:  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   47:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   48:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   49:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
   50:  * OF THE POSSIBILITY OF SUCH DAMAGE.
   51:  * ====================================================================
   52:  *
   53:  * This product includes cryptographic software written by Eric Young
   54:  * (eay@cryptsoft.com).  This product includes software written by Tim
   55:  * Hudson (tjh@cryptsoft.com).
   56:  *
   57:  */
   58: #include <stdio.h>
   59: #include <string.h>
   60: #include "apps.h"
   61: #include <openssl/pem.h>
   62: #include <openssl/err.h>
   63: #include <openssl/evp.h>
   64: #include <openssl/pkcs12.h>
   65: 
   66: #define PROG pkcs8_main
   67: 
   68: int MAIN(int, char **);
   69: 
   70: int MAIN(int argc, char **argv)
   71:         {
   72:         ENGINE *e = NULL;
   73:         char **args, *infile = NULL, *outfile = NULL;
   74:         char *passargin = NULL, *passargout = NULL;
   75:         BIO *in = NULL, *out = NULL;
   76:         int topk8 = 0;
   77:         int pbe_nid = -1;
   78:         const EVP_CIPHER *cipher = NULL;
   79:         int iter = PKCS12_DEFAULT_ITER;
   80:         int informat, outformat;
   81:         int p8_broken = PKCS8_OK;
   82:         int nocrypt = 0;
   83:         X509_SIG *p8;
   84:         PKCS8_PRIV_KEY_INFO *p8inf;
   85:         EVP_PKEY *pkey=NULL;
   86:         char pass[50], *passin = NULL, *passout = NULL, *p8pass = NULL;
   87:         int badarg = 0;
   88: #ifndef OPENSSL_NO_ENGINE
   89:         char *engine=NULL;
   90: #endif
   91: 
   92:         if (bio_err == NULL) bio_err = BIO_new_fp (stderr, BIO_NOCLOSE);
   93: 
   94:         if (!load_config(bio_err, NULL))
   95:                 goto end;
   96: 
   97:         informat=FORMAT_PEM;
   98:         outformat=FORMAT_PEM;
   99: 
  100:         ERR_load_crypto_strings();
  101:         OpenSSL_add_all_algorithms();
  102:         args = argv + 1;
  103:         while (!badarg && *args && *args[0] == '-')
  104:                 {
  105:                 if (!strcmp(*args,"-v2"))
  106:                         {
  107:                         if (args[1])
  108:                                 {
  109:                                 args++;
  110:                                 cipher=EVP_get_cipherbyname(*args);
  111:                                 if (!cipher)
  112:                                         {
  113:                                         BIO_printf(bio_err,
  114:                                                  "Unknown cipher %s\n", *args);
  115:                                         badarg = 1;
  116:                                         }
  117:                                 }
  118:                         else
  119:                                 badarg = 1;
  120:                         }
  121:                 else if (!strcmp(*args,"-v1"))
  122:                         {
  123:                         if (args[1])
  124:                                 {
  125:                                 args++;
  126:                                 pbe_nid=OBJ_txt2nid(*args);
  127:                                 if (pbe_nid == NID_undef)
  128:                                         {
  129:                                         BIO_printf(bio_err,
  130:                                                  "Unknown PBE algorithm %s\n", *args);
  131:                                         badarg = 1;
  132:                                         }
  133:                                 }
  134:                         else
  135:                                 badarg = 1;
  136:                         }
  137:                 else if (!strcmp(*args,"-inform"))
  138:                         {
  139:                         if (args[1])
  140:                                 {
  141:                                 args++;
  142:                                 informat=str2fmt(*args);
  143:                                 }
  144:                         else badarg = 1;
  145:                         }
  146:                 else if (!strcmp(*args,"-outform"))
  147:                         {
  148:                         if (args[1])
  149:                                 {
  150:                                 args++;
  151:                                 outformat=str2fmt(*args);
  152:                                 }
  153:                         else badarg = 1;
  154:                         }
  155:                 else if (!strcmp (*args, "-topk8"))
  156:                         topk8 = 1;
  157:                 else if (!strcmp (*args, "-noiter"))
  158:                         iter = 1;
  159:                 else if (!strcmp (*args, "-nocrypt"))
  160:                         nocrypt = 1;
  161:                 else if (!strcmp (*args, "-nooct"))
  162:                         p8_broken = PKCS8_NO_OCTET;
  163:                 else if (!strcmp (*args, "-nsdb"))
  164:                         p8_broken = PKCS8_NS_DB;
  165:                 else if (!strcmp (*args, "-embed"))
  166:                         p8_broken = PKCS8_EMBEDDED_PARAM;
  167:                 else if (!strcmp(*args,"-passin"))
  168:                         {
  169:                         if (!args[1]) goto bad;
  170:                         passargin= *(++args);
  171:                         }
  172:                 else if (!strcmp(*args,"-passout"))
  173:                         {
  174:                         if (!args[1]) goto bad;
  175:                         passargout= *(++args);
  176:                         }
  177: #ifndef OPENSSL_NO_ENGINE
  178:                 else if (strcmp(*args,"-engine") == 0)
  179:                         {
  180:                         if (!args[1]) goto bad;
  181:                         engine= *(++args);
  182:                         }
  183: #endif
  184:                 else if (!strcmp (*args, "-in"))
  185:                         {
  186:                         if (args[1])
  187:                                 {
  188:                                 args++;
  189:                                 infile = *args;
  190:                                 }
  191:                         else badarg = 1;
  192:                         }
  193:                 else if (!strcmp (*args, "-out"))
  194:                         {
  195:                         if (args[1])
  196:                                 {
  197:                                 args++;
  198:                                 outfile = *args;
  199:                                 }
  200:                         else badarg = 1;
  201:                         }
  202:                 else badarg = 1;
  203:                 args++;
  204:                 }
  205: 
  206:         if (badarg)
  207:                 {
  208:                 bad:
  209:                 BIO_printf(bio_err, "Usage pkcs8 [options]\n");
  210:                 BIO_printf(bio_err, "where options are\n");
  211:                 BIO_printf(bio_err, "-in file        input file\n");
  212:                 BIO_printf(bio_err, "-inform X       input format (DER or PEM)\n");
  213:                 BIO_printf(bio_err, "-passin arg     input file pass phrase source\n");
  214:                 BIO_printf(bio_err, "-outform X      output format (DER or PEM)\n");
  215:                 BIO_printf(bio_err, "-out file       output file\n");
  216:                 BIO_printf(bio_err, "-passout arg    output file pass phrase source\n");
  217:                 BIO_printf(bio_err, "-topk8          output PKCS8 file\n");
  218:                 BIO_printf(bio_err, "-nooct          use (nonstandard) no octet format\n");
  219:                 BIO_printf(bio_err, "-embed          use (nonstandard) embedded DSA parameters format\n");
  220:                 BIO_printf(bio_err, "-nsdb           use (nonstandard) DSA Netscape DB format\n");
  221:                 BIO_printf(bio_err, "-noiter         use 1 as iteration count\n");
  222:                 BIO_printf(bio_err, "-nocrypt        use or expect unencrypted private key\n");
  223:                 BIO_printf(bio_err, "-v2 alg         use PKCS#5 v2.0 and cipher \"alg\"\n");
  224:                 BIO_printf(bio_err, "-v1 obj         use PKCS#5 v1.5 and cipher \"alg\"\n");
  225: #ifndef OPENSSL_NO_ENGINE
  226:                 BIO_printf(bio_err," -engine e       use engine e, possibly a hardware device.\n");
  227: #endif
  228:                 return 1;
  229:                 }
  230: 
  231: #ifndef OPENSSL_NO_ENGINE
  232:         e = setup_engine(bio_err, engine, 0);
  233: #endif
  234: 
  235:         if (!app_passwd(bio_err, passargin, passargout, &passin, &passout))
  236:                 {
  237:                 BIO_printf(bio_err, "Error getting passwords\n");
  238:                 return 1;
  239:                 }
  240: 
  241:         if ((pbe_nid == -1) && !cipher)
  242:                 pbe_nid = NID_pbeWithMD5AndDES_CBC;
  243: 
  244:         if (infile)
  245:                 {
  246:                 if (!(in = BIO_new_file(infile, "rb")))
  247:                         {
  248:                         BIO_printf(bio_err,
  249:                                  "Can't open input file %s\n", infile);
  250:                         return (1);
  251:                         }
  252:                 }
  253:         else
  254:                 in = BIO_new_fp (stdin, BIO_NOCLOSE);
  255: 
  256:         if (outfile)
  257:                 {
  258:                 if (!(out = BIO_new_file (outfile, "wb")))
  259:                         {
  260:                         BIO_printf(bio_err,
  261:                                  "Can't open output file %s\n", outfile);
  262:                         return (1);
  263:                         }
  264:                 }
  265:         else
  266:                 {
  267:                 out = BIO_new_fp (stdout, BIO_NOCLOSE);
  268: #ifdef OPENSSL_SYS_VMS
  269:                         {
  270:                         BIO *tmpbio = BIO_new(BIO_f_linebuffer());
  271:                         out = BIO_push(tmpbio, out);
  272:                         }
  273: #endif
  274:                 }
  275:         if (topk8)
  276:                 {
  277:                 BIO_free(in); /* Not needed in this section */
  278:                 pkey = load_key(bio_err, infile, informat, 1,
  279:                         passin, e, "key");
  280:                 if (!pkey)
  281:                         {
  282:                         BIO_free_all(out);
  283:                         return 1;
  284:                         }
  285:                 if (!(p8inf = EVP_PKEY2PKCS8_broken(pkey, p8_broken)))
  286:                         {
  287:                         BIO_printf(bio_err, "Error converting key\n");
  288:                         ERR_print_errors(bio_err);
  289:                         EVP_PKEY_free(pkey);
  290:                         BIO_free_all(out);
  291:                         return 1;
  292:                         }
  293:                 if (nocrypt)
  294:                         {
  295:                         if (outformat == FORMAT_PEM) 
  296:                                 PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8inf);
  297:                         else if (outformat == FORMAT_ASN1)
  298:                                 i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8inf);
  299:                         else
  300:                                 {
  301:                                 BIO_printf(bio_err, "Bad format specified for key\n");
  302:                                 PKCS8_PRIV_KEY_INFO_free(p8inf);
  303:                                 EVP_PKEY_free(pkey);
  304:                                 BIO_free_all(out);
  305:                                 return (1);
  306:                                 }
  307:                         }
  308:                 else
  309:                         {
  310:                         if (passout)
  311:                                 p8pass = passout;
  312:                         else
  313:                                 {
  314:                                 p8pass = pass;
  315:                                 if (EVP_read_pw_string(pass, sizeof pass, "Enter Encryption Password:", 1))
  316:                                         {
  317:                                         PKCS8_PRIV_KEY_INFO_free(p8inf);
  318:                                         EVP_PKEY_free(pkey);
  319:                                         BIO_free_all(out);
  320:                                         return (1);
  321:                                         }
  322:                                 }
  323:                         app_RAND_load_file(NULL, bio_err, 0);
  324:                         if (!(p8 = PKCS8_encrypt(pbe_nid, cipher,
  325:                                         p8pass, strlen(p8pass),
  326:                                         NULL, 0, iter, p8inf)))
  327:                                 {
  328:                                 BIO_printf(bio_err, "Error encrypting key\n");
  329:                                 ERR_print_errors(bio_err);
  330:                                 PKCS8_PRIV_KEY_INFO_free(p8inf);
  331:                                 EVP_PKEY_free(pkey);
  332:                                 BIO_free_all(out);
  333:                                 return (1);
  334:                                 }
  335:                         app_RAND_write_file(NULL, bio_err);
  336:                         if (outformat == FORMAT_PEM) 
  337:                                 PEM_write_bio_PKCS8(out, p8);
  338:                         else if (outformat == FORMAT_ASN1)
  339:                                 i2d_PKCS8_bio(out, p8);
  340:                         else
  341:                                 {
  342:                                 BIO_printf(bio_err, "Bad format specified for key\n");
  343:                                 PKCS8_PRIV_KEY_INFO_free(p8inf);
  344:                                 EVP_PKEY_free(pkey);
  345:                                 BIO_free_all(out);
  346:                                 return (1);
  347:                                 }
  348:                         X509_SIG_free(p8);
  349:                         }
  350: 
  351:                 PKCS8_PRIV_KEY_INFO_free (p8inf);
  352:                 EVP_PKEY_free(pkey);
  353:                 BIO_free_all(out);
  354:                 if (passin)
  355:                         OPENSSL_free(passin);
  356:                 if (passout)
  357:                         OPENSSL_free(passout);
  358:                 return (0);
  359:                 }
  360: 
  361:         if (nocrypt)
  362:                 {
  363:                 if (informat == FORMAT_PEM) 
  364:                         p8inf = PEM_read_bio_PKCS8_PRIV_KEY_INFO(in,NULL,NULL, NULL);
  365:                 else if (informat == FORMAT_ASN1)
  366:                         p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
  367:                 else
  368:                         {
  369:                         BIO_printf(bio_err, "Bad format specified for key\n");
  370:                         return (1);
  371:                         }
  372:                 }
  373:         else
  374:                 {
  375:                 if (informat == FORMAT_PEM) 
  376:                         p8 = PEM_read_bio_PKCS8(in, NULL, NULL, NULL);
  377:                 else if (informat == FORMAT_ASN1)
  378:                         p8 = d2i_PKCS8_bio(in, NULL);
  379:                 else
  380:                         {
  381:                         BIO_printf(bio_err, "Bad format specified for key\n");
  382:                         return (1);
  383:                         }
  384: 
  385:                 if (!p8)
  386:                         {
  387:                         BIO_printf (bio_err, "Error reading key\n");
  388:                         ERR_print_errors(bio_err);
  389:                         return (1);
  390:                         }
  391:                 if (passin)
  392:                         p8pass = passin;
  393:                 else
  394:                         {
  395:                         p8pass = pass;
  396:                         EVP_read_pw_string(pass, sizeof pass, "Enter Password:", 0);
  397:                         }
  398:                 p8inf = PKCS8_decrypt(p8, p8pass, strlen(p8pass));
  399:                 X509_SIG_free(p8);
  400:                 }
  401: 
  402:         if (!p8inf)
  403:                 {
  404:                 BIO_printf(bio_err, "Error decrypting key\n");
  405:                 ERR_print_errors(bio_err);
  406:                 return (1);
  407:                 }
  408: 
  409:         if (!(pkey = EVP_PKCS82PKEY(p8inf)))
  410:                 {
  411:                 BIO_printf(bio_err, "Error converting key\n");
  412:                 ERR_print_errors(bio_err);
  413:                 return (1);
  414:                 }
  415:         
  416:         if (p8inf->broken)
  417:                 {
  418:                 BIO_printf(bio_err, "Warning: broken key encoding: ");
  419:                 switch (p8inf->broken)
  420:                         {
  421:                         case PKCS8_NO_OCTET:
  422:                         BIO_printf(bio_err, "No Octet String in PrivateKey\n");
  423:                         break;
  424: 
  425:                         case PKCS8_EMBEDDED_PARAM:
  426:                         BIO_printf(bio_err, "DSA parameters included in PrivateKey\n");
  427:                         break;
  428: 
  429:                         case PKCS8_NS_DB:
  430:                         BIO_printf(bio_err, "DSA public key include in PrivateKey\n");
  431:                         break;
  432: 
  433:                         default:
  434:                         BIO_printf(bio_err, "Unknown broken type\n");
  435:                         break;
  436:                 }
  437:         }
  438:         
  439:         PKCS8_PRIV_KEY_INFO_free(p8inf);
  440:         if (outformat == FORMAT_PEM) 
  441:                 PEM_write_bio_PrivateKey(out, pkey, NULL, NULL, 0, NULL, passout);
  442:         else if (outformat == FORMAT_ASN1)
  443:                 i2d_PrivateKey_bio(out, pkey);
  444:         else
  445:                 {
  446:                 BIO_printf(bio_err, "Bad format specified for key\n");
  447:                         return (1);
  448:                 }
  449: 
  450:         end:
  451:         EVP_PKEY_free(pkey);
  452:         BIO_free_all(out);
  453:         BIO_free(in);
  454:         if (passin)
  455:                 OPENSSL_free(passin);
  456:         if (passout)
  457:                 OPENSSL_free(passout);
  458: 
  459:         return (0);
  460:         }
Syntax (Markdown)