Add support for setting keybits and public exponent value for pkey RSA keygen.
[openssl.git] / apps / pkeyutl.c
index 0c6186791e46c48b4c2b6d5a11d98b9ac31dc533..1ecde3cd858e1e3f64de390d365f1e69052d418d 100644 (file)
@@ -81,7 +81,7 @@ int MAIN(int argc, char **);
 int MAIN(int argc, char **argv)
 {
        BIO *in = NULL, *out = NULL;
-       char *infile = NULL, *outfile = NULL;
+       char *infile = NULL, *outfile = NULL, *sigfile = NULL;
        char *engine = NULL;
        int pkey_op = EVP_PKEY_OP_SIGN, key_type = KEY_PRIVKEY;
        int keyform = FORMAT_PEM;
@@ -89,12 +89,12 @@ int MAIN(int argc, char **argv)
        char hexdump = 0, asn1parse = 0;
        EVP_PKEY_CTX *ctx = NULL;
        char *passargin = NULL;
-       int keysize;
+       int keysize = -1;
 
-       unsigned char *buf_in = NULL, *buf_out = NULL;
-       int buf_inlen, buf_outlen;
+       unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
+       int buf_inlen, buf_outlen, siglen = -1;
 
-       int ret = 1, rv;
+       int ret = 1, rv = -1;
 
        argc--;
        argv++;
@@ -118,6 +118,11 @@ int MAIN(int argc, char **argv)
                        if (--argc < 1) badarg = 1;
                        outfile= *(++argv);
                        }
