Esempio n. 1
0
/* Build a value tree from the already stored values. */
static gpg_error_t
build_cri (ksba_certreq_t cr)
{
  gpg_error_t err;
  ksba_writer_t writer;
  void *value = NULL;
  size_t valuelen;
  int certmode;

  /* If a serial number has been set, we don't create a CSR but a
     proper certificate.  */
  certmode = !!cr->x509.serial.der;

  err = ksba_writer_new (&writer);
  if (err)
    goto leave;
  err = ksba_writer_set_mem (writer, 2048);
  if (err)
    goto leave;

  if (!cr->key.der)
    {
      err = gpg_error (GPG_ERR_MISSING_VALUE);
      goto leave;
    }

  /* We write all stuff out to a temporary writer object, then use
     this object to create the cri and store the cri image */

  if (certmode)
    {
      /* Store the version structure; version is 3 (encoded as 2):
         [0] { INTEGER 2 }  */
      err = ksba_writer_write (writer, "\xa0\x03\x02\x01\x02", 5);
    }
  else
    {
      /* Store version v1 (which is a 0).  */
      err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
      if (!err)
        err = ksba_writer_write (writer, "", 1);
    }
  if (err)
    goto leave;

  /* For a certificate we need to store the s/n, the signature
     algorithm identifier, the issuer DN and the validity.  */
  if (certmode)
    {
      /* Store the serial number. */
      err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0,
                                cr->x509.serial.derlen);
      if (!err)
        err = ksba_writer_write (writer,
                                 cr->x509.serial.der, cr->x509.serial.derlen);
      if (err)
        goto leave;

      /* Store the signature algorithm identifier.  */
      if (!cr->x509.siginfo.der)
        err = gpg_error (GPG_ERR_MISSING_VALUE);
      else
        err = ksba_writer_write (writer,
                                 cr->x509.siginfo.der, cr->x509.siginfo.derlen);
      if (err)
        goto leave;


      /* Store the issuer DN.  If no issuer DN has been set we use the
         subject DN.  */
      if (cr->x509.issuer.der)
        err = ksba_writer_write (writer,
                                 cr->x509.issuer.der, cr->x509.issuer.derlen);
      else if (cr->subject.der)
        err = ksba_writer_write (writer, cr->subject.der, cr->subject.derlen);
      else
        err = gpg_error (GPG_ERR_MISSING_VALUE);
      if (err)
        goto leave;

      /* Store the Validity.  */
      {
        unsigned char templ[36];
        unsigned char *tp;

        tp = templ;
        *tp++ = 0x30;
        *tp++ = 0x22;

        *tp++ = TYPE_GENERALIZED_TIME;
        *tp++ = 15;
        if (cr->x509.not_before[0])
          {
            if (_ksba_cmp_time (cr->x509.not_before, "20500101T000000") >= 0)
              {
                memcpy (tp, cr->x509.not_before, 8);
                tp += 8;
                memcpy (tp, cr->x509.not_before+9, 6);
                tp += 6;
              }
            else
              {
                tp[-2] = TYPE_UTC_TIME;
                tp[-1] = 13;
                memcpy (tp, cr->x509.not_before+2, 6);
                tp += 6;
                memcpy (tp, cr->x509.not_before+9, 6);
                tp += 6;
              }
          }
        else
          {
            tp[-2] = TYPE_UTC_TIME;
            tp[-1] = 13;
            memcpy (tp, "110101000000", 12);
            tp += 12;
          }
        *tp++ = 'Z';

        *tp++ = TYPE_GENERALIZED_TIME;
        *tp++ = 15;
        if (cr->x509.not_after[0])
          {
            if (_ksba_cmp_time (cr->x509.not_after, "20500101T000000") >= 0)
              {
                memcpy (tp, cr->x509.not_after, 8);
                tp += 8;
                memcpy (tp, cr->x509.not_after+9, 6);
                tp += 6;
              }
            else
              {
                tp[-2] = TYPE_UTC_TIME;
                tp[-1] = 13;
                memcpy (tp, cr->x509.not_after+2, 6);
                tp += 6;
                memcpy (tp, cr->x509.not_after+9, 6);
                tp += 6;
              }
          }
        else
          {
            memcpy (tp,"20630405170000", 14);
            tp += 14;
          }
        *tp++ = 'Z';
        assert (tp - templ <= 36);
        templ[1] = tp - templ - 2;  /* Fixup the sequence length.  */

        err = ksba_writer_write (writer, templ, tp - templ);
        if (err)
          goto leave;
      }
    }

  /* store the subject */
  if (!cr->subject.der)
    {
      err = gpg_error (GPG_ERR_MISSING_VALUE);
      goto leave;
    }
  err = ksba_writer_write (writer, cr->subject.der, cr->subject.derlen);
  if (err)
    goto leave;

  /* store the public key info */
  err = ksba_writer_write (writer, cr->key.der, cr->key.derlen);
  if (err)
    goto leave;

  /* Copy generalNames objects to the extension list. */
  if (cr->subject_alt_names)
    {
      err = add_general_names_to_extn (cr, cr->subject_alt_names,
                                       oidstr_subjectAltName);
      if (err)
        goto leave;
      while (cr->subject_alt_names)
        {
          struct general_names_s *tmp = cr->subject_alt_names->next;
          xfree (cr->subject_alt_names);
          cr->subject_alt_names = tmp;
        }
      cr->subject_alt_names = NULL;
    }


  /* Write the extensions.  Note that the implicit SET OF is REQUIRED */
  xfree (value); value = NULL;
  valuelen = 0;
  if (cr->extn_list)
    {
      err = build_extensions (cr, certmode, &value, &valuelen);
      if (err)
        goto leave;
      err = _ksba_ber_write_tl (writer, certmode? 3:0,
                                CLASS_CONTEXT, 1, valuelen);
      if (!err)
        err = ksba_writer_write (writer, value, valuelen);
      if (err)
        goto leave;
    }
  else
    { /* We can't write an object of length zero using our ber_write
         function.  So we must open encode it. */
      err = ksba_writer_write (writer,
                               certmode? "\xa3\x02\x30":"\xa0\x02\x30", 4);
      if (err)
        goto leave;
    }


  /* pack it into the sequence */
  xfree (value);
  value = ksba_writer_snatch_mem (writer, &valuelen);
  if (!value)
    {
      err = gpg_error (GPG_ERR_ENOMEM);
      goto leave;
    }
  /* reinitialize the buffer to create the outer sequence */
  err = ksba_writer_set_mem (writer, valuelen+10);
  if (err)
    goto leave;
  /* write outer sequence */
  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;

  /* and store the final result */
  cr->cri.der = ksba_writer_snatch_mem (writer, &cr->cri.derlen);
  if (!cr->cri.der)
    err = gpg_error (GPG_ERR_ENOMEM);

 leave:
  ksba_writer_release (writer);
  xfree (value);
  return err;
}
Esempio n. 2
0
/* Build a value tree from the already stored values. */
static gpg_error_t
build_cri (ksba_certreq_t cr)
{
  gpg_error_t err;
  ksba_writer_t writer;
  void *value = NULL;
  size_t valuelen;

  err = ksba_writer_new (&writer);
  if (err)
    goto leave;
  err = ksba_writer_set_mem (writer, 2048);
  if (err)
    goto leave;

  /* We write all stuff out to a temporary writer object, then use
     this object to create the cri and store the cri image */

  /* store version v1 (which is a 0) */
  err = _ksba_ber_write_tl (writer, TYPE_INTEGER, CLASS_UNIVERSAL, 0, 1);
  if (!err)
    err = ksba_writer_write (writer, "", 1);
  if (err)
    goto leave;

  /* store the subject */
  if (!cr->subject.der)
    {
      err = gpg_error (GPG_ERR_MISSING_VALUE);
      goto leave;
    }
  err = ksba_writer_write (writer, cr->subject.der, cr->subject.derlen);
  if (err)
    goto leave;

  /* store the public key info */
  if (!cr->key.der)
    {
      err = gpg_error (GPG_ERR_MISSING_VALUE);
      goto leave;
    }
  err = ksba_writer_write (writer, cr->key.der, cr->key.derlen);
  if (err)
    goto leave;

  /* Copy generalNames objects to the extension list. */
  if (cr->subject_alt_names)
    {
      err = add_general_names_to_extn (cr, cr->subject_alt_names, 
                                       oidstr_subjectAltName);
      if (err)
        goto leave;
      while (cr->subject_alt_names)
        {
          struct general_names_s *tmp = cr->subject_alt_names->next;
          xfree (cr->subject_alt_names);
          cr->subject_alt_names = tmp;
        }
      cr->subject_alt_names = NULL;
    }
  

  /* Write the extensions.  Note that the implicit SET OF is REQUIRED */
  xfree (value); value = NULL;
  valuelen = 0;
  if (cr->extn_list)
    {
      err = build_extensions (cr, &value, &valuelen);
      if (err)
        goto leave;
      err = _ksba_ber_write_tl (writer, 0, CLASS_CONTEXT, 1, valuelen);
      if (!err)
        err = ksba_writer_write (writer, value, valuelen);
      if (err)
        goto leave;
    }
  else
    { /* We can't write an object of length zero using our ber_write
         function.  So we must open encode it. */
      err = ksba_writer_write (writer, "\xa0\x02\x30", 4);
      if (err)
        goto leave;
    }


  /* pack it into the sequence */
  xfree (value); 
  value = ksba_writer_snatch_mem (writer, &valuelen);
  if (!value)
    {
      err = gpg_error (GPG_ERR_ENOMEM);
      goto leave;
    }
  /* reinitialize the buffer to create the outer sequence */
  err = ksba_writer_set_mem (writer, valuelen+10);
  if (err)
    goto leave;
  /* write outer sequence */
  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;
  
  /* and store the final result */
  cr->cri.der = ksba_writer_snatch_mem (writer, &cr->cri.derlen);
  if (!cr->cri.der)
    err = gpg_error (GPG_ERR_ENOMEM);

 leave:
  ksba_writer_release (writer);
  xfree (value);
  return err;
}