void str_from_uint8_hex(uint8_t input_value, char *output_str) { str_merge("0x", output_str, 0); get_hex_string(input_value>>4, output_str+2); get_hex_string(input_value, output_str+3); output_str[4] = '\0'; }
void str_from_uint32_hex(uint32_t input_value, char *output_str) { str_merge("0x", output_str, 0); get_hex_string(input_value>>28, output_str+2); get_hex_string(input_value>>24, output_str+3); get_hex_string(input_value>>20, output_str+4); get_hex_string(input_value>>16, output_str+5); get_hex_string(input_value>>12, output_str+6); get_hex_string(input_value>>8, output_str+7); get_hex_string(input_value>>4, output_str+8); get_hex_string(input_value, output_str+9); output_str[10] = '\0'; }
void rsamd5_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; RSA *rsa = NULL; u_char md5_hash[MD5_DIGEST_LENGTH]; val_log(ctx, LOG_DEBUG, "rsamd5_sigverify(): parsing the public key..."); if ((rsa = RSA_new()) == NULL) { val_log(ctx, LOG_INFO, "rsamd5_sigverify(): could not allocate rsa structure."); *key_status = VAL_AC_INVALID_KEY; return; }; if (rsamd5_parse_public_key(dnskey->public_key, dnskey->public_key_len, rsa) != VAL_NO_ERROR) { val_log(ctx, LOG_INFO, "rsamd5_sigverify(): Error in parsing public key."); RSA_free(rsa); *key_status = VAL_AC_INVALID_KEY; return; } memset(md5_hash, 0, MD5_DIGEST_LENGTH); MD5(data, data_len, (u_char *) md5_hash); val_log(ctx, LOG_DEBUG, "rsamd5_sigverify(): MD5 hash = %s", get_hex_string(md5_hash, MD5_DIGEST_LENGTH, buf, buflen)); val_log(ctx, LOG_DEBUG, "rsamd5_sigverify(): verifying RSA signature..."); if (RSA_verify(NID_md5, (u_char *) md5_hash, MD5_DIGEST_LENGTH, rrsig->signature, rrsig->signature_len, rsa) == 1) { val_log(ctx, LOG_INFO, "rsamd5_sigverify(): returned SUCCESS"); RSA_free(rsa); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "rsamd5_sigverify(): returned FAILURE"); RSA_free(rsa); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } return; }
static char * get_rr_string(struct val_rr_rec *rr, char *buf, size_t buflen) { char *ptr = buf; char *endptr = ptr + buflen; while (rr) { get_hex_string(rr->rr_rdata, rr->rr_rdata_length, ptr, endptr - ptr); ptr += strlen(ptr); rr = rr->rr_next; } return buf; }
/* * print a subset of fields from "struct nfs_args" that are otherwise * not being provided anywhere else. */ void print_nfs_args(const nfs_args_t *nap, u_long nfs_version) { int fhlen = 32; /* default: NFS V.2 file handle length is 32 */ #ifdef HAVE_TRANSPORT_TYPE_TLI struct netbuf *nbp; struct knetconfig *kncp; #else /* not HAVE_TRANSPORT_TYPE_TLI */ struct sockaddr_in *sap; #endif /* not HAVE_TRANSPORT_TYPE_TLI */ if (!nap) { plog(XLOG_DEBUG, "NULL nfs_args!"); return; } /* override default file handle size */ #ifdef FHSIZE fhlen = FHSIZE; #endif /* FHSIZE */ #ifdef NFS_FHSIZE fhlen = NFS_FHSIZE; #endif /* NFS_FHSIZE */ #ifdef HAVE_TRANSPORT_TYPE_TLI nbp = nap->addr; plog(XLOG_DEBUG, "NA->addr {netbuf} (maxlen=%d, len=%d) = \"%s\"", nbp->maxlen, nbp->len, get_hex_string(nbp->len, nbp->buf)); nbp = nap->syncaddr; plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp); kncp = nap->knconf; plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics); plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly); plog(XLOG_DEBUG, "NA->knconf->proto \"%s\"", kncp->knc_proto); plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev); /* don't print knconf->unused field */ #else /* not HAVE_TRANSPORT_TYPE_TLI */ # ifdef NFS_ARGS_T_ADDR_IS_POINTER sap = (struct sockaddr_in *) nap->addr; # else /* not NFS_ARGS_T_ADDR_IS_POINTER */ sap = (struct sockaddr_in *) &nap->addr; # endif /* not NFS_ARGS_T_ADDR_IS_POINTER */ plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"", (int) sizeof(struct sockaddr_in), get_hex_string(sizeof(struct sockaddr_in), (const char *)sap)); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN /* as per POSIX, sin_len need not be set (used internally by kernel) */ plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family); plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port); plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"", get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr)); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ #ifdef HAVE_NFS_ARGS_T_ADDRLEN plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen); #endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */ plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null"); #ifdef HAVE_NFS_ARGS_T_NAMLEN plog(XLOG_DEBUG, "NA->namlen = %d", nap->namlen); #endif /* HAVE_NFS_ARGS_T_NAMLEN */ #ifdef MNT2_NFS_OPT_FSNAME plog(XLOG_DEBUG, "NA->fsname = \"%s\"", nap->fsname ? nap->fsname : "null"); #endif /* MNT2_NFS_OPT_FSNAME */ #ifdef HAVE_NFS_ARGS_T_FHSIZE plog(XLOG_DEBUG, "NA->fhsize = %d", nap->fhsize); fhlen = nap->fhsize; #endif /* HAVE_NFS_ARGS_T_FHSIZE */ #ifdef HAVE_NFS_ARGS_T_FH_LEN plog(XLOG_DEBUG, "NA->fh_len = %d", nap->fh_len); fhlen = nap->fh_len; #endif /* HAVE_NFS_ARGS_T_FH_LEN */ /* * XXX: need to figure out how to correctly print file handles, * since some times they are pointers, and sometimes the real structure * is stored in nfs_args. Even if it is a pointer, it can be the actual * char[] array, or a structure containing multiple fields. */ plog(XLOG_DEBUG, "NA->filehandle = \"%s\"", get_hex_string(fhlen, (const char *) &nap->NFS_FH_FIELD)); #ifdef HAVE_NFS_ARGS_T_SOTYPE plog(XLOG_DEBUG, "NA->sotype = %d", nap->sotype); #endif /* HAVE_NFS_ARGS_T_SOTYPE */ #ifdef HAVE_NFS_ARGS_T_PROTO plog(XLOG_DEBUG, "NA->proto = %d", (int) nap->proto); #endif /* HAVE_NFS_ARGS_T_PROTO */ #ifdef HAVE_NFS_ARGS_T_VERSION plog(XLOG_DEBUG, "NA->version = %d", nap->version); #endif /* HAVE_NFS_ARGS_T_VERSION */ plog(XLOG_DEBUG, "NA->flags = 0x%x", (int) nap->flags); plog(XLOG_DEBUG, "NA->rsize = %d", (int) nap->rsize); plog(XLOG_DEBUG, "NA->wsize = %d", (int) nap->wsize); #ifdef HAVE_NFS_ARGS_T_BSIZE plog(XLOG_DEBUG, "NA->bsize = %d", nap->bsize); #endif /* HAVE_NFS_ARGS_T_BSIZE */ plog(XLOG_DEBUG, "NA->timeo = %d", (int) nap->timeo); plog(XLOG_DEBUG, "NA->retrans = %d", (int) nap->retrans); #ifdef HAVE_NFS_ARGS_T_ACREGMIN plog(XLOG_DEBUG, "NA->acregmin = %d", (int) nap->acregmin); plog(XLOG_DEBUG, "NA->acregmax = %d", (int) nap->acregmax); plog(XLOG_DEBUG, "NA->acdirmin = %d", (int) nap->acdirmin); plog(XLOG_DEBUG, "NA->acdirmax = %d", (int) nap->acdirmax); #endif /* HAVE_NFS_ARGS_T_ACREGMIN */ #ifdef MNTTAB_OPT_SYMTTL plog(XLOG_DEBUG, "NA->symttl = %d", nap->symttl); #endif /* MNTTAB_OPT_SYMTTL */ #ifdef MNTTAB_OPT_PG_THRESH plog(XLOG_DEBUG, "NA->pg_thresh = %d", nap->pg_thresh); #endif /* MNTTAB_OPT_PG_THRESH */ #ifdef MNT2_NFS_OPT_BIODS plog(XLOG_DEBUG, "NA->biods = %d", nap->biods); #endif /* MNT2_NFS_OPT_BIODS */ }
void dsasha1_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; DSA *dsa = NULL; u_char sha1_hash[SHA_DIGEST_LENGTH]; u_char sig_asn1[2+2*(3+SHA_DIGEST_LENGTH)]; val_log(ctx, LOG_DEBUG, "dsasha1_sigverify(): parsing the public key..."); if ((dsa = DSA_new()) == NULL) { val_log(ctx, LOG_INFO, "dsasha1_sigverify(): could not allocate dsa structure."); *key_status = VAL_AC_INVALID_KEY; return; }; if (dsasha1_parse_public_key (dnskey->public_key, dnskey->public_key_len, dsa) != VAL_NO_ERROR) { val_log(ctx, LOG_INFO, "dsasha1_sigverify(): Error in parsing public key."); DSA_free(dsa); *key_status = VAL_AC_INVALID_KEY; return; } memset(sha1_hash, 0, SHA_DIGEST_LENGTH); SHA1(data, data_len, sha1_hash); val_log(ctx, LOG_DEBUG, "dsasha1_sigverify(): SHA-1 hash = %s", get_hex_string(sha1_hash, SHA_DIGEST_LENGTH, buf, buflen)); val_log(ctx, LOG_DEBUG, "dsasha1_sigverify(): verifying DSA signature..."); /* * Fix: courtesy tom.fowler * First convert the signature into its DER representation * 0x30, 0x2E, - ASN1 sequence * 0x02, 0x15, - ASN integer, length 21 bytes * 0x00, <R bytes> - 1 + 20 bytes per 2536 * 0x02, 0x15, - ASN integer * 0x00, <S bytes> - 1 + 20 bytes per 2536 */ if (rrsig->signature_len < (1 + 2*SHA_DIGEST_LENGTH)) { /* dont have enough data */ val_log(ctx, LOG_INFO, "dsasha1_sigverify(): Error parsing DSA rrsig."); DSA_free(dsa); *sig_status = VAL_AC_INVALID_RRSIG; return; } memcpy(sig_asn1, "\x30\x2E\x02\x15\x00", 5); memcpy(sig_asn1+5, rrsig->signature+1, SHA_DIGEST_LENGTH); memcpy(sig_asn1+5+SHA_DIGEST_LENGTH, "\x02\x15\x00", 3); memcpy(sig_asn1+5+SHA_DIGEST_LENGTH+3, rrsig->signature+1+SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH); if (DSA_verify (NID_sha1, (u_char *) sha1_hash, SHA_DIGEST_LENGTH, sig_asn1, sizeof(sig_asn1), dsa) == 1) { val_log(ctx, LOG_INFO, "dsasha1_sigverify(): returned SUCCESS"); DSA_free(dsa); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "dsasha1_sigverify(): returned FAILURE"); DSA_free(dsa); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } return; }
void ecdsa_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; u_char sha_hash[MAX_DIGEST_LENGTH]; EC_KEY *eckey = NULL; BIGNUM *bn_x = NULL; BIGNUM *bn_y = NULL; ECDSA_SIG *ecdsa_sig; size_t hashlen = 0; ecdsa_sig = ECDSA_SIG_new(); memset(sha_hash, 0, sizeof(sha_hash)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): parsing the public key..."); if (rrsig->algorithm == ALG_ECDSAP256SHA256) { hashlen = SHA256_DIGEST_LENGTH; SHA256(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); /* P-256 */ } else if (rrsig->algorithm == ALG_ECDSAP384SHA384) { hashlen = SHA384_DIGEST_LENGTH; SHA384(data, data_len, sha_hash); eckey = EC_KEY_new_by_curve_name(NID_secp384r1); /* P-384 */ } if (eckey == NULL) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): could not create key for ECDSA group."); *key_status = VAL_AC_INVALID_KEY; goto err; }; /* * contruct an EC_POINT from the "Q" field in the * dnskey->public_key, dnskey->public_key_len */ if (dnskey->public_key_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): dnskey length does not match expected size."); *key_status = VAL_AC_INVALID_KEY; goto err; } bn_x = BN_bin2bn(dnskey->public_key, hashlen, NULL); bn_y = BN_bin2bn(&dnskey->public_key[hashlen], hashlen, NULL); if (1 != EC_KEY_set_public_key_affine_coordinates(eckey, bn_x, bn_y)) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Error associating ECSA structure with key."); *key_status = VAL_AC_INVALID_KEY; goto err; } val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): SHA hash = %s", get_hex_string(sha_hash, hashlen, buf, buflen)); val_log(ctx, LOG_DEBUG, "ecdsa_sigverify(): verifying ECDSA signature..."); /* * contruct ECDSA signature from the "r" and "s" fileds in * rrsig->signature, rrsig->signature_len */ if (rrsig->signature_len != 2*hashlen) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): Signature length does not match expected size."); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; goto err; } ECDSA_SIG_set0(ecdsa_sig, BN_bin2bn(rrsig->signature, hashlen, NULL), BN_bin2bn(&rrsig->signature[hashlen], hashlen, NULL)); if (ECDSA_do_verify(sha_hash, hashlen, ecdsa_sig, eckey) == 1) { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned SUCCESS"); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "ecdsa_sigverify(): returned FAILURE"); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } /* Free all structures allocated */ err: if (ecdsa_sig) ECDSA_SIG_free(ecdsa_sig); if (bn_x) BN_free(bn_x); if (bn_y) BN_free(bn_y); if (eckey) EC_KEY_free(eckey); return; }
void rsasha_sigverify(val_context_t * ctx, const u_char *data, size_t data_len, const val_dnskey_rdata_t * dnskey, const val_rrsig_rdata_t * rrsig, val_astatus_t * key_status, val_astatus_t * sig_status) { char buf[1028]; size_t buflen = 1024; RSA *rsa = NULL; u_char sha_hash[MAX_DIGEST_LENGTH]; size_t hashlen = 0; int nid = 0; val_log(ctx, LOG_DEBUG, "rsasha_sigverify(): parsing the public key..."); if ((rsa = RSA_new()) == NULL) { val_log(ctx, LOG_INFO, "rsasha_sigverify(): could not allocate rsa structure."); *key_status = VAL_AC_INVALID_KEY; return; }; if (rsa_parse_public_key (dnskey->public_key, (size_t)dnskey->public_key_len, rsa) != VAL_NO_ERROR) { val_log(ctx, LOG_INFO, "rsasha_sigverify(): Error in parsing public key."); RSA_free(rsa); *key_status = VAL_AC_INVALID_KEY; return; } memset(sha_hash, 0, sizeof(sha_hash)); if (rrsig->algorithm == ALG_RSASHA1 #ifdef LIBVAL_NSEC3 || rrsig->algorithm == ALG_NSEC3_RSASHA1 #endif ) { SHA1(data, data_len, sha_hash); hashlen = SHA_DIGEST_LENGTH; nid = NID_sha1; } else if (rrsig->algorithm == ALG_RSASHA256) { SHA256(data, data_len, sha_hash); hashlen = SHA256_DIGEST_LENGTH; nid = NID_sha256; } else if (rrsig->algorithm == ALG_RSASHA512) { SHA512(data, data_len, sha_hash); hashlen = SHA512_DIGEST_LENGTH; nid = NID_sha512; } else { val_log(ctx, LOG_INFO, "rsasha_sigverify(): Unkown algorithm."); RSA_free(rsa); *key_status = VAL_AC_INVALID_KEY; return; } val_log(ctx, LOG_DEBUG, "rsasha_sigverify(): SHA hash = %s", get_hex_string(sha_hash, hashlen, buf, buflen)); val_log(ctx, LOG_DEBUG, "rsasha_sigverify(): verifying RSA signature..."); if (RSA_verify (nid, sha_hash, hashlen, rrsig->signature, rrsig->signature_len, rsa) == 1) { val_log(ctx, LOG_INFO, "rsasha_sigverify(): returned SUCCESS"); RSA_free(rsa); *sig_status = VAL_AC_RRSIG_VERIFIED; } else { val_log(ctx, LOG_INFO, "rsasha_sigverify(): returned FAILURE"); RSA_free(rsa); *sig_status = VAL_AC_RRSIG_VERIFY_FAILED; } return; }