int dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv, const char *directory) { FILE *fp; int ret, i; isc_result_t iret; char filename[ISC_DIR_NAMEMAX]; char buffer[MAXFIELDSIZE * 2]; isc_buffer_t b; isc_fsaccess_t access; REQUIRE(priv != NULL); if (check_data(priv, dst_key_alg(key), ISC_FALSE) < 0) return (DST_R_INVALIDPRIVATEKEY); isc_buffer_init(&b, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b); if (ret != ISC_R_SUCCESS) return (ret); if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); /* XXXDCL return value should be checked for full filesystem */ fprintf(fp, "%s v%d.%d\n", PRIVATE_KEY_STR, MAJOR_VERSION, MINOR_VERSION); fprintf(fp, "%s %d ", ALGORITHM_STR, dst_key_alg(key)); /* XXXVIX this switch statement is too sparse to gen a jump table. */ switch (dst_key_alg(key)) { case DST_ALG_RSAMD5: fprintf(fp, "(RSA)\n"); break; case DST_ALG_DH: fprintf(fp, "(DH)\n"); break; case DST_ALG_DSA: fprintf(fp, "(DSA)\n"); break; case DST_ALG_RSASHA1: fprintf(fp, "(RSASHA1)\n"); break; case DST_ALG_NSEC3DSA: fprintf(fp, "(NSEC3DSA)\n"); break; case DST_ALG_NSEC3RSASHA1: fprintf(fp, "(NSEC3RSASHA1)\n"); break; case DST_ALG_RSASHA256: fprintf(fp, "(RSASHA256)\n"); break; case DST_ALG_RSASHA512: fprintf(fp, "(RSASHA512)\n"); break; case DST_ALG_HMACMD5: fprintf(fp, "(HMAC_MD5)\n"); break; case DST_ALG_HMACSHA1: fprintf(fp, "(HMAC_SHA1)\n"); break; case DST_ALG_HMACSHA224: fprintf(fp, "(HMAC_SHA224)\n"); break; case DST_ALG_HMACSHA256: fprintf(fp, "(HMAC_SHA256)\n"); break; case DST_ALG_HMACSHA384: fprintf(fp, "(HMAC_SHA384)\n"); break; case DST_ALG_HMACSHA512: fprintf(fp, "(HMAC_SHA512)\n"); break; default: fprintf(fp, "(?)\n"); break; } for (i = 0; i < priv->nelements; i++) { isc_buffer_t b; isc_region_t r; const char *s; s = find_tag(priv->elements[i].tag); r.base = priv->elements[i].data; r.length = priv->elements[i].length; isc_buffer_init(&b, buffer, sizeof(buffer)); iret = isc_base64_totext(&r, sizeof(buffer), "", &b); if (iret != ISC_R_SUCCESS) { fclose(fp); return (DST_R_INVALIDPRIVATEKEY); } isc_buffer_usedregion(&b, &r); fprintf(fp, "%s ", s); isc_util_fwrite(r.base, 1, r.length, fp); fprintf(fp, "\n"); } fflush(fp); iret = ferror(fp) ? DST_R_WRITEERROR : ISC_R_SUCCESS; fclose(fp); return (iret); }
/*% * Writes a public key to disk in DNS format. */ static isc_result_t write_public_key(const dst_key_t *key, int type, const char *directory) { FILE *fp; isc_buffer_t keyb, textb, fileb, classb; isc_region_t r; char filename[ISC_DIR_NAMEMAX]; unsigned char key_array[DST_KEY_MAXSIZE]; char text_array[DST_KEY_MAXTEXTSIZE]; char class_array[10]; isc_result_t ret; dns_rdata_t rdata = DNS_RDATA_INIT; isc_fsaccess_t access; REQUIRE(VALID_KEY(key)); isc_buffer_init(&keyb, key_array, sizeof(key_array)); isc_buffer_init(&textb, text_array, sizeof(text_array)); isc_buffer_init(&classb, class_array, sizeof(class_array)); ret = dst_key_todns(key, &keyb); if (ret != ISC_R_SUCCESS) return (ret); isc_buffer_usedregion(&keyb, &r); dns_rdata_fromregion(&rdata, key->key_class, dns_rdatatype_dnskey, &r); ret = dns_rdata_totext(&rdata, (dns_name_t *) NULL, &textb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); ret = dns_rdataclass_totext(key->key_class, &classb); if (ret != ISC_R_SUCCESS) return (DST_R_INVALIDPUBLICKEY); /* * Make the filename. */ isc_buffer_init(&fileb, filename, sizeof(filename)); ret = dst_key_buildfilename(key, DST_TYPE_PUBLIC, directory, &fileb); if (ret != ISC_R_SUCCESS) return (ret); /* * Create public key file. */ if ((fp = fopen(filename, "w")) == NULL) return (DST_R_WRITEERROR); if (issymmetric(key)) { access = 0; isc_fsaccess_add(ISC_FSACCESS_OWNER, ISC_FSACCESS_READ | ISC_FSACCESS_WRITE, &access); (void)isc_fsaccess_set(filename, access); } /* Write key information in comments */ if ((type & DST_TYPE_KEY) == 0) { fprintf(fp, "; This is a %s%s-signing key, keyid %d, for ", (key->key_flags & DNS_KEYFLAG_REVOKE) != 0 ? "revoked " : "", (key->key_flags & DNS_KEYFLAG_KSK) != 0 ? "key" : "zone", key->key_id); ret = dns_name_print(key->key_name, fp); if (ret != ISC_R_SUCCESS) { fclose(fp); return (ret); } fputc('\n', fp); printtime(key, DST_TIME_CREATED, "; Created", fp); printtime(key, DST_TIME_PUBLISH, "; Publish", fp); printtime(key, DST_TIME_ACTIVATE, "; Activate", fp); printtime(key, DST_TIME_REVOKE, "; Revoke", fp); printtime(key, DST_TIME_INACTIVE, "; Inactive", fp); printtime(key, DST_TIME_DELETE, "; Delete", fp); } /* Now print the actual key */ ret = dns_name_print(key->key_name, fp); fprintf(fp, " "); isc_buffer_usedregion(&classb, &r); isc_util_fwrite(r.base, 1, r.length, fp); if ((type & DST_TYPE_KEY) != 0) fprintf(fp, " KEY "); else fprintf(fp, " DNSKEY "); isc_buffer_usedregion(&textb, &r); isc_util_fwrite(r.base, 1, r.length, fp); fputc('\n', fp); fflush(fp); if (ferror(fp)) ret = DST_R_WRITEERROR; fclose(fp); return (ret); }
static void output(void *closure, const char *text, int textlen) { UNUSED(closure); (void) isc_util_fwrite(text, 1, textlen, stdout); }