+               else if (!strcmp(*argv,"-sigfile"))
+                       {
+                       if (--argc < 1) badarg = 1;
+                       sigfile= *(++argv);
+                       }
                else if(!strcmp(*argv, "-inkey"))
                        {
                        if (--argc < 1)
@@ -149,8 +154,10 @@ int MAIN(int argc, char **argv)
 #ifndef OPENSSL_NO_ENGINE
                else if(!strcmp(*argv, "-engine"))
                        {
-                       if (--argc < 1) badarg = 1;
-                       engine = *(++argv);
+                       if (--argc < 1)
+                               badarg = 1;
+                       else
+                               engine = *(++argv);
                        }
 #endif
                else if(!strcmp(*argv, "-pubin"))
@@ -165,12 +172,31 @@ int MAIN(int argc, char **argv)
                        pkey_op = EVP_PKEY_OP_SIGN;
                else if(!strcmp(*argv, "-verify"))
                        pkey_op = EVP_PKEY_OP_VERIFY;
+               else if(!strcmp(*argv, "-verifyrecover"))
+                       pkey_op = EVP_PKEY_OP_VERIFYRECOVER;
                else if(!strcmp(*argv, "-rev"))
                        rev = 1;
                else if(!strcmp(*argv, "-encrypt"))
                        pkey_op = EVP_PKEY_OP_ENCRYPT;
                else if(!strcmp(*argv, "-decrypt"))
                        pkey_op = EVP_PKEY_OP_DECRYPT;
+               else if (strcmp(*argv,"-param") == 0)
+                       {
+                       if (--argc < 1)
+                               badarg = 1;
+                       if (!ctx)
+                               {
+                               BIO_puts(bio_err,
+                                       "-param command before -inkey\n");
+                               badarg = 1;
+                               }
+                       else if (pkey_ctrl_string(ctx, *(++argv)) <= 0)
+                               {
+                               BIO_puts(bio_err, "parameter setting error\n");
+                               ERR_print_errors(bio_err);
+                               goto end;
+                               }
+                       }
                else badarg = 1;
                if(badarg)
                        {
@@ -187,24 +213,44 @@ int MAIN(int argc, char **argv)
                goto end;
                }
 
+       if (sigfile && (pkey_op != EVP_PKEY_OP_VERIFY))
+               {
+               BIO_puts(bio_err, "Signature file specified for non verify\n");
+               goto end;
+               }
+
+       if (!sigfile && (pkey_op == EVP_PKEY_OP_VERIFY))
+               {
+               BIO_puts(bio_err, "No signature file specified for verify\n");
+               goto end;
+               }
+
 /* FIXME: seed PRNG only if needed */
        app_RAND_load_file(NULL, bio_err, 0);
 
-       if(infile) {
-               if(!(in = BIO_new_file(infile, "rb"))) {
+       if(infile)
+               {
+               if(!(in = BIO_new_file(infile, "rb")))
+                       {
                        BIO_printf(bio_err, "Error Reading Input File\n");
                        ERR_print_errors(bio_err);      
                        goto end;
+                       }
                }
-       } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
+       else
+               in = BIO_new_fp(stdin, BIO_NOCLOSE);
 
-       if(outfile) {
-               if(!(out = BIO_new_file(outfile, "wb"))) {
-                       BIO_printf(bio_err, "Error Reading Output File\n");
+       if(outfile)
+               {
+               if(!(out = BIO_new_file(outfile, "wb")))
+                       {
+                       BIO_printf(bio_err, "Error Creating Output File\n");
                        ERR_print_errors(bio_err);      
                        goto end;
+                       }
                }
-       } else {
+       else
+               {
                out = BIO_new_fp(stdout, BIO_NOCLOSE);
 #ifdef OPENSSL_SYS_VMS
                {
@@ -214,24 +260,44 @@ int MAIN(int argc, char **argv)
 #endif
        }
 
-       buf_in = OPENSSL_malloc(keysize * 2);
+       if (sigfile)
+               {
+               BIO *sigbio = BIO_new_file(sigfile, "rb");
+               if (!sigbio)
+                       {
+                       BIO_printf(bio_err, "Can't open signature file %s\n",
+                                                               sigfile);
+                       goto end;
+                       }
+               siglen = bio_to_mem(&sig, keysize * 10, sigbio);
+               BIO_free(sigbio);
+               if (siglen <= 0)
+                       {
+                       BIO_printf(bio_err, "Error reading signature data\n");
+                       goto end;
+                       }
+               }
+       
        buf_out = OPENSSL_malloc(keysize);
 
        /* Read the input data */
-       buf_inlen = BIO_read(in, buf_in, keysize * 2);
-       if(buf_inlen <= 0) {
+       buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
+       if(buf_inlen <= 0)
+               {
                BIO_printf(bio_err, "Error reading input Data\n");
                exit(1);
-       }
-       if(rev) {
+               }
+       if(rev)
+               {
                int i;
                unsigned char ctmp;
-               for(i = 0; i < buf_inlen/2; i++) {
+               for(i = 0; i < buf_inlen/2; i++)
+                       {
                        ctmp = buf_in[i];
                        buf_in[i] = buf_in[buf_inlen - 1 - i];
                        buf_in[buf_inlen - 1 - i] = ctmp;
+                       }
                }
-       }
        switch(pkey_op)
                {
                case EVP_PKEY_OP_VERIFYRECOVER:
@@ -252,30 +318,48 @@ int MAIN(int argc, char **argv)
                case EVP_PKEY_OP_DECRYPT:
                rv  = EVP_PKEY_decrypt(ctx, buf_out, &buf_outlen,
                                                        buf_in, buf_inlen);
-               break;
+               break; 
+
+               case EVP_PKEY_OP_VERIFY:
+               rv  = EVP_PKEY_verify(ctx, sig, siglen, buf_in, buf_inlen);
+               if (rv == 0)
+                       BIO_puts(out, "Signature Verification Failure\n");
+               else if (rv == 1)
+                       BIO_puts(out, "Signature Verified Successfully\n");
+               if (rv >= 0)
+                       goto end;
+               break; 
 
                }
 
-       if(rv <= 0) {
+       if(rv <= 0)
+               {
                BIO_printf(bio_err, "Public Key operation error\n");
                ERR_print_errors(bio_err);
                goto end;
-       }
+               }
        ret = 0;
-       if(asn1parse) {
-               if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1)) {
+       if(asn1parse)
+               {
+               if(!ASN1_parse_dump(out, buf_out, buf_outlen, 1, -1))
                        ERR_print_errors(bio_err);
                }
-       } else if(hexdump) BIO_dump(out, (char *)buf_out, buf_outlen);
-       else BIO_write(out, buf_out, buf_outlen);
+       else if(hexdump)
+               BIO_dump(out, (char *)buf_out, buf_outlen);
+       else
+               BIO_write(out, buf_out, buf_outlen);
 
        end:
        if (ctx)
                EVP_PKEY_CTX_free(ctx);
        BIO_free(in);
        BIO_free_all(out);
-       if(buf_in) OPENSSL_free(buf_in);
-       if(buf_out) OPENSSL_free(buf_out);
+       if (buf_in)
+               OPENSSL_free(buf_in);
+       if (buf_out)
+               OPENSSL_free(buf_out);
+       if (sig)
+               OPENSSL_free(sig);
        return ret;
 }
 
@@ -309,7 +393,7 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
        EVP_PKEY *pkey = NULL;
        EVP_PKEY_CTX *ctx = NULL;
        char *passin = NULL;
-       int rv;
+       int rv = -1;
        X509 *x;
        if(((pkey_op == EVP_PKEY_OP_SIGN) || (pkey_op == EVP_PKEY_OP_DECRYPT))
                && (key_type != KEY_PRIVKEY))
@@ -351,7 +435,7 @@ static EVP_PKEY_CTX *init_ctx(int *pkeysize,
        if (!pkey)
                goto end;
 
-       ctx = EVP_PKEY_CTX_new(pkey);
+       ctx = EVP_PKEY_CTX_new(pkey, NULL);
 
        EVP_PKEY_free(pkey);