/* * Produce the signature for an assertion. */ char * kn_sign_assertion(char *buf, int buflen, char *key, char *sigalg, int vflag) { int i, alg, hashtype, encoding, internalenc; struct keynote_deckey dc; struct assertion *as; char *s, *sig; keynote_errno = 0; s = NULL; if (sigalg == NULL || buf == NULL || key == NULL) { keynote_errno = ERROR_NOTFOUND; return NULL; } if (sigalg[0] == '\0' || sigalg[strlen(sigalg) - 1] != ':') { keynote_errno = ERROR_SYNTAX; return NULL; } /* We're using a different format for X509 private keys, so... */ alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding, &internalenc); if (alg != KEYNOTE_ALGORITHM_X509) { /* Parse the private key */ s = keynote_get_private_key(key); if (s == NULL) return NULL; /* Decode private key */ i = kn_decode_key(&dc, s, KEYNOTE_PRIVATE_KEY); if (i == -1) { free(s); return NULL; } } else /* X509 private key */ { dc.dec_key = key; dc.dec_algorithm = alg; } as = keynote_parse_assertion(buf, buflen, ASSERT_FLAG_SIGGEN); if (as == NULL) { if (alg != KEYNOTE_ALGORITHM_X509) { keynote_free_key(dc.dec_key, dc.dec_algorithm); free(s); } return NULL; } sig = keynote_sign_assertion(as, sigalg, dc.dec_key, dc.dec_algorithm, vflag); if (alg != KEYNOTE_ALGORITHM_X509) keynote_free_key(dc.dec_key, dc.dec_algorithm); keynote_free_assertion(as); if (s != NULL) free(s); return sig; }
/* * Find and decode the configured key (pre-shared or public) for the * peer denoted by ID. Stash the len in KEYLEN. */ static void * ike_auth_get_key (int type, char *id, char *local_id, size_t *keylen) { char *key, *buf; #if defined (USE_X509) || defined (USE_KEYNOTE) char *keyfile; #if defined (USE_X509) BIO *keyh; RSA *rsakey; size_t fsize; #endif #endif switch (type) { case IKE_AUTH_PRE_SHARED: /* Get the pre-shared key for our peer. */ key = conf_get_str (id, "Authentication"); if (!key && local_id) key = conf_get_str (local_id, "Authentication"); if (!key) { log_print ("ike_auth_get_key: " "no key found for peer \"%s\" or local ID \"%s\"", id, local_id); return 0; } /* If the key starts with 0x it is in hex format. */ if (strncasecmp (key, "0x", 2) == 0) { *keylen = (strlen (key) - 1) / 2; buf = malloc (*keylen); if (!buf) { log_print ("ike_auth_get_key: malloc (%lu) failed", (unsigned long)*keylen); return 0; } if (hex2raw (key + 2, (unsigned char *)buf, *keylen)) { free (buf); log_print ("ike_auth_get_key: invalid hex key %s", key); return 0; } key = buf; } else *keylen = strlen (key); break; case IKE_AUTH_RSA_SIG: #if defined (USE_X509) || defined (USE_KEYNOTE) #if defined (USE_KEYNOTE) if (local_id && (keyfile = conf_get_str ("KeyNote", "Credential-directory")) != 0) { struct stat sb; struct keynote_deckey dc; char *privkeyfile, *buf2; int fd, pkflen; size_t size; pkflen = strlen (keyfile) + strlen (local_id) + sizeof PRIVATE_KEY_FILE + sizeof "//" - 1; privkeyfile = calloc (pkflen, sizeof (char)); if (!privkeyfile) { log_print ("ike_auth_get_key: failed to allocate %d bytes", pkflen); return 0; } snprintf (privkeyfile, pkflen, "%s/%s/%s", keyfile, local_id, PRIVATE_KEY_FILE); keyfile = privkeyfile; if (stat (keyfile, &sb) < 0) { free (keyfile); goto ignorekeynote; } size = (size_t)sb.st_size; fd = open (keyfile, O_RDONLY, 0); if (fd < 0) { log_print ("ike_auth_get_key: failed opening \"%s\"", keyfile); free (keyfile); return 0; } buf = calloc (size + 1, sizeof (char)); if (!buf) { log_print ("ike_auth_get_key: failed allocating %lu bytes", (unsigned long)size + 1); free (keyfile); return 0; } if (read (fd, buf, size) != size) { free (buf); log_print ("ike_auth_get_key: " "failed reading %lu bytes from \"%s\"", (unsigned long)size, keyfile); free (keyfile); return 0; } close (fd); /* Parse private key string */ buf2 = kn_get_string (buf); free (buf); if (kn_decode_key (&dc, buf2, KEYNOTE_PRIVATE_KEY) == -1) { free (buf2); log_print ("ike_auth_get_key: failed decoding key in \"%s\"", keyfile); free (keyfile); return 0; } free (buf2); if (dc.dec_algorithm != KEYNOTE_ALGORITHM_RSA) { log_print ("ike_auth_get_key: wrong algorithm type %d in \"%s\"", dc.dec_algorithm, keyfile); free (keyfile); kn_free_key (&dc); return 0; } free (keyfile); return dc.dec_key; } ignorekeynote: #endif /* USE_KEYNOTE */ #ifdef USE_X509 /* Otherwise, try X.509 */ keyfile = conf_get_str ("X509-certificates", "Private-key"); if (check_file_secrecy (keyfile, &fsize)) return 0; keyh = BIO_new (BIO_s_file ()); if (keyh == NULL) { log_print ("ike_auth_get_key: " "BIO_new (BIO_s_file ()) failed"); return 0; } if (BIO_read_filename (keyh, keyfile) == -1) { log_print ("ike_auth_get_key: " "BIO_read_filename (keyh, \"%s\") failed", keyfile); BIO_free (keyh); return 0; } #if SSLEAY_VERSION_NUMBER >= 0x00904100L rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL, NULL); #else rsakey = PEM_read_bio_RSAPrivateKey (keyh, NULL, NULL); #endif BIO_free (keyh); if (!rsakey) { log_print ("ike_auth_get_key: PEM_read_bio_RSAPrivateKey failed"); return 0; } return rsakey; #endif /* USE_X509 */ #endif /* USE_X509 || USE_KEYNOTE */ default: log_print ("ike_auth_get_key: unknown key type %d", type); return 0; } return key; }