summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/analysis/db/certs.c198
-rw-r--r--src/analysis/db/certs.h6
2 files changed, 181 insertions, 23 deletions
diff --git a/src/analysis/db/certs.c b/src/analysis/db/certs.c
index 148abf2..22ff397 100644
--- a/src/analysis/db/certs.c
+++ b/src/analysis/db/certs.c
@@ -39,6 +39,7 @@
#include <i18n.h>
+#include "../../common/extstr.h"
#include "../../core/logs.h"
@@ -52,6 +53,9 @@ static bool add_extension_to_req(STACK_OF(X509_EXTENSION) *, int, /*const */char
/* Crée une paire de clefs RSA. */
static RSA *generate_rsa_key(unsigned int, unsigned long);
+/* Recharge l'identité inscrite dans un élément X509. */
+static bool load_identity_from_x509(/*const */X509_NAME *, x509_entries *);
+
/******************************************************************************
@@ -97,6 +101,70 @@ bool are_x509_entries_empty(const x509_entries *entries)
/******************************************************************************
* *
+* Paramètres : entries = éléments d'identité à convertir. *
+* *
+* Description : Traduit en chaîne de caractères une définition d'identité. *
+* *
+* Retour : Chaîne de caractères ou NULL. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+char *translate_x509_entries(const x509_entries *entries)
+{
+ char *result; /* Description à retourner */
+
+ result = NULL;
+
+ if (entries->country != NULL)
+ {
+ result = stradd(result, "C=");
+ result = stradd(result, entries->country);
+ }
+
+ if (entries->state != NULL)
+ {
+ if (result != NULL) result = stradd(result, "/");
+ result = stradd(result, "ST=");
+ result = stradd(result, entries->state);
+ }
+
+ if (entries->locality != NULL)
+ {
+ if (result != NULL) result = stradd(result, "/");
+ result = stradd(result, "L=");
+ result = stradd(result, entries->locality);
+ }
+
+ if (entries->organisation != NULL)
+ {
+ if (result != NULL) result = stradd(result, "/");
+ result = stradd(result, "O=");
+ result = stradd(result, entries->organisation);
+ }
+
+ if (entries->organisational_unit != NULL)
+ {
+ if (result != NULL) result = stradd(result, "/");
+ result = stradd(result, "OU=");
+ result = stradd(result, entries->organisational_unit);
+ }
+
+ if (entries->common_name != NULL)
+ {
+ if (result != NULL) result = stradd(result, "/");
+ result = stradd(result, "CN=");
+ result = stradd(result, entries->common_name);
+ }
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : entries = éléments d'identité à supprimer de la mémoire. *
* *
* Description : Libère la mémoire occupée par une définition d'identité. *
@@ -624,6 +692,64 @@ bool build_keys_and_request(const char *dir, const char *label, const x509_entri
/******************************************************************************
* *
+* Paramètres : subject = sujet d'un élément X509. *
+* entries = éléments de l'identité constituée. [OUT] *
+* *
+* Description : Recharge l'identité inscrite dans un élément X509. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
+
+static bool load_identity_from_x509(/*const */X509_NAME *subject, x509_entries *entries)
+{
+ bool result; /* Bilan à retourner */
+ int length; /* Taille du champ visé */
+
+ result = false;
+
+#define GET_NAME_ENTRY(key, value) \
+ do \
+ { \
+ length = X509_NAME_get_text_by_NID(subject, key, NULL, -1); \
+ if (length != -1) \
+ { \
+ entries->value = malloc((length + 1) * sizeof(char)); \
+ length = X509_NAME_get_text_by_NID(subject, key, entries->value, length + 1); \
+ assert(length != -1); \
+ if (length == -1) \
+ goto copy_failed; \
+ } \
+ } \
+ while (0)
+
+ GET_NAME_ENTRY(NID_countryName, country);
+
+ GET_NAME_ENTRY(NID_stateOrProvinceName, state);
+
+ GET_NAME_ENTRY(NID_localityName, locality);
+
+ GET_NAME_ENTRY(NID_organizationName, organisation);
+
+ GET_NAME_ENTRY(NID_organizationalUnitName, organisational_unit);
+
+ GET_NAME_ENTRY(NID_commonName, common_name);
+
+#undef GET_NAME_ENTRY
+
+ result = true;
+
+ copy_failed:
+
+ return result;
+
+}
+
+
+/******************************************************************************
+* *
* Paramètres : csr = fichier contenant le certificat à signer. *
* entries = éléments de l'identité constituée. [OUT] *
* *
@@ -641,7 +767,6 @@ bool load_identity_from_request(const char *csr, x509_entries *entries)
FILE *stream; /* Flux ouvert en lecture */
X509_REQ *req; /* Certificat X509 à signer */
X509_NAME *subject; /* Sujet du certificat */
- int length; /* Taille du champ visé */
result = false;
@@ -666,38 +791,65 @@ bool load_identity_from_request(const char *csr, x509_entries *entries)
subject = X509_REQ_get_subject_name(req);
-#define GET_NAME_ENTRY(key, value) \
- do \
- { \
- length = X509_NAME_get_text_by_NID(subject, key, NULL, -1); \
- if (length != -1) \
- { \
- entries->value = malloc((length + 1) * sizeof(char)); \
- length = X509_NAME_get_text_by_NID(subject, key, entries->value, length + 1); \
- assert(length != -1); \
- } \
- } \
- while (0)
+ result = load_identity_from_x509(subject, entries);
- GET_NAME_ENTRY(NID_countryName, country);
+ X509_REQ_free(req);
- GET_NAME_ENTRY(NID_stateOrProvinceName, state);
+ csr_read_failed:
- GET_NAME_ENTRY(NID_localityName, locality);
+ return result;
- GET_NAME_ENTRY(NID_organizationName, organisation);
+}
- GET_NAME_ENTRY(NID_organizationalUnitName, organisational_unit);
- GET_NAME_ENTRY(NID_commonName, common_name);
+/******************************************************************************
+* *
+* Paramètres : crt = fichier contenant un certificat signé. *
+* entries = éléments de l'identité constituée. [OUT] *
+* *
+* Description : Recharge l'identité inscrite dans un certificat signé. *
+* *
+* Retour : Bilan de l'opération. *
+* *
+* Remarques : - *
+* *
+******************************************************************************/
-#undef GET_NAME_ENTRY
+bool load_identity_from_cert(const char *crt, x509_entries *entries)
+{
+ bool result; /* Bilan à retourner */
+ FILE *stream; /* Flux ouvert en lecture */
+ X509 *x; /* Certificat X509 signé */
+ X509_NAME *subject; /* Sujet du certificat */
- X509_REQ_free(req);
+ result = false;
- result = true;
+ memset(entries, 0, sizeof(*entries));
- csr_read_failed:
+ /* Chargement de la requête */
+
+ stream = fopen(crt, "rb");
+ if (stream == NULL) goto crt_read_failed;
+
+ x = PEM_read_X509(stream, NULL, NULL, NULL);
+
+ fclose(stream);
+
+ if (x == NULL)
+ {
+ log_variadic_message(LMT_ERROR, _("Unable to read the signed certificate from '%s'"), crt);
+ goto crt_read_failed;
+ }
+
+ /* Recherche des éléments */
+
+ subject = X509_get_subject_name(x);
+
+ result = load_identity_from_x509(subject, entries);
+
+ X509_free(x);
+
+ crt_read_failed:
return result;
diff --git a/src/analysis/db/certs.h b/src/analysis/db/certs.h
index 51a2e34..359b3d3 100644
--- a/src/analysis/db/certs.h
+++ b/src/analysis/db/certs.h
@@ -45,6 +45,9 @@ typedef struct _x509_entries
/* Indique si une définition existe dans l'identité. */
bool are_x509_entries_empty(const x509_entries *);
+/* Traduit en chaîne de caractères une définition d'identité. */
+char *translate_x509_entries(const x509_entries *);
+
/* Libère la mémoire occupée par une définition d'identité. */
void free_x509_entries(x509_entries *);
@@ -57,6 +60,9 @@ bool build_keys_and_request(const char *, const char *, const x509_entries *);
/* Recharge l'identité inscrite dans une requête de signature. */
bool load_identity_from_request(const char *, x509_entries *);
+/* Recharge l'identité inscrite dans un certificat signé. */
+bool load_identity_from_cert(const char *, x509_entries *);
+
/* Signe un certificat pour application. */
bool sign_cert(const char *, const char *, const char *, const char *, unsigned long);