int main (int argc, char **argv) { gpg_error_t err; if (argc) { argc--; argv++; } if (!argc) { test_oid_to_str (); } else if (!strcmp (*argv, "--from-str")) { unsigned char *buffer; size_t n, buflen; for (argv++,argc-- ; argc; argc--, argv++) { err = ksba_oid_from_str (*argv, &buffer, &buflen); if (err) { fprintf (stderr, "can't convert `%s': %s\n", *argv, gpg_strerror (err)); return 1; } printf ("%s ->", *argv); for (n=0; n < buflen; n++) printf (" %02X", buffer[n]); putchar ('\n'); free (buffer); } } else if (!strcmp (*argv, "--to-str")) { char *buffer; size_t buflen; char *result; argv++;argc--; buffer = read_into_buffer (stdin, &buflen); result = ksba_oid_to_str (buffer, buflen); free (buffer); printf ("%s\n", result? result:"[malloc failed]"); free (result); } else { fputs ("usage: "PGM" [--from-str|--to-str]\n", stderr); return 1; } return 0; }
/* Create and write a AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } where parameters will be set to NULL if parm is NULL or to an octet string with the given parm. As a special hack parameter will not be written if PARM is given but parmlen is 0. */ gpg_error_t _ksba_der_write_algorithm_identifier (ksba_writer_t w, const char *oid, const void *parm, size_t parmlen) { gpg_error_t err; unsigned char *buf; size_t len; int no_null = (parm && !parmlen); err = ksba_oid_from_str (oid, &buf, &len); if (err) return err; /* write the sequence */ /* fixme: the the length to encode the TLV values are actually not just 2 byte each but depend on the length of the values - for our purposes the static values do work. */ err = _ksba_ber_write_tl (w, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, (no_null? 2:4) + len + (parm? parmlen:0)); if (err) goto leave; /* the OBJECT ID header and the value */ err = _ksba_ber_write_tl (w, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, len); if (!err) err = ksba_writer_write (w, buf, len); if (err) goto leave; /* Write the parameter */ if (no_null) ; else if (parm) { err = _ksba_ber_write_tl (w, TYPE_OCTET_STRING, CLASS_UNIVERSAL, 0, parmlen); if (!err) err = ksba_writer_write (w, parm, parmlen); } else { err = _ksba_ber_write_tl (w, TYPE_NULL, CLASS_UNIVERSAL, 0, 0); } leave: xfree (buf); return err; }
gpg_error_t _ksba_der_store_oid (AsnNode node, const char *oid) { gpg_error_t err; if (node->type == TYPE_ANY) node->type = TYPE_OBJECT_ID; if (node->type == TYPE_OBJECT_ID) { unsigned char *buf; size_t len; err = ksba_oid_from_str (oid, &buf, &len); if (err) return err; err = store_value (node, buf, len); xfree (buf); return err; } else return gpg_error (GPG_ERR_INV_VALUE); }
/* Build the extension block and return it in R_DER and R_DERLEN. IF CERTMODE is true build X.509 certificate extension instead. */ static gpg_error_t build_extensions (ksba_certreq_t cr, int certmode, void **r_der, size_t *r_derlen) { gpg_error_t err; ksba_writer_t writer, w=NULL; struct extn_list_s *e; unsigned char *value = NULL; size_t valuelen; unsigned char *p; size_t n; *r_der = NULL; *r_derlen = 0; err = ksba_writer_new (&writer); if (err) goto leave; err = ksba_writer_set_mem (writer, 2048); if (err) goto leave; err = ksba_writer_new (&w); if (err) goto leave; for (e=cr->extn_list; e; e = e->next) { err = ksba_writer_set_mem (w, e->derlen + 100); if (err) goto leave; err = ksba_oid_from_str (e->oid, &p, &n); if(err) goto leave; err = _ksba_ber_write_tl (w, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, n); if (!err) err = ksba_writer_write (w, p, n); xfree (p); if (e->critical) { err = _ksba_ber_write_tl (w, TYPE_BOOLEAN, CLASS_UNIVERSAL, 0, 1); if (!err) err = ksba_writer_write (w, "\xff", 1); if(err) goto leave; } err = _ksba_ber_write_tl (w, TYPE_OCTET_STRING, CLASS_UNIVERSAL, 0, e->derlen); if (!err) err = ksba_writer_write (w, e->der, e->derlen); if(err) goto leave; p = ksba_writer_snatch_mem (w, &n); if (!p) { err = gpg_error (GPG_ERR_ENOMEM); goto leave; } err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, n); if (!err) err = ksba_writer_write (writer, p, n); xfree (p); p = NULL; if (err) goto leave; } /* Embed all the sequences into another sequence */ value = ksba_writer_snatch_mem (writer, &valuelen); if (!value) { err = gpg_error (GPG_ERR_ENOMEM); goto leave; } err = ksba_writer_set_mem (writer, valuelen+10); if (err) goto leave; err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, valuelen); if (!err) err = ksba_writer_write (writer, value, valuelen); if (err) goto leave; xfree (value); value = ksba_writer_snatch_mem (writer, &valuelen); if (!value) { err = gpg_error (GPG_ERR_ENOMEM); goto leave; } if (!certmode) { /* Now create the extension request sequence content */ err = ksba_writer_set_mem (writer, valuelen+100); if (err) goto leave; err = ksba_oid_from_str (oidstr_extensionReq, &p, &n); if(err) goto leave; err = _ksba_ber_write_tl (writer, TYPE_OBJECT_ID, CLASS_UNIVERSAL, 0, n); if (!err) err = ksba_writer_write (writer, p, n); xfree (p); p = NULL; if (err) return err; err = _ksba_ber_write_tl (writer, TYPE_SET, CLASS_UNIVERSAL, 1, valuelen); if (!err) err = ksba_writer_write (writer, value, valuelen); /* Put this all into a SEQUENCE */ xfree (value); value = ksba_writer_snatch_mem (writer, &valuelen); if (!value) { err = gpg_error (GPG_ERR_ENOMEM); goto leave; } err = ksba_writer_set_mem (writer, valuelen+10); if (err) goto leave; err = _ksba_ber_write_tl (writer, TYPE_SEQUENCE, CLASS_UNIVERSAL, 1, valuelen); if (!err) err = ksba_writer_write (writer, value, valuelen); if (err) goto leave; xfree (value); value = ksba_writer_snatch_mem (writer, &valuelen); if (!value) { err = gpg_error (GPG_ERR_ENOMEM); goto leave; } } *r_der = value; *r_derlen = valuelen; value = NULL; leave: ksba_writer_release (writer); ksba_writer_release (w); xfree (value); return err; }