+
+ if (os->rawder == NULL && os->rawpem == NULL
+ && os->pk8der == NULL && os->pk8pem == NULL)
+ {
+ return 1;
+ }
+ if (br_ec_compute_pub(br_ec_get_default(), &pk, kbuf, sk) == 0) {
+ fprintf(stderr,
+ "ERROR: cannot re-encode (unsupported curve)\n");
+ return 0;
+ }
+
+ r = 1;
+ if (os->rawder != NULL || os->rawpem != NULL) {
+ len = br_encode_ec_raw_der(NULL, sk, &pk);
+ if (len == 0) {
+ fprintf(stderr, "ERROR: cannot re-encode"
+ " (unsupported curve)\n");
+ return 0;
+ }
+ buf = xmalloc(len);
+ if (br_encode_ec_raw_der(buf, sk, &pk) != len) {
+ fprintf(stderr, "ERROR: re-encode failure\n");
+ xfree(buf);
+ return 0;
+ }
+ if (os->rawder != NULL) {
+ r &= write_to_file(os->rawder, buf, len);
+ }
+ if (os->rawpem != NULL) {
+ r &= write_to_pem_file(os->rawpem,
+ buf, len, "EC PRIVATE KEY");
+ }
+ xfree(buf);
+ }
+ if (os->pk8der != NULL || os->pk8pem != NULL) {
+ len = br_encode_ec_pkcs8_der(NULL, sk, &pk);
+ if (len == 0) {
+ fprintf(stderr, "ERROR: cannot re-encode"
+ " (unsupported curve)\n");
+ return 0;
+ }
+ buf = xmalloc(len);
+ if (br_encode_ec_pkcs8_der(buf, sk, &pk) != len) {
+ fprintf(stderr, "ERROR: re-encode failure\n");
+ xfree(buf);
+ return 0;
+ }
+ if (os->pk8der != NULL) {
+ r &= write_to_file(os->pk8der, buf, len);
+ }
+ if (os->pk8pem != NULL) {
+ r &= write_to_pem_file(os->pk8pem,
+ buf, len, "PRIVATE KEY");
+ }
+ xfree(buf);
+ }
+ return r;
+}
+
+static int
+parse_rsa_spec(const char *kgen_spec, unsigned *size, uint32_t *pubexp)
+{
+ const char *p;
+ char *end;
+ unsigned long ul;
+
+ p = kgen_spec;
+ if (*p != 'r' && *p != 'R') {
+ return 0;
+ }
+ p ++;
+ if (*p != 's' && *p != 'S') {
+ return 0;
+ }
+ p ++;
+ if (*p != 'a' && *p != 'A') {
+ return 0;
+ }
+ p ++;
+ if (*p == 0) {
+ *size = 2048;
+ *pubexp = 3;
+ return 1;
+ } else if (*p != ':') {
+ return 0;
+ }
+ p ++;
+ ul = strtoul(p, &end, 10);
+ if (ul < 512 || ul > 32768) {
+ return 0;
+ }
+ *size = ul;
+ p = end;
+ if (*p == 0) {
+ *pubexp = 3;
+ return 1;
+ } else if (*p != ':') {
+ return 0;
+ }
+ p ++;
+ ul = strtoul(p, &end, 10);
+ if ((ul & 1) == 0 || ul == 1 || ((ul >> 30) >> 2) != 0) {
+ return 0;
+ }
+ *pubexp = ul;
+ if (*end != 0) {
+ return 0;
+ }
+ return 1;