/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd = fopen(filename, "r"); pem_init_logger(); if (fd) { int bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); rewind(fd); blob->ptr = malloc(blob->len); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); logger->log(logger, CONTROL, " loading %s file '%s' (%d bytes)", type, filename, bytes); *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { logger->log(logger, CONTROL|LEVEL1, " file coded in DER format"); return TRUE; } if (passphrase != NULL) logger->log_bytes(logger, PRIVATE, " passphrase:", passphrase->ptr, passphrase->len); /* try PEM format */ ugh = pem_to_bin(blob, passphrase, pgp); if (ugh == NULL) { if (*pgp) { logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format"); return TRUE; } if (is_asn1(*blob)) { logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format"); return TRUE; } ugh = "file coded in unknown format, discarded"; } /* a conversion error has occured */ logger->log(logger, ERROR, " %s", ugh); chunk_free(blob); } else { logger->log(logger, ERROR, " could not open %s file '%s'", type, filename); } return FALSE; }
/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool load_coded_file(const char *filename, prompt_pass_t *pass, int verbose, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd; fd = fopen(filename, "r"); if (fd) { int bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); rewind(fd); blob->ptr = alloc_bytes(blob->len, type); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); if(verbose) { openswan_log(" loaded %s file '%s' (%d bytes)", type, filename, bytes); } *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" file coded in DER format"); ) return TRUE; }
/** * load the credential from a blob */ static void *load_from_blob(chunk_t blob, credential_type_t type, int subtype, chunk_t(*cb)(void*,int), void *cb_data, x509_flag_t flags) { void *cred = NULL; bool pgp = FALSE; blob = chunk_clone(blob); if (!is_asn1(blob)) { if (pem_to_bin(&blob, cb, cb_data, &pgp) != SUCCESS) { chunk_clear(&blob); return NULL; } if (pgp && type == CRED_PRIVATE_KEY) { /* PGP encoded keys are parsed with a KEY_ANY key type, as it * can contain any type of key. However, ipsec.secrets uses * RSA for PGP keys, which is actually wrong. */ subtype = KEY_ANY; } } /* if CERT_ANY is given, ASN1 encoded blob is handled as X509 */ if (type == CRED_CERTIFICATE && subtype == CERT_ANY) { subtype = pgp ? CERT_GPG : CERT_X509; } cred = lib->creds->create(lib->creds, type, subtype, pgp ? BUILD_BLOB_PGP : BUILD_BLOB_ASN1_DER, blob, flags ? BUILD_X509_FLAG : BUILD_END, flags, BUILD_END); chunk_clear(&blob); return cred; }
/* * fetch an ASN.1 blob coded in PEM or DER format from a URL */ static err_t fetch_asn1_blob(char *url, chunk_t *blob) { err_t ugh = NULL; if (strlen(url) >= 4 && strncasecmp(url, "ldap", 4) == 0) { ugh = fetch_ldap_url(url, blob); } else { ugh = fetch_curl(url, blob); } if (ugh != NULL) return ugh; if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" fetched blob coded in DER format") ) } else { bool pgp = FALSE; ugh = pemtobin(blob, NULL, "", &pgp); if (ugh == NULL) { if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" fetched blob coded in PEM format") ) } else { ugh = "blob coded in unknown format"; pfree(blob->ptr); } } else { pfree(blob->ptr); } }
/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool load_coded_file(const char *filename, prompt_pass_t *pass, int verbose, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd; fd = fopen(filename, "r"); if (fd) { size_t bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); if (blob->len <= 0) { if (verbose) openswan_log(" discarded %s file '%s', bad size %zu bytes", type, filename, blob->len); fclose(fd); return FALSE; } rewind(fd); blob->ptr = alloc_bytes(blob->len, type); bytes = fread(blob->ptr, 1, blob->len, fd); if(bytes != blob->len) { openswan_log(" WARNING: could not fully read certificate-blob filename '%s'\n", filename); } fclose(fd); if(verbose) { openswan_log(" loaded %s file '%s' (%zu bytes)", type, filename, bytes); } *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { DBG(DBG_PARSING, DBG_log(" file coded in DER format"); ) return TRUE; }
/* * Decode the CR payload of Phase 1. */ void decode_cr(struct msg_digest *md, generalName_t **requested_ca) { struct payload_digest *p; for (p = md->chain[ISAKMP_NEXT_CR]; p != NULL; p = p->next) { struct isakmp_cr *const cr = &p->payload.cr; chunk_t ca_name; ca_name.len = pbs_left(&p->pbs); ca_name.ptr = (ca_name.len > 0)? p->pbs.cur : NULL; DBG_cond_dump_chunk(DBG_PARSING, "CR", ca_name); if (cr->isacr_type == CERT_X509_SIGNATURE) { if (ca_name.len > 0) { generalName_t *gn; if (!is_asn1(ca_name)) continue; gn = alloc_thing(generalName_t, "generalName"); clonetochunk(ca_name, ca_name.ptr,ca_name.len, "ca name"); gn->kind = GN_DIRECTORY_NAME; gn->name = ca_name; gn->next = *requested_ca; *requested_ca = gn; } DBG(DBG_PARSING | DBG_CONTROL, char buf[IDTOA_BUF]; dntoa_or_null(buf, IDTOA_BUF, ca_name, "%any"); DBG_log("requested CA: '%s'", buf); ) } else loglog(RC_LOG_SERIOUS, "ignoring %s certificate request payload", enum_show(&cert_type_names, cr->isacr_type)); }
END_TEST /******************************************************************************* * is_asn1 */ START_TEST(test_is_asn1) { typedef struct { bool asn1; chunk_t chunk; } testdata_t; u_char buf[8]; chunk_t chunk_zero = { buf, 0 }; chunk_t chunk_mean = { 0, 1 }; testdata_t test[] = { { FALSE, chunk_zero }, { FALSE, chunk_empty }, { FALSE, chunk_mean }, { TRUE, chunk_from_chars(0x30, 0x00) }, { TRUE, chunk_from_chars(0x31, 0x00) }, { TRUE, chunk_from_chars(0x04, 0x00) }, { FALSE, chunk_from_chars(0x02, 0x00) }, { FALSE, chunk_from_chars(0x30, 0x01) }, { FALSE, chunk_from_chars(0x30, 0x80) }, { TRUE, chunk_from_chars(0x30, 0x01, 0xa1) }, { FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2) }, { TRUE, chunk_from_chars(0x30, 0x01, 0xa1, 0x0a) }, { FALSE, chunk_from_chars(0x30, 0x01, 0xa1, 0xa2, 0x0a) }, }; int i; for (i = 0; i < countof(test); i++) { ck_assert(is_asn1(test[i].chunk) == test[i].asn1); } }