static void test_some_asn1_stuff (const ASN1_ARRAY_TYPE *defs, const gchar *file, const gchar *identifier) { GNode *asn; gpointer data, encoded; gsize n_data, n_encoded; if (!g_file_get_contents (file, (gchar**)&data, &n_data, NULL)) g_assert_not_reached (); asn = egg_asn1x_create (defs, identifier); egg_asn1x_dump (asn); if (!egg_asn1x_decode (asn, data, n_data)) g_warning ("decode of %s failed: %s", identifier, egg_asn1x_message (asn)); encoded = egg_asn1x_encode (asn, NULL, &n_encoded); if (encoded == NULL) g_warning ("encode of %s failed: %s", identifier, egg_asn1x_message (asn)); /* Decode the encoding */ if (!egg_asn1x_decode (asn, encoded, n_encoded)) g_warning ("decode of encoded %s failed: %s", identifier, egg_asn1x_message (asn)); egg_asn1x_clear (asn); egg_asn1x_destroy (asn); g_free (encoded); g_free (data); }
static gboolean gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, GBytes *data) { GkmXdgTrust *self = GKM_XDG_TRUST (base); GNode *asn = NULL; if (g_bytes_get_size (data) == 0) return FALSE; asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_val_if_fail (asn, FALSE); if (!egg_asn1x_decode (asn, data)) { g_warning ("couldn't parse trust data: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return FALSE; } /* Next parse out all the pairs */ if (!load_assertions (self, asn)) { egg_asn1x_destroy (asn); return FALSE; } /* Take ownership of this new data */ if (self->pv->bytes) g_bytes_unref (self->pv->bytes); self->pv->bytes = g_bytes_ref (data); egg_asn1x_destroy (self->pv->asn); self->pv->asn = asn; return TRUE; }
static GkmXdgTrust* create_trust_for_complete (GkmModule *module, GkmManager *manager, CK_ATTRIBUTE_PTR cert) { GkmXdgTrust *trust; GNode *asn, *ref, *node; GBytes *bytes; asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_val_if_fail (asn, NULL); ref = egg_asn1x_node (asn, "reference", NULL); node = egg_asn1x_node (ref, "certComplete", NULL); egg_asn1x_set_choice (ref, node); bytes = g_bytes_new (cert->pValue, cert->ulValueLen); egg_asn1x_set_any_raw (node, bytes); g_bytes_unref (bytes); trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL); trust->pv->asn = asn; /* Encode it, which validates, and so we have read access to all the data */ trust->pv->bytes = egg_asn1x_encode (asn, NULL); if (!trust->pv->bytes) { g_warning ("created invalid trust object: %s", egg_asn1x_message (asn)); return NULL; } return trust; }
static GkmXdgTrust* create_trust_for_reference (GkmModule *module, GkmManager *manager, CK_ATTRIBUTE_PTR serial, CK_ATTRIBUTE_PTR issuer) { GkmXdgTrust *trust; GNode *asn, *ref, *node; asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_val_if_fail (asn, NULL); ref = egg_asn1x_node (asn, "reference", NULL); node = egg_asn1x_node (ref, "certReference", NULL); egg_asn1x_set_choice (ref, node); egg_asn1x_set_integer_as_raw (egg_asn1x_node (node, "serialNumber", NULL), g_memdup (serial->pValue, serial->ulValueLen), serial->ulValueLen, g_free); egg_asn1x_set_raw_element (egg_asn1x_node (node, "issuer", NULL), g_memdup (issuer->pValue, issuer->ulValueLen), issuer->ulValueLen, g_free); trust = g_object_new (GKM_XDG_TYPE_TRUST, "module", module, "manager", manager, NULL); trust->pv->asn = asn; /* Encode it, so we have read access to all the data */ trust->pv->data = egg_asn1x_encode (asn, NULL, &trust->pv->n_data); if (!trust->pv->data) { g_warning ("created invalid trust object: %s", egg_asn1x_message (asn)); return NULL; } return trust; }
static gboolean validate_der (CK_ATTRIBUTE_PTR attr, const gchar *asn_type) { GNode *asn; gboolean valid = TRUE; GBytes *data; if (!attr->pValue || attr->ulValueLen == (CK_ULONG)-1) return FALSE; asn = egg_asn1x_create (pkix_asn1_tab, asn_type); g_return_val_if_fail (asn, FALSE); data = g_bytes_new_static (attr->pValue, attr->ulValueLen); valid = egg_asn1x_decode (asn, data); g_bytes_unref (data); if (!valid) g_message ("failed to parse certificate passed to trust assertion: %s", egg_asn1x_message (asn)); /* Yes, this is an expensive check, but worthwhile */ egg_asn1x_destroy (asn); return valid; }
guchar* gkm_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key) { GNode *asn = NULL; gcry_mpi_t x; guchar *result = NULL; x = NULL; asn = egg_asn1x_create (pk_asn1_tab, "DSAPrivatePart"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (skey, &x, "dsa", "x", NULL)) goto done; if (!gkm_data_asn1_write_mpi (asn, x)) goto done; result = egg_asn1x_encode (asn, egg_secure_realloc, n_key); if (result == NULL) g_warning ("couldn't encode private dsa key: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (x); return result; }
static gboolean gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login, gpointer *data, gsize *n_data) { GkmXdgTrust *self = GKM_XDG_TRUST (base); g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE); g_return_val_if_fail (data, FALSE); g_return_val_if_fail (n_data, FALSE); g_return_val_if_fail (self->pv->asn, FALSE); if (!save_assertions (self, self->pv->asn)) return FALSE; *data = egg_asn1x_encode (self->pv->asn, NULL, n_data); if (*data == NULL) { g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn)); return FALSE; } /* ASN.1 now refers to this data, take ownership */ g_free (self->pv->data); self->pv->data = *data; self->pv->n_data = *n_data; /* Return a duplicate, since we own encoded */ *data = g_memdup (*data, *n_data); return TRUE; }
guchar* gkm_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len) { GNode *asn = NULL; gcry_mpi_t n, e; guchar *result = NULL; n = e = NULL; asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) || !gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL)) goto done; if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e)) goto done; result = egg_asn1x_encode (asn, NULL, len); if (result == NULL) g_warning ("couldn't encode public rsa key: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (n); gcry_mpi_release (e); return result; }
static void on_subject_public_key (GObject *source, GAsyncResult *result, gpointer user_data) { GcrKeyRenderer *self = GCR_KEY_RENDERER (user_data); GError *error = NULL; GNode *node; node = _gcr_subject_public_key_load_finish (result, &error); if (error != NULL) { g_message ("couldn't load key information: %s", error->message); g_clear_error (&error); } else { if (self->pv->spk) g_bytes_unref (self->pv->spk); self->pv->spk = NULL; self->pv->spk = egg_asn1x_encode (node, NULL); if (self->pv->spk == NULL) g_warning ("invalid subjectPublicKey loaded: %s", egg_asn1x_message (node)); egg_asn1x_destroy (node); gcr_renderer_emit_data_changed (GCR_RENDERER (self)); } g_object_unref (self); }
guchar* gkm_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params) { GNode *asn = NULL; gcry_mpi_t p, q, g; guchar *result = NULL; p = q = g = NULL; asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) || !gkm_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) || !gkm_sexp_extract_mpi (skey, &g, "dsa", "g", NULL)) goto done; if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g)) goto done; result = egg_asn1x_encode (asn, egg_secure_realloc, n_params); if (result == NULL) g_warning ("couldn't encode private dsa params: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (g); return result; }
static void create_trust_file_for_certificate (const gchar *filename, const gchar *certificate) { GError *err = NULL; GNode *asn, *cert, *choice, *ref; GBytes *bytes, *result; gchar *data; gsize n_data; if (!g_file_get_contents (certificate, &data, &n_data, &err)) barf_and_die ("couldn't read certificate file", egg_error_message (err)); /* Make sure the certificate is */ cert = egg_asn1x_create (pkix_asn1_tab, "Certificate"); g_return_if_fail (cert); bytes = g_bytes_new_take (data, n_data); if (!egg_asn1x_decode (cert, bytes)) barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert)); asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_if_fail (asn); ref = egg_asn1x_node (asn, "reference", NULL); choice = egg_asn1x_node (ref, "certComplete", NULL); if (!egg_asn1x_set_choice (ref, choice) || !egg_asn1x_set_any_raw (choice, bytes)) g_return_if_reached (); g_bytes_unref (bytes); result = egg_asn1x_encode (asn, NULL); if (result == NULL) barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); egg_asn1x_destroy (cert); if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL), g_bytes_get_size (result), &err)) barf_and_die ("couldn't write trust file", egg_error_message (err)); g_bytes_unref (result); }
static void add_trust_purpose_to_file (const gchar *filename, const gchar *purpose) { GError *err = NULL; gchar *data; GBytes *result; gsize n_data; GNode *asn, *assertion; GBytes *bytes; if (!g_file_get_contents (filename, &data, &n_data, &err)) barf_and_die ("couldn't read trust file", egg_error_message (err)); /* Create up the trust structure */ asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_if_fail (asn); /* And parse it */ bytes = g_bytes_new_take (data, n_data); if (!egg_asn1x_decode (asn, bytes)) barf_and_die ("couldn't parse trust file", egg_asn1x_message (asn)); g_bytes_unref (bytes); assertion = egg_asn1x_append (egg_asn1x_node (asn, "assertions", NULL)); g_return_if_fail (assertion); if (!egg_asn1x_set_string_as_utf8 (egg_asn1x_node (assertion, "purpose", NULL), g_strdup (purpose), g_free)) g_return_if_reached (); egg_asn1x_set_enumerated (egg_asn1x_node (assertion, "level", NULL), g_quark_from_string ("trusted")); result = egg_asn1x_encode (asn, NULL); if (result == NULL) barf_and_die ("couldn't encode trust file", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL), g_bytes_get_size (result), &err)) barf_and_die ("couldn't write trust file", egg_error_message (err)); g_bytes_unref (result); }
guchar* gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password, gsize n_password, gsize *n_data) { gcry_error_t gcry; gcry_cipher_hd_t cih; GNode *asn = NULL; guchar *key, *data; gsize n_key, block = 0; /* Encode the key in normal pkcs8 fashion */ key = gkm_data_der_write_private_pkcs8_plain (skey, &n_key); if (key == NULL) return NULL; asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Create a and write out a cipher used for encryption */ cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block); g_return_val_if_fail (cih, NULL); /* Pad the block of data */ if(block > 1) { gsize pad; guchar *padded; pad = block - (n_key % block); if (pad == 0) pad = block; padded = egg_secure_realloc (key, n_key + pad); memset (padded + n_key, pad, pad); key = padded; n_key += pad; } gcry = gcry_cipher_encrypt (cih, key, n_key, NULL, 0); g_return_val_if_fail (gcry == 0, NULL); gcry_cipher_close (cih); if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), key, n_key, egg_secure_free)) g_return_val_if_reached (NULL); data = egg_asn1x_encode (asn, NULL, n_data); if (data == NULL) g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }
GBytes * gkm_data_der_write_certificate (GNode *asn1) { GBytes *result; g_return_val_if_fail (asn1, NULL); result = egg_asn1x_encode (asn1, NULL); if (result == NULL) g_warning ("couldn't encode certificate: %s", egg_asn1x_message (asn1)); return result; }
guchar* gkm_data_der_write_certificate (GNode *asn1, gsize *n_data) { gpointer result; g_return_val_if_fail (asn1, NULL); g_return_val_if_fail (n_data, NULL); result = egg_asn1x_encode (asn1, NULL, n_data); if (result == NULL) g_warning ("couldn't encode certificate: %s", egg_asn1x_message (asn1)); return result; }
int main(int argc, char* argv[]) { GError *err = NULL; gchar *contents; gsize n_contents; GNode *asn, *node; gint i, count; if (argc != 2) { g_printerr ("usage: dump-trust-file file\n"); return 2; } if (!g_file_get_contents (argv[1], &contents, &n_contents, &err)) barf_and_die ("couldn't load file", egg_error_message (err)); asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_val_if_fail (asn, 1); if (!egg_asn1x_decode (asn, contents, n_contents)) barf_and_die ("couldn't parse file", egg_asn1x_message (asn)); /* Print out the certificate we refer to first */ node = egg_asn1x_node (asn, "reference", "certReference", NULL); if (egg_asn1x_have (node)) { dump_certificate_reference (node); } else { node = egg_asn1x_node (asn, "reference", "certComplete", NULL); if (egg_asn1x_have (node)) dump_certificate_complete (node); else barf_and_die ("unsupported certificate reference", NULL); } /* Then the assertions */ count = egg_asn1x_count (egg_asn1x_node (asn, "assertions", NULL)); for (i = 0; i < count; ++i) { node = egg_asn1x_node (asn, "assertions", i + 1, NULL); dump_assertion (node); } egg_asn1x_destroy (asn); g_free (contents); return 0; }
static void test_personal_name_invalid (Test *test, gconstpointer unused) { GNode *asn; gboolean ret; asn = egg_asn1x_create (pkix_asn1_tab, "PersonalName"); if (g_test_verbose ()) egg_asn1x_dump (asn); ret = egg_asn1x_decode (asn, test->data); g_assert (ret == FALSE); g_assert (strstr (egg_asn1x_message (asn), "content size is out of bounds") != NULL); egg_asn1x_destroy (asn); }
guchar* gkm_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len) { GNode *asn = NULL; gcry_mpi_t p, q, g, y, x; guchar *result = NULL; p = q = g = y = x = NULL; asn = egg_asn1x_create (pk_asn1_tab, "DSAPrivateKey"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) || !gkm_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) || !gkm_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) || !gkm_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) || !gkm_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL)) goto done; if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "Y", NULL), y) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "priv", NULL), x)) goto done; if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0)) goto done; result = egg_asn1x_encode (asn, egg_secure_realloc, len); if (result == NULL) g_warning ("couldn't encode private dsa key: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (g); gcry_mpi_release (y); gcry_mpi_release (x); return result; }
static gboolean gkm_xdg_trust_real_load (GkmSerializable *base, GkmSecret *login, gconstpointer data, gsize n_data) { GkmXdgTrust *self = GKM_XDG_TRUST (base); GNode *asn = NULL; gpointer copy; g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE); g_return_val_if_fail (data, FALSE); if (n_data == 0) return FALSE; copy = g_memdup (data, n_data); asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_val_if_fail (asn, FALSE); if (!egg_asn1x_decode (asn, copy, n_data)) { g_warning ("couldn't parse trust data: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); g_free (copy); return FALSE; } /* Next parse out all the pairs */ if (!load_assertions (self, asn)) { egg_asn1x_destroy (asn); g_free (copy); return FALSE; } /* Take ownership of this new data */ g_free (self->pv->data); self->pv->data = copy; self->pv->n_data = n_data; egg_asn1x_destroy (self->pv->asn); self->pv->asn = asn; return TRUE; }
static void dump_certificate_complete (GNode *asn) { GNode *cert; gchar *issuer, *serial, *subject; gconstpointer element; gpointer data; gsize n_data, n_element; /* Parse the certificate out */ cert = egg_asn1x_create (pkix_asn1_tab, "Certificate"); g_return_if_fail (cert); element = egg_asn1x_get_raw_element (asn, &n_element); g_return_if_fail (element); if (!egg_asn1x_decode (cert, element, n_element)) barf_and_die ("couldn't parse certificate", egg_asn1x_message (cert)); issuer = egg_dn_read (egg_asn1x_node (asn, "issuer", NULL)); g_return_if_fail (issuer); subject = egg_dn_read (egg_asn1x_node (asn, "subject", NULL)); g_return_if_fail (subject); data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), NULL, &n_data); g_return_if_fail (data && n_data); serial = egg_hex_encode (data, n_data); g_free (data); g_print ("Complete\n"); g_print (" issuer: %s\n", issuer); g_print (" subject: %s\n", subject); g_print (" serial: 0x%s\n", serial); egg_asn1x_destroy (cert); g_free (data); g_free (serial); g_free (issuer); g_free (subject); }
GBytes * gkm_data_der_write_public_key_dsa (gcry_sexp_t s_key) { GNode *asn = NULL; gcry_mpi_t p, q, g, y; GBytes *result = NULL; p = q = g = y = NULL; asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicKey"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) || !gkm_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) || !gkm_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) || !gkm_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL)) goto done; if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "p", NULL), p) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "q", NULL), q) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "g", NULL), g) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "Y", NULL), y)) goto done; egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0); result = egg_asn1x_encode (asn, NULL); if (result == NULL) g_warning ("couldn't encode public dsa key: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (g); gcry_mpi_release (y); return result; }
/** * gcr_certificate_request_encode: * @self: a certificate request * @textual: whether to encode output as text * @length: location to place length of returned data * * Encode the certificate request. It must have been completed with * gcr_certificate_request_complete() or gcr_certificate_request_complete_async() * * If @textual is %FALSE, the output is a DER encoded certificate request. * * If @textual is %TRUE, the output is encoded as text. For PKCS\#10 requests this * is done using the OpenSSL style PEM encoding. * * Returns: (transfer full) (array length=length): the encoded certificate request */ guchar * gcr_certificate_request_encode (GcrCertificateRequest *self, gboolean textual, gsize *length) { GBytes *bytes; gpointer encoded; gpointer data; gsize size; g_return_val_if_fail (GCR_IS_CERTIFICATE_REQUEST (self), NULL); g_return_val_if_fail (length != NULL, NULL); bytes = egg_asn1x_encode (self->asn, NULL); if (bytes == NULL) { g_warning ("couldn't encode certificate request: %s", egg_asn1x_message (self->asn)); return NULL; } size = g_bytes_get_size (bytes); encoded = g_byte_array_free (g_bytes_unref_to_array (bytes), FALSE); if (textual) { data = egg_armor_write (encoded, size, g_quark_from_static_string ("CERTIFICATE REQUEST"), NULL, length); g_free (encoded); encoded = data; } else { *length = size; } return encoded; }
static void dump_certificate_reference (GNode *asn) { gchar *issuer, *serial; gpointer data; gsize n_data; GNode *name; gconstpointer element; gsize n_element; /* Parse the name out */ name = egg_asn1x_create (pkix_asn1_tab, "Name"); g_return_if_fail (name); element = egg_asn1x_get_raw_element (egg_asn1x_node (asn, "issuer", NULL), &n_element); g_return_if_fail (element); if (!egg_asn1x_decode (name, element, n_element)) barf_and_die ("couldn't parse certificate", egg_asn1x_message (name)); issuer = egg_dn_read (name); g_return_if_fail (issuer); data = egg_asn1x_get_integer_as_raw (egg_asn1x_node (asn, "serial", NULL), NULL, &n_data); g_return_if_fail (data && n_data); serial = egg_hex_encode (data, n_data); g_free (data); g_print ("Reference\n"); g_print (" issuer: %s\n", issuer); g_print (" serial: 0x%s\n", serial); egg_asn1x_destroy (name); g_free (data); g_free (serial); g_free (issuer); }
static GBytes * gkm_xdg_trust_real_save (GkmSerializable *base, GkmSecret *login) { GkmXdgTrust *self = GKM_XDG_TRUST (base); GBytes *bytes; g_return_val_if_fail (GKM_XDG_IS_TRUST (self), FALSE); g_return_val_if_fail (self->pv->asn, FALSE); if (!save_assertions (self, self->pv->asn)) return FALSE; bytes = egg_asn1x_encode (self->pv->asn, NULL); if (bytes == NULL) { g_warning ("encoding trust failed: %s", egg_asn1x_message (self->pv->asn)); return FALSE; } if (self->pv->bytes) g_bytes_unref (self->pv->bytes); self->pv->bytes = bytes; return g_bytes_ref (bytes); }
static gcry_cipher_hd_t prepare_and_encode_pkcs8_cipher (GNode *asn, const gchar *password, gsize n_password, gsize *n_block) { GNode *asn1_params = NULL; gcry_cipher_hd_t cih; guchar salt[8]; gcry_error_t gcry; guchar *key, *iv, *portion; gsize n_key, n_portion; int iterations; init_quarks (); /* Make sure the encryption algorithm works */ g_return_val_if_fail (gcry_cipher_algo_info (OID_PKCS12_PBE_3DES_SHA1, GCRYCTL_TEST_ALGO, NULL, 0), NULL); /* The encryption algorithm */ if(!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL), OID_PKCS12_PBE_3DES_SHA1)) g_return_val_if_reached (NULL); /* Randomize some input for the password based secret */ iterations = 1000 + (int) (1000.0 * rand () / (RAND_MAX + 1.0)); gcry_create_nonce (salt, sizeof (salt)); /* Allocate space for the key and iv */ n_key = gcry_cipher_get_algo_keylen (GCRY_CIPHER_3DES); *n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1); g_return_val_if_fail (n_key && *n_block, NULL); if (!egg_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1, password, n_password, salt, sizeof (salt), iterations, &key, &iv)) g_return_val_if_reached (NULL); /* Now write out the parameters */ asn1_params = egg_asn1x_create (pkix_asn1_tab, "pkcs-12-PbeParams"); g_return_val_if_fail (asn1_params, NULL); if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn1_params, "salt", NULL), salt, sizeof (salt), NULL)) g_return_val_if_reached (NULL); if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn1_params, "iterations", NULL), iterations)) g_return_val_if_reached (NULL); portion = egg_asn1x_encode (asn1_params, NULL, &n_portion); if (portion == NULL) { g_warning ("couldn't encode pkcs8 params key: %s", egg_asn1x_message (asn1_params)); g_return_val_if_reached (NULL); } if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL), portion, n_portion, g_free)) g_return_val_if_reached (NULL); /* Now make a cipher that matches what we wrote out */ gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0); g_return_val_if_fail (gcry == 0, NULL); g_return_val_if_fail (cih, NULL); gcry_cipher_setiv (cih, iv, *n_block); gcry_cipher_setkey (cih, key, n_key); g_free (iv); egg_secure_free (key); egg_asn1x_destroy (asn1_params); return cih; }
GBytes * gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password, gsize n_password) { gcry_error_t gcry; gcry_cipher_hd_t cih; GNode *asn = NULL; GBytes *key, *data; guchar *raw; gsize n_raw, n_key; gsize block = 0; /* Encode the key in normal pkcs8 fashion */ key = gkm_data_der_write_private_pkcs8_plain (skey); if (key == NULL) return NULL; asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Create a and write out a cipher used for encryption */ cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block); g_return_val_if_fail (cih, NULL); n_key = g_bytes_get_size (key); /* Pad the block of data */ if(block > 1) { gsize n_pad = block - (n_key % block); if (n_pad == 0) n_pad = block; raw = egg_secure_alloc (n_key + n_pad); memcpy (raw, g_bytes_get_data (key, NULL), n_key); memset (raw + n_key, (int)n_pad, n_pad); n_raw = n_key + n_pad; /* No padding, probably stream cipher */ } else { raw = egg_secure_alloc (n_key); memcpy (raw, g_bytes_get_data (key, NULL), n_key); n_raw = n_key; } g_bytes_unref (key); gcry = gcry_cipher_encrypt (cih, raw, n_raw, NULL, 0); g_return_val_if_fail (gcry == 0, NULL); gcry_cipher_close (cih); key = g_bytes_new_with_free_func (raw, n_raw, egg_secure_free, raw); egg_asn1x_set_string_as_bytes (egg_asn1x_node (asn, "encryptedData", NULL), key); g_bytes_unref (key); data = egg_asn1x_encode (asn, NULL); if (data == NULL) g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }
guchar* gkm_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data) { GNode *asn = NULL; int algorithm; gboolean is_priv; GQuark oid; guchar *params, *key, *data; gsize n_params, n_key; init_quarks (); /* Parse and check that the key is for real */ if (!gkm_sexp_parse_key (skey, &algorithm, &is_priv, NULL)) g_return_val_if_reached (NULL); g_return_val_if_fail (is_priv == TRUE, NULL); asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-PrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Write out the version */ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0)) g_return_val_if_reached (NULL); /* Per algorithm differences */ switch (algorithm) { /* RSA gets encoded in a standard simple way */ case GCRY_PK_RSA: oid = OID_PKIX1_RSA; params = NULL; n_params = 0; key = gkm_data_der_write_private_key_rsa (skey, &n_key); break; /* DSA gets incoded with the params seperate */ case GCRY_PK_DSA: oid = OID_PKIX1_DSA; key = gkm_data_der_write_private_key_dsa_part (skey, &n_key); params = gkm_data_der_write_private_key_dsa_params (skey, &n_params); break; default: g_warning ("trying to serialize unsupported private key algorithm: %d", algorithm); return NULL; }; /* Write out the algorithm */ if (!egg_asn1x_set_oid_as_quark (egg_asn1x_node (asn, "privateKeyAlgorithm", "algorithm", NULL), oid)) g_return_val_if_reached (NULL); /* Write out the parameters */ if (params) { if (!egg_asn1x_set_raw_element (egg_asn1x_node (asn, "privateKeyAlgorithm", "parameters", NULL), params, n_params, egg_secure_free)) g_return_val_if_reached (NULL); } /* Write out the key portion */ if (!egg_asn1x_set_string_as_raw (egg_asn1x_node (asn, "privateKey", NULL), key, n_key, egg_secure_free)) g_return_val_if_reached (NULL); data = egg_asn1x_encode (asn, egg_secure_realloc, n_data); if (data == NULL) g_warning ("couldn't encode private pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }
guchar* gkm_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key) { GNode *asn = NULL; gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp; guchar *result = NULL; n = e = d = p = q = u = e1 = e2 = tmp = NULL; asn = egg_asn1x_create (pk_asn1_tab, "RSAPrivateKey"); g_return_val_if_fail (asn, NULL); if (!gkm_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) || !gkm_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) || !gkm_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) || !gkm_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) || !gkm_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) || !gkm_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL)) goto done; if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "modulus", NULL), n) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "publicExponent", NULL), e) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "privateExponent", NULL), d) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime1", NULL), p) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "prime2", NULL), q) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "coefficient", NULL), u)) goto done; /* Calculate e1 and e2 */ tmp = gcry_mpi_snew (1024); gcry_mpi_sub_ui (tmp, p, 1); e1 = gcry_mpi_snew (1024); gcry_mpi_mod (e1, d, tmp); gcry_mpi_sub_ui (tmp, q, 1); e2 = gcry_mpi_snew (1024); gcry_mpi_mod (e2, d, tmp); /* Write out calculated */ if (!gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent1", NULL), e1) || !gkm_data_asn1_write_mpi (egg_asn1x_node (asn, "exponent2", NULL), e2)) goto done; /* Write out the version */ if (!egg_asn1x_set_integer_as_ulong (egg_asn1x_node (asn, "version", NULL), 0)) goto done; result = egg_asn1x_encode (asn, egg_secure_realloc, n_key); if (result == NULL) g_warning ("couldn't encode private rsa key: %s", egg_asn1x_message (asn)); done: egg_asn1x_destroy (asn); gcry_mpi_release (n); gcry_mpi_release (e); gcry_mpi_release (d); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (u); gcry_mpi_release (tmp); gcry_mpi_release (e1); gcry_mpi_release (e2); return result; }
static void create_trust_file_for_issuer_and_serial (const gchar *filename, const gchar *certificate) { GError *err = NULL; GNode *asn, *cert, *choice, *ref; GNode *issuer, *serial; gchar *data; GBytes *result; GBytes *value; GBytes *element; gsize n_data; GBytes *bytes; if (!g_file_get_contents (certificate, &data, &n_data, &err)) barf_and_die ("couldn't read certificate file", egg_error_message (err)); /* Make sure the certificate is */ cert = egg_asn1x_create (pkix_asn1_tab, "Certificate"); g_return_if_fail (cert); bytes = g_bytes_new_take (data, n_data); if (!egg_asn1x_decode (cert, bytes)) barf_and_die ("couldn't parse der certificate file", egg_asn1x_message (cert)); g_bytes_unref (bytes); /* Dig out the issuer and serial */ issuer = egg_asn1x_node (cert, "tbsCertificate", "issuer", NULL); serial = egg_asn1x_node (cert, "tbsCertificate", "serialNumber", NULL); g_return_if_fail (issuer && serial); /* Create up the trust structure */ asn = egg_asn1x_create (xdg_asn1_tab, "trust-1"); g_return_if_fail (asn); /* Setup the type of trust assertion */ ref = egg_asn1x_node (asn, "reference", NULL); choice = egg_asn1x_node (ref, "certReference", NULL); if (!egg_asn1x_set_choice (ref, choice)) g_return_if_reached (); /* Copy over the serial and issuer */ element = egg_asn1x_get_element_raw (issuer); if (!egg_asn1x_set_any_raw (egg_asn1x_node (choice, "issuer", NULL), element)) g_return_if_reached (); g_bytes_unref (element); value = egg_asn1x_get_integer_as_raw (serial); egg_asn1x_set_integer_as_raw (egg_asn1x_node (choice, "serialNumber", NULL), value); g_bytes_unref (value); result = egg_asn1x_encode (asn, NULL); if (result == NULL) barf_and_die ("couldn't encode the trust file", egg_asn1x_message (asn)); g_free (data); egg_asn1x_destroy (cert); egg_asn1x_destroy (asn); if (!g_file_set_contents (filename, g_bytes_get_data (result, NULL), g_bytes_get_size (result), &err)) barf_and_die ("couldn't write trust file", egg_error_message (err)); g_bytes_unref (result); }