162efe6ecSMatthew Dillon /*
262efe6ecSMatthew Dillon * Copyright (c) 2011-2012 The DragonFly Project. All rights reserved.
362efe6ecSMatthew Dillon *
462efe6ecSMatthew Dillon * This code is derived from software contributed to The DragonFly Project
562efe6ecSMatthew Dillon * by Matthew Dillon <dillon@dragonflybsd.org>
662efe6ecSMatthew Dillon * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
762efe6ecSMatthew Dillon *
862efe6ecSMatthew Dillon * Redistribution and use in source and binary forms, with or without
962efe6ecSMatthew Dillon * modification, are permitted provided that the following conditions
1062efe6ecSMatthew Dillon * are met:
1162efe6ecSMatthew Dillon *
1262efe6ecSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
1362efe6ecSMatthew Dillon * notice, this list of conditions and the following disclaimer.
1462efe6ecSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
1562efe6ecSMatthew Dillon * notice, this list of conditions and the following disclaimer in
1662efe6ecSMatthew Dillon * the documentation and/or other materials provided with the
1762efe6ecSMatthew Dillon * distribution.
1862efe6ecSMatthew Dillon * 3. Neither the name of The DragonFly Project nor the names of its
1962efe6ecSMatthew Dillon * contributors may be used to endorse or promote products derived
2062efe6ecSMatthew Dillon * from this software without specific, prior written permission.
2162efe6ecSMatthew Dillon *
2262efe6ecSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2362efe6ecSMatthew Dillon * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2462efe6ecSMatthew Dillon * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2562efe6ecSMatthew Dillon * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
2662efe6ecSMatthew Dillon * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2762efe6ecSMatthew Dillon * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2862efe6ecSMatthew Dillon * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2962efe6ecSMatthew Dillon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
3062efe6ecSMatthew Dillon * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3162efe6ecSMatthew Dillon * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3262efe6ecSMatthew Dillon * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3362efe6ecSMatthew Dillon * SUCH DAMAGE.
3462efe6ecSMatthew Dillon */
3562efe6ecSMatthew Dillon
3662efe6ecSMatthew Dillon #include "hammer2.h"
3762efe6ecSMatthew Dillon
380c3a8cd0SMatthew Dillon #include <openssl/rsa.h> /* public/private key functions */
390c3a8cd0SMatthew Dillon #include <openssl/pem.h> /* public/private key file load */
400c3a8cd0SMatthew Dillon #include <openssl/err.h>
410c3a8cd0SMatthew Dillon
4262efe6ecSMatthew Dillon /*
4362efe6ecSMatthew Dillon * Should be run as root. Creates /etc/hammer2/rsa.{pub,prv} using
4462efe6ecSMatthew Dillon * an openssl command.
4562efe6ecSMatthew Dillon */
4662efe6ecSMatthew Dillon int
cmd_rsainit(const char * dir_path)4762efe6ecSMatthew Dillon cmd_rsainit(const char *dir_path)
4862efe6ecSMatthew Dillon {
4962efe6ecSMatthew Dillon struct stat st;
5062efe6ecSMatthew Dillon int ecode;
5162efe6ecSMatthew Dillon char *str1;
5262efe6ecSMatthew Dillon char *str2;
5362efe6ecSMatthew Dillon char *cmd;
5462efe6ecSMatthew Dillon mode_t old_umask;
5562efe6ecSMatthew Dillon
5662efe6ecSMatthew Dillon /*
5762efe6ecSMatthew Dillon * Create the directory if necessary
5862efe6ecSMatthew Dillon */
5962efe6ecSMatthew Dillon if (stat(dir_path, &st) < 0) {
6062efe6ecSMatthew Dillon str1 = strdup(dir_path);
6162efe6ecSMatthew Dillon str2 = str1 - 1;
6262efe6ecSMatthew Dillon
6362efe6ecSMatthew Dillon while ((str2 = strchr(str2 + 1, '/')) != NULL) {
6462efe6ecSMatthew Dillon *str2 = 0;
6562efe6ecSMatthew Dillon mkdir(str1, 0755);
6662efe6ecSMatthew Dillon *str2 = '/';
6762efe6ecSMatthew Dillon }
6862efe6ecSMatthew Dillon mkdir(str1, 0700);
6962efe6ecSMatthew Dillon free(str1);
7062efe6ecSMatthew Dillon }
7162efe6ecSMatthew Dillon asprintf(&str1, "%s/rsa.prv", dir_path);
7262efe6ecSMatthew Dillon asprintf(&str2, "%s/rsa.pub", dir_path);
7362efe6ecSMatthew Dillon
7462efe6ecSMatthew Dillon old_umask = umask(077);
75*ce48a6c5SMatthew Dillon if (stat(str1, &st) < 0) {
7662efe6ecSMatthew Dillon asprintf(&cmd, "openssl genrsa -out %s 2048", str1);
7762efe6ecSMatthew Dillon ecode = system(cmd);
7862efe6ecSMatthew Dillon free(cmd);
7962efe6ecSMatthew Dillon chmod(str1, 0400);
8062efe6ecSMatthew Dillon if (ecode) {
8162efe6ecSMatthew Dillon fprintf(stderr,
8262efe6ecSMatthew Dillon "hammer2 rsainit: private key gen failed\n");
8362efe6ecSMatthew Dillon free(str2);
8462efe6ecSMatthew Dillon free(str1);
85*ce48a6c5SMatthew Dillon umask(old_umask);
8662efe6ecSMatthew Dillon return 1;
8762efe6ecSMatthew Dillon }
8862efe6ecSMatthew Dillon printf("hammer2 rsainit: created %s\n", str1);
8962efe6ecSMatthew Dillon remove(str2);
9062efe6ecSMatthew Dillon } else {
9162efe6ecSMatthew Dillon printf("hammer2 rsainit: Using existing private key in %s\n",
9262efe6ecSMatthew Dillon str1);
9362efe6ecSMatthew Dillon }
9462efe6ecSMatthew Dillon if (stat(str2, &st) < 0) {
9562efe6ecSMatthew Dillon asprintf(&cmd, "openssl rsa -in %s -out %s -pubout",
9662efe6ecSMatthew Dillon str1, str2);
9762efe6ecSMatthew Dillon ecode = system(cmd);
9862efe6ecSMatthew Dillon free(cmd);
9962efe6ecSMatthew Dillon if (ecode) {
10062efe6ecSMatthew Dillon fprintf(stderr,
10162efe6ecSMatthew Dillon "hammer2 rsainit: public key gen failed\n");
10262efe6ecSMatthew Dillon free(str2);
10362efe6ecSMatthew Dillon free(str1);
104*ce48a6c5SMatthew Dillon umask(old_umask);
10562efe6ecSMatthew Dillon return 1;
10662efe6ecSMatthew Dillon }
10762efe6ecSMatthew Dillon printf("hammer2 rsainit: created %s\n", str2);
10862efe6ecSMatthew Dillon } else {
10962efe6ecSMatthew Dillon printf("hammer2 rsainit: both keys already exist\n");
11062efe6ecSMatthew Dillon }
111*ce48a6c5SMatthew Dillon umask(old_umask);
11262efe6ecSMatthew Dillon free(str2);
11362efe6ecSMatthew Dillon free(str1);
11462efe6ecSMatthew Dillon
11562efe6ecSMatthew Dillon return 0;
11662efe6ecSMatthew Dillon }
11762efe6ecSMatthew Dillon
11862efe6ecSMatthew Dillon int
cmd_rsaenc(const char ** keyfiles,int nkeys)11962efe6ecSMatthew Dillon cmd_rsaenc(const char **keyfiles, int nkeys)
12062efe6ecSMatthew Dillon {
12162efe6ecSMatthew Dillon RSA **keys = calloc(nkeys, sizeof(RSA *));
12262efe6ecSMatthew Dillon int *ispub = calloc(nkeys, sizeof(int));
12362efe6ecSMatthew Dillon int ecode = 0;
12462efe6ecSMatthew Dillon int blksize = 0;
12562efe6ecSMatthew Dillon int i;
12662efe6ecSMatthew Dillon int off;
12762efe6ecSMatthew Dillon int n;
12862efe6ecSMatthew Dillon unsigned char *data_in;
12962efe6ecSMatthew Dillon unsigned char *data_out;
13062efe6ecSMatthew Dillon
13162efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
13262efe6ecSMatthew Dillon FILE *fp;
13362efe6ecSMatthew Dillon const char *sfx;
13462efe6ecSMatthew Dillon
13562efe6ecSMatthew Dillon sfx = strrchr(keyfiles[i], '.');
13662efe6ecSMatthew Dillon if (sfx && strcmp(sfx, ".pub") == 0) {
13762efe6ecSMatthew Dillon fp = fopen(keyfiles[i], "r");
13862efe6ecSMatthew Dillon if (fp == NULL) {
13962efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
14062efe6ecSMatthew Dillon "open %s\n", keyfiles[i]);
14162efe6ecSMatthew Dillon ecode = 1;
14262efe6ecSMatthew Dillon goto done;
14362efe6ecSMatthew Dillon }
14462efe6ecSMatthew Dillon keys[i] = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
14562efe6ecSMatthew Dillon ispub[i] = 1;
14662efe6ecSMatthew Dillon fclose(fp);
14762efe6ecSMatthew Dillon if (keys[i] == NULL) {
14862efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
14962efe6ecSMatthew Dillon "parse public key from %s\n",
15062efe6ecSMatthew Dillon keyfiles[i]);
15162efe6ecSMatthew Dillon ecode = 1;
15262efe6ecSMatthew Dillon goto done;
15362efe6ecSMatthew Dillon }
15462efe6ecSMatthew Dillon } else if (sfx && strcmp(sfx, ".prv") == 0) {
15562efe6ecSMatthew Dillon fp = fopen(keyfiles[i], "r");
15662efe6ecSMatthew Dillon if (fp == NULL) {
15762efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
15862efe6ecSMatthew Dillon "open %s\n", keyfiles[i]);
15962efe6ecSMatthew Dillon ecode = 1;
16062efe6ecSMatthew Dillon goto done;
16162efe6ecSMatthew Dillon }
16262efe6ecSMatthew Dillon keys[i] = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
16362efe6ecSMatthew Dillon fclose(fp);
16462efe6ecSMatthew Dillon if (keys[i] == NULL) {
16562efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
16662efe6ecSMatthew Dillon "parse private key from %s\n",
16762efe6ecSMatthew Dillon keyfiles[i]);
16862efe6ecSMatthew Dillon ecode = 1;
16962efe6ecSMatthew Dillon goto done;
17062efe6ecSMatthew Dillon }
17162efe6ecSMatthew Dillon } else {
17262efe6ecSMatthew Dillon fprintf(stderr, "hammer2: rsaenc: key files must end "
17362efe6ecSMatthew Dillon "in .pub or .prv\n");
17462efe6ecSMatthew Dillon ecode = 1;
17562efe6ecSMatthew Dillon goto done;
17662efe6ecSMatthew Dillon }
17762efe6ecSMatthew Dillon if (i == 0)
17862efe6ecSMatthew Dillon blksize = RSA_size(keys[i]);
17962efe6ecSMatthew Dillon else
18062efe6ecSMatthew Dillon assert(blksize == RSA_size(keys[i]));
18162efe6ecSMatthew Dillon }
18262efe6ecSMatthew Dillon fprintf(stderr, "blksize %d\n", blksize);
18362efe6ecSMatthew Dillon
18462efe6ecSMatthew Dillon /*
18562efe6ecSMatthew Dillon *
18662efe6ecSMatthew Dillon */
18762efe6ecSMatthew Dillon data_in = malloc(blksize);
18862efe6ecSMatthew Dillon data_out = malloc(blksize);
18962efe6ecSMatthew Dillon off = 0;
19062efe6ecSMatthew Dillon while ((n = read(0, data_in + off, blksize - off)) > 0) {
19162efe6ecSMatthew Dillon off += n;
19262efe6ecSMatthew Dillon if (off == blksize) {
19362efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
19462efe6ecSMatthew Dillon if (ispub[i])
19562efe6ecSMatthew Dillon RSA_public_encrypt(blksize,
19662efe6ecSMatthew Dillon data_in, data_out,
19762efe6ecSMatthew Dillon keys[i],
19862efe6ecSMatthew Dillon RSA_NO_PADDING);
19962efe6ecSMatthew Dillon else
20062efe6ecSMatthew Dillon RSA_private_encrypt(blksize,
20162efe6ecSMatthew Dillon data_in, data_out,
20262efe6ecSMatthew Dillon keys[i],
20362efe6ecSMatthew Dillon RSA_NO_PADDING);
20462efe6ecSMatthew Dillon if (i + 1 != nkeys)
20562efe6ecSMatthew Dillon bcopy(data_out, data_in, blksize);
20662efe6ecSMatthew Dillon }
20762efe6ecSMatthew Dillon if (write(1, data_out, blksize) != blksize) {
20862efe6ecSMatthew Dillon perror("write");
20962efe6ecSMatthew Dillon ecode = 1;
21062efe6ecSMatthew Dillon break;
21162efe6ecSMatthew Dillon }
21262efe6ecSMatthew Dillon off = 0;
21362efe6ecSMatthew Dillon }
21462efe6ecSMatthew Dillon }
21562efe6ecSMatthew Dillon if (off && ecode == 0) {
21662efe6ecSMatthew Dillon if (off < blksize)
21762efe6ecSMatthew Dillon bzero(data_in + off, blksize - off);
21862efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
21962efe6ecSMatthew Dillon if (ispub[i])
22062efe6ecSMatthew Dillon RSA_public_encrypt(blksize,
22162efe6ecSMatthew Dillon data_in, data_out,
22262efe6ecSMatthew Dillon keys[i],
22362efe6ecSMatthew Dillon RSA_NO_PADDING);
22462efe6ecSMatthew Dillon else
22562efe6ecSMatthew Dillon RSA_private_encrypt(blksize,
22662efe6ecSMatthew Dillon data_in, data_out,
22762efe6ecSMatthew Dillon keys[i],
22862efe6ecSMatthew Dillon RSA_NO_PADDING);
22962efe6ecSMatthew Dillon if (i + 1 != nkeys)
23062efe6ecSMatthew Dillon bcopy(data_out, data_in, blksize);
23162efe6ecSMatthew Dillon }
23262efe6ecSMatthew Dillon if (write(1, data_out, blksize) != blksize) {
23362efe6ecSMatthew Dillon perror("write");
23462efe6ecSMatthew Dillon ecode = 1;
23562efe6ecSMatthew Dillon }
23662efe6ecSMatthew Dillon }
23762efe6ecSMatthew Dillon if (n < 0) {
23862efe6ecSMatthew Dillon perror("read");
23962efe6ecSMatthew Dillon ecode = 1;
24062efe6ecSMatthew Dillon }
24162efe6ecSMatthew Dillon free(data_out);
24262efe6ecSMatthew Dillon free(data_in);
24362efe6ecSMatthew Dillon done:
24462efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
24562efe6ecSMatthew Dillon if (keys[i])
24662efe6ecSMatthew Dillon RSA_free(keys[i]);
24762efe6ecSMatthew Dillon }
24862efe6ecSMatthew Dillon free(keys);
24962efe6ecSMatthew Dillon free(ispub);
25062efe6ecSMatthew Dillon return (ecode);
25162efe6ecSMatthew Dillon }
25262efe6ecSMatthew Dillon
25362efe6ecSMatthew Dillon int
cmd_rsadec(const char ** keyfiles,int nkeys)25462efe6ecSMatthew Dillon cmd_rsadec(const char **keyfiles, int nkeys)
25562efe6ecSMatthew Dillon {
25662efe6ecSMatthew Dillon RSA **keys = calloc(nkeys, sizeof(RSA *));
25762efe6ecSMatthew Dillon int *ispub = calloc(nkeys, sizeof(int));
25862efe6ecSMatthew Dillon int ecode = 0;
25962efe6ecSMatthew Dillon int blksize = 0;
26062efe6ecSMatthew Dillon int i;
26162efe6ecSMatthew Dillon int off;
26262efe6ecSMatthew Dillon int n;
26362efe6ecSMatthew Dillon unsigned char *data_in;
26462efe6ecSMatthew Dillon unsigned char *data_out;
26562efe6ecSMatthew Dillon
26662efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
26762efe6ecSMatthew Dillon FILE *fp;
26862efe6ecSMatthew Dillon const char *sfx;
26962efe6ecSMatthew Dillon
27062efe6ecSMatthew Dillon sfx = strrchr(keyfiles[i], '.');
27162efe6ecSMatthew Dillon if (sfx && strcmp(sfx, ".pub") == 0) {
27262efe6ecSMatthew Dillon fp = fopen(keyfiles[i], "r");
27362efe6ecSMatthew Dillon if (fp == NULL) {
27462efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
27562efe6ecSMatthew Dillon "open %s\n", keyfiles[i]);
27662efe6ecSMatthew Dillon ecode = 1;
27762efe6ecSMatthew Dillon goto done;
27862efe6ecSMatthew Dillon }
27962efe6ecSMatthew Dillon keys[i] = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
28062efe6ecSMatthew Dillon ispub[i] = 1;
28162efe6ecSMatthew Dillon fclose(fp);
28262efe6ecSMatthew Dillon if (keys[i] == NULL) {
28362efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
28462efe6ecSMatthew Dillon "parse public key from %s\n",
28562efe6ecSMatthew Dillon keyfiles[i]);
28662efe6ecSMatthew Dillon ecode = 1;
28762efe6ecSMatthew Dillon goto done;
28862efe6ecSMatthew Dillon }
28962efe6ecSMatthew Dillon } else if (sfx && strcmp(sfx, ".prv") == 0) {
29062efe6ecSMatthew Dillon fp = fopen(keyfiles[i], "r");
29162efe6ecSMatthew Dillon if (fp == NULL) {
29262efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
29362efe6ecSMatthew Dillon "open %s\n", keyfiles[i]);
29462efe6ecSMatthew Dillon ecode = 1;
29562efe6ecSMatthew Dillon goto done;
29662efe6ecSMatthew Dillon }
29762efe6ecSMatthew Dillon keys[i] = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
29862efe6ecSMatthew Dillon fclose(fp);
29962efe6ecSMatthew Dillon if (keys[i] == NULL) {
30062efe6ecSMatthew Dillon fprintf(stderr, "hammer2 rsaenc: unable to "
30162efe6ecSMatthew Dillon "parse private key from %s\n",
30262efe6ecSMatthew Dillon keyfiles[i]);
30362efe6ecSMatthew Dillon ecode = 1;
30462efe6ecSMatthew Dillon goto done;
30562efe6ecSMatthew Dillon }
30662efe6ecSMatthew Dillon } else {
30762efe6ecSMatthew Dillon fprintf(stderr, "hammer2: rsaenc: key files must end "
30862efe6ecSMatthew Dillon "in .pub or .prv\n");
30962efe6ecSMatthew Dillon ecode = 1;
31062efe6ecSMatthew Dillon goto done;
31162efe6ecSMatthew Dillon }
31262efe6ecSMatthew Dillon if (i == 0)
31362efe6ecSMatthew Dillon blksize = RSA_size(keys[i]);
31462efe6ecSMatthew Dillon else
31562efe6ecSMatthew Dillon assert(blksize == RSA_size(keys[i]));
31662efe6ecSMatthew Dillon }
31762efe6ecSMatthew Dillon
31862efe6ecSMatthew Dillon /*
31962efe6ecSMatthew Dillon *
32062efe6ecSMatthew Dillon */
32162efe6ecSMatthew Dillon data_in = malloc(blksize);
32262efe6ecSMatthew Dillon data_out = malloc(blksize);
32362efe6ecSMatthew Dillon off = 0;
32462efe6ecSMatthew Dillon while ((n = read(0, data_in + off, blksize - off)) > 0) {
32562efe6ecSMatthew Dillon off += n;
32662efe6ecSMatthew Dillon if (off == blksize) {
32762efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
32862efe6ecSMatthew Dillon if (ispub[i])
32962efe6ecSMatthew Dillon RSA_public_decrypt(blksize,
33062efe6ecSMatthew Dillon data_in, data_out,
33162efe6ecSMatthew Dillon keys[i],
33262efe6ecSMatthew Dillon RSA_NO_PADDING);
33362efe6ecSMatthew Dillon else
33462efe6ecSMatthew Dillon RSA_private_decrypt(blksize,
33562efe6ecSMatthew Dillon data_in, data_out,
33662efe6ecSMatthew Dillon keys[i],
33762efe6ecSMatthew Dillon RSA_NO_PADDING);
33862efe6ecSMatthew Dillon if (i + 1 != nkeys)
33962efe6ecSMatthew Dillon bcopy(data_out, data_in, blksize);
34062efe6ecSMatthew Dillon }
34162efe6ecSMatthew Dillon if (write(1, data_out, blksize) != blksize) {
34262efe6ecSMatthew Dillon perror("write");
34362efe6ecSMatthew Dillon ecode = 1;
34462efe6ecSMatthew Dillon break;
34562efe6ecSMatthew Dillon }
34662efe6ecSMatthew Dillon off = 0;
34762efe6ecSMatthew Dillon }
34862efe6ecSMatthew Dillon }
34962efe6ecSMatthew Dillon if (off) {
35062efe6ecSMatthew Dillon if (off < blksize)
35162efe6ecSMatthew Dillon bzero(data_in + off, blksize - off);
35262efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
35362efe6ecSMatthew Dillon if (ispub[i])
35462efe6ecSMatthew Dillon RSA_public_decrypt(blksize,
35562efe6ecSMatthew Dillon data_in, data_out,
35662efe6ecSMatthew Dillon keys[i],
35762efe6ecSMatthew Dillon RSA_NO_PADDING);
35862efe6ecSMatthew Dillon else
35962efe6ecSMatthew Dillon RSA_private_decrypt(blksize,
36062efe6ecSMatthew Dillon data_in, data_out,
36162efe6ecSMatthew Dillon keys[i],
36262efe6ecSMatthew Dillon RSA_NO_PADDING);
36362efe6ecSMatthew Dillon if (i + 1 != nkeys)
36462efe6ecSMatthew Dillon bcopy(data_out, data_in, blksize);
36562efe6ecSMatthew Dillon }
36662efe6ecSMatthew Dillon if (write(1, data_out, blksize) != blksize) {
36762efe6ecSMatthew Dillon perror("write");
36862efe6ecSMatthew Dillon ecode = 1;
36962efe6ecSMatthew Dillon }
37062efe6ecSMatthew Dillon }
37162efe6ecSMatthew Dillon if (n < 0) {
37262efe6ecSMatthew Dillon perror("read");
37362efe6ecSMatthew Dillon ecode = 1;
37462efe6ecSMatthew Dillon }
37562efe6ecSMatthew Dillon free(data_out);
37662efe6ecSMatthew Dillon free(data_in);
37762efe6ecSMatthew Dillon done:
37862efe6ecSMatthew Dillon for (i = 0; i < nkeys; ++i) {
37962efe6ecSMatthew Dillon if (keys[i])
38062efe6ecSMatthew Dillon RSA_free(keys[i]);
38162efe6ecSMatthew Dillon }
38262efe6ecSMatthew Dillon free(keys);
38362efe6ecSMatthew Dillon free(ispub);
38462efe6ecSMatthew Dillon return (ecode);
38562efe6ecSMatthew Dillon }
386