Home | History | Annotate | Line # | Download | only in apps
      1      1.1  christos /*
      2  1.1.1.2  christos  * Copyright 2006-2018 The OpenSSL Project Authors. All Rights Reserved.
      3      1.1  christos  *
      4  1.1.1.2  christos  * Licensed under the OpenSSL license (the "License").  You may not use
      5  1.1.1.2  christos  * this file except in compliance with the License.  You can obtain a copy
      6  1.1.1.2  christos  * in the file LICENSE in the source distribution or at
      7  1.1.1.2  christos  * https://www.openssl.org/source/license.html
      8      1.1  christos  */
      9  1.1.1.2  christos 
     10      1.1  christos #include <stdio.h>
     11      1.1  christos #include <string.h>
     12      1.1  christos #include "apps.h"
     13  1.1.1.2  christos #include "progs.h"
     14      1.1  christos #include <openssl/pem.h>
     15      1.1  christos #include <openssl/err.h>
     16      1.1  christos #include <openssl/evp.h>
     17      1.1  christos 
     18  1.1.1.2  christos typedef enum OPTION_choice {
     19  1.1.1.2  christos     OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
     20  1.1.1.2  christos     OPT_IN, OPT_OUT, OPT_TEXT, OPT_NOOUT,
     21  1.1.1.2  christos     OPT_ENGINE, OPT_CHECK
     22  1.1.1.2  christos } OPTION_CHOICE;
     23  1.1.1.2  christos 
     24  1.1.1.2  christos const OPTIONS pkeyparam_options[] = {
     25  1.1.1.2  christos     {"help", OPT_HELP, '-', "Display this summary"},
     26  1.1.1.2  christos     {"in", OPT_IN, '<', "Input file"},
     27  1.1.1.2  christos     {"out", OPT_OUT, '>', "Output file"},
     28  1.1.1.2  christos     {"text", OPT_TEXT, '-', "Print parameters as text"},
     29  1.1.1.2  christos     {"noout", OPT_NOOUT, '-', "Don't output encoded parameters"},
     30  1.1.1.2  christos #ifndef OPENSSL_NO_ENGINE
     31  1.1.1.2  christos     {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
     32  1.1.1.2  christos #endif
     33  1.1.1.2  christos     {"check", OPT_CHECK, '-', "Check key param consistency"},
     34  1.1.1.2  christos     {NULL}
     35  1.1.1.2  christos };
     36      1.1  christos 
     37  1.1.1.2  christos int pkeyparam_main(int argc, char **argv)
     38      1.1  christos {
     39  1.1.1.2  christos     ENGINE *e = NULL;
     40      1.1  christos     BIO *in = NULL, *out = NULL;
     41      1.1  christos     EVP_PKEY *pkey = NULL;
     42  1.1.1.2  christos     int text = 0, noout = 0, ret = 1, check = 0;
     43  1.1.1.2  christos     OPTION_CHOICE o;
     44  1.1.1.2  christos     char *infile = NULL, *outfile = NULL, *prog;
     45  1.1.1.2  christos 
     46  1.1.1.2  christos     prog = opt_init(argc, argv, pkeyparam_options);
     47  1.1.1.2  christos     while ((o = opt_next()) != OPT_EOF) {
     48  1.1.1.2  christos         switch (o) {
     49  1.1.1.2  christos         case OPT_EOF:
     50  1.1.1.2  christos         case OPT_ERR:
     51  1.1.1.2  christos  opthelp:
     52  1.1.1.2  christos             BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
     53  1.1.1.2  christos             goto end;
     54  1.1.1.2  christos         case OPT_HELP:
     55  1.1.1.2  christos             opt_help(pkeyparam_options);
     56  1.1.1.2  christos             ret = 0;
     57  1.1.1.2  christos             goto end;
     58  1.1.1.2  christos         case OPT_IN:
     59  1.1.1.2  christos             infile = opt_arg();
     60  1.1.1.2  christos             break;
     61  1.1.1.2  christos         case OPT_OUT:
     62  1.1.1.2  christos             outfile = opt_arg();
     63  1.1.1.2  christos             break;
     64  1.1.1.2  christos         case OPT_ENGINE:
     65  1.1.1.2  christos             e = setup_engine(opt_arg(), 0);
     66  1.1.1.2  christos             break;
     67  1.1.1.2  christos         case OPT_TEXT:
     68      1.1  christos             text = 1;
     69  1.1.1.2  christos             break;
     70  1.1.1.2  christos         case OPT_NOOUT:
     71      1.1  christos             noout = 1;
     72  1.1.1.2  christos             break;
     73  1.1.1.2  christos         case OPT_CHECK:
     74  1.1.1.2  christos             check = 1;
     75  1.1.1.2  christos             break;
     76  1.1.1.2  christos         }
     77      1.1  christos     }
     78  1.1.1.2  christos     argc = opt_num_rest();
     79  1.1.1.2  christos     if (argc != 0)
     80  1.1.1.2  christos         goto opthelp;
     81      1.1  christos 
     82  1.1.1.2  christos     in = bio_open_default(infile, 'r', FORMAT_PEM);
     83  1.1.1.2  christos     if (in == NULL)
     84  1.1.1.2  christos         goto end;
     85  1.1.1.2  christos     out = bio_open_default(outfile, 'w', FORMAT_PEM);
     86  1.1.1.2  christos     if (out == NULL)
     87  1.1.1.2  christos         goto end;
     88  1.1.1.2  christos     pkey = PEM_read_bio_Parameters(in, NULL);
     89  1.1.1.2  christos     if (pkey == NULL) {
     90  1.1.1.2  christos         BIO_printf(bio_err, "Error reading parameters\n");
     91  1.1.1.2  christos         ERR_print_errors(bio_err);
     92  1.1.1.2  christos         goto end;
     93      1.1  christos     }
     94      1.1  christos 
     95  1.1.1.2  christos     if (check) {
     96  1.1.1.2  christos         int r;
     97  1.1.1.2  christos         EVP_PKEY_CTX *ctx;
     98  1.1.1.2  christos 
     99  1.1.1.2  christos         ctx = EVP_PKEY_CTX_new(pkey, e);
    100  1.1.1.2  christos         if (ctx == NULL) {
    101  1.1.1.2  christos             ERR_print_errors(bio_err);
    102      1.1  christos             goto end;
    103      1.1  christos         }
    104      1.1  christos 
    105  1.1.1.2  christos         r = EVP_PKEY_param_check(ctx);
    106      1.1  christos 
    107  1.1.1.2  christos         if (r == 1) {
    108  1.1.1.2  christos             BIO_printf(out, "Parameters are valid\n");
    109  1.1.1.2  christos         } else {
    110  1.1.1.2  christos             /*
    111  1.1.1.2  christos              * Note: at least for RSA keys if this function returns
    112  1.1.1.2  christos              * -1, there will be no error reasons.
    113  1.1.1.2  christos              */
    114  1.1.1.2  christos             unsigned long err;
    115  1.1.1.2  christos 
    116  1.1.1.2  christos             BIO_printf(out, "Parameters are invalid\n");
    117  1.1.1.2  christos 
    118  1.1.1.2  christos             while ((err = ERR_peek_error()) != 0) {
    119  1.1.1.2  christos                 BIO_printf(out, "Detailed error: %s\n",
    120  1.1.1.2  christos                            ERR_reason_error_string(err));
    121  1.1.1.2  christos                 ERR_get_error(); /* remove err from error stack */
    122  1.1.1.2  christos             }
    123  1.1.1.2  christos         }
    124  1.1.1.2  christos         EVP_PKEY_CTX_free(ctx);
    125      1.1  christos     }
    126      1.1  christos 
    127      1.1  christos     if (!noout)
    128      1.1  christos         PEM_write_bio_Parameters(out, pkey);
    129      1.1  christos 
    130      1.1  christos     if (text)
    131      1.1  christos         EVP_PKEY_print_params(out, pkey, 0, NULL);
    132      1.1  christos 
    133      1.1  christos     ret = 0;
    134      1.1  christos 
    135      1.1  christos  end:
    136      1.1  christos     EVP_PKEY_free(pkey);
    137      1.1  christos     release_engine(e);
    138      1.1  christos     BIO_free_all(out);
    139      1.1  christos     BIO_free(in);
    140      1.1  christos 
    141      1.1  christos     return ret;
    142      1.1  christos }
    143