Ejemplo n.º 1
0
int write_default_fields(
    struct Certificate *certp)
{

    struct CertificateToBeSigned *ctftbsp = &certp->toBeSigned;
    struct Extension *cextp;


    // key usage
    // If ca set keyCertSign and CRLsign bits
    // if ee set digitalSignature bit
    if (!(cextp = find_extension(&ctftbsp->extensions, id_keyUsage, false)))
        cextp = make_extension(&ctftbsp->extensions, id_keyUsage);
    if (eecert)
    {                           // clear everything first
        write_casn_num(&cextp->critical, 1);
        write_casn(&cextp->extnValue.keyUsage.self, (uchar *) "", 0);
        write_casn_bit(&cextp->extnValue.keyUsage.digitalSignature, 1);
    }
    else
    {
        write_casn_num(&cextp->critical, 1);
        write_casn(&cextp->extnValue.keyUsage.self, (uchar *) "", 0);
        write_casn_bit(&cextp->extnValue.keyUsage.keyCertSign, 1);
        write_casn_bit(&cextp->extnValue.keyUsage.cRLSign, 1);
    }

    // basic constraints
    // if ee no extension, if ca set ca to one
    cextp = find_extension(&ctftbsp->extensions, id_basicConstraints, false);
    if (eecert)
    {
        // no basic constraints extension for an ee cert
        if (cextp)
            removeExtension(&ctftbsp->extensions, id_basicConstraints);
    }
    else
    {
        int caConstraint = 1;
        if (!cextp)
            cextp = make_extension(&ctftbsp->extensions, id_basicConstraints);
        write_casn_num(&cextp->critical, 1);
        // write_casn(&cextp->extnValue.basicConstraints.self, (uchar *)"",
        // 0);
        write_casn_num(&cextp->extnValue.basicConstraints.cA, caConstraint);
    }

    return SUCCESS;
}
Ejemplo n.º 2
0
int write_cert_aia(
    void *cert,
    void *val)
{
    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    struct Extension *extp;
    struct Extensions *extsp = &tbsp->extensions;
    struct AuthorityInfoAccessSyntax *aiasp;
    struct AccessDescription *accdsp;
    char *ptr = (char *)val;

    if (selfSigned)
    {
        // warn ignored
        return SUCCESS;
    }

    extp = make_extension(extsp, id_pkix_authorityInfoAccess);
    while (isspace((int)(unsigned char)*ptr))
        ptr++;                  // strip leading spaces

    aiasp = &extp->extnValue.authorityInfoAccess;
    accdsp = (struct AccessDescription *)inject_casn(&aiasp->self, 0);
    write_objid(&accdsp->accessMethod, id_ad_caIssuers);
    write_casn(&accdsp->accessLocation.url, (unsigned char *)ptr, strlen(ptr));

    return SUCCESS;
}
Ejemplo n.º 3
0
/*
 * Take values from the subject keyfile and write them to the
 * current certificate.
 * val is filename of the subject keyfile
 * values of interest are the subject public key and the ski.
 */
int use_subject_keyfile(
    void *cert,
    void *val)
{
    struct Certificate *certp = (struct Certificate *)cert;
    struct CertificateToBeSigned *ctftbsp = &certp->toBeSigned;
    struct SubjectPublicKeyInfo *spkinfop = &ctftbsp->subjectPublicKeyInfo;
    struct Extensions *extsp = &ctftbsp->extensions;
    struct Extension *extp;
    struct casn *spkp = &spkinfop->subjectPublicKey;


    if (val == NULL)
        return -1;

    // if no subjectPublicKey in the cert then get if from keyfile
    if (vsize_casn(&spkinfop->subjectPublicKey) <= 0)
    {
        write_objid(&spkinfop->algorithm.algorithm, id_rsadsi_rsaEncryption);
        write_casn(&spkinfop->algorithm.parameters.rsadsi_rsaEncryption,
                   (uchar *) "", 0);
        if (!fillPublicKey(spkp, val))
            return -1;
    }

    // always update SKI to match subjectPublicKey
    if (!(extp = find_extension(extsp, id_subjectKeyIdentifier, false)))
        extp = make_extension(extsp, id_subjectKeyIdentifier);
    writeHashedPublicKey(&extp->extnValue.subjectKeyIdentifier, spkp, false);

    return (SUCCESS);
}
Ejemplo n.º 4
0
void Extensions::deserialize(TLS_Data_Reader& reader)
   {
   if(reader.has_remaining())
      {
      const u16bit all_extn_size = reader.get_u16bit();

      if(reader.remaining_bytes() != all_extn_size)
         throw Decoding_Error("Bad extension size");

      while(reader.has_remaining())
         {
         const u16bit extension_code = reader.get_u16bit();
         const u16bit extension_size = reader.get_u16bit();

         Extension* extn = make_extension(reader,
                                          extension_code,
                                          extension_size);

         if(extn)
            this->add(extn);
         else // unknown/unhandled extension
            reader.discard_next(extension_size);
         }
      }
   }
Ejemplo n.º 5
0
/*
 * Subject Information Access - comma separated ASCII strings
 */
int write_cert_sia(
    void *cert,
    void *val)
{
    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    struct Extension *extp;
    struct Extensions *extsp = &tbsp->extensions;
    struct SubjectInfoAccess *siap;
    struct AccessDescription *accdsp;
    char *ptr,
       *next;
    int numpts = 0,
        ptr_len;
    char token = ',';

    // FIXME - can have 3 object identifiers, have to parse out
    // r:, m: or s: for the different ones.

    // separate out the sia's and write each one into the sequence
    extp = make_extension(extsp, id_pe_subjectInfoAccess);
    ptr = val;
    while (ptr != NULL)
    {
        next = strchr(ptr, token);
        while (isspace((int)(unsigned char)*ptr))
            ptr++;              // strip leading spaces
        if (next == NULL)
            ptr_len = strlen(ptr);
        else
        {
            ptr_len = (char *)next - (char *)ptr;
            next++;
        }

        siap = &extp->extnValue.subjectInfoAccess;
        accdsp =
            (struct AccessDescription *)inject_casn(&siap->self, numpts++);
        if (!accdsp)
            return -1;

        // parse out what object id to use
        // s - signedOjbect, r - caRepository, m - manifest
        if (strncmp(ptr, "r:", strlen("r:")) == 0)
            write_objid(&accdsp->accessMethod, id_ad_caRepository);
        else if (strncmp(ptr, "s:", strlen("s:")) == 0)
            write_objid(&accdsp->accessMethod, id_ad_signedObject);
        else if (strncmp(ptr, "m:", strlen("m:")) == 0)
            write_objid(&accdsp->accessMethod, id_ad_rpkiManifest);
        else
            return -1;

        ptr += 2;               // jump over the object id designation
        ptr_len -= 2;
        write_casn(&accdsp->accessLocation.url, (unsigned char *)ptr, ptr_len);
        ptr = next;
    }
    return SUCCESS;
}
Ejemplo n.º 6
0
/*
 * Take values from the parents certificateand write them to the
 * current certificate.
 * val is filename of the parent certificate
 * fields of interest:
 *    signature algorithm ID - overwrite (from template)
 *    issuer     - if filled in then don't overwrite
 *    aki        - use ski from issuer's cert
 *    algorithm ID  overwrite (from template)
 */
int use_parent_cert(
    void *cert,
    void *val)
{
    struct Certificate issuer;
    struct Certificate *certp = (struct Certificate *)cert;
    struct CertificateToBeSigned *ctftbsp = &certp->toBeSigned;
    Certificate(&issuer, (ushort) 0);
    struct Extension *iextp,
       *cextp;

    // if not parent cert or we are self signed (and shouldn't have a parent
    // cert)
    if ((val == NULL) || (selfSigned))
        return SUCCESS;

    // fprintf(stdout,"getting issuers cert %s\n", (char *)val);
    if (get_casn_file(&issuer.self, val, 0) < 0)
    {
        fprintf(stdout, "can't use issuers cert %s", (char *)val);
        return -1;
    }
    // copy algorithm identifiers (overwrite template value)
    // fprintf(stdout,"trying to copy algorithm identifiers\n");
    copy_casn(&certp->algorithm.self, &issuer.toBeSigned.signature.self);
    copy_casn(&ctftbsp->signature.self, &issuer.toBeSigned.signature.self);
    // fprintf(stdout,"copied algorithm identifiers\n");

    // copy subject name from issuer cert into issuer name in cert if issuer
    // name
    // not filled in.
    copy_casn(&ctftbsp->issuer.self, &issuer.toBeSigned.subject.self);
    // fprintf(stdout,"copied issuer name\n");

    // replace aki extension of certificate with ski from issuer's cert
    cextp = find_extension(&ctftbsp->extensions, id_authKeyId, false);
    if (!cextp)
        cextp = make_extension(&ctftbsp->extensions, id_authKeyId);
    // fprintf(stdout,"copying ski as aki\n");
    if ((iextp = find_extension(&issuer.toBeSigned.extensions,
                                id_subjectKeyIdentifier, false)))
    {
        copy_casn(&cextp->extnValue.authKeyId.keyIdentifier,
                  &iextp->extnValue.subjectKeyIdentifier);
    }
    else
    {
        fprintf(stdout, "Error: issuer cert has no SKI. AKI not set.");
        delete_casn(&issuer.self);
        return -1;
    }

    delete_casn(&issuer.self);
    return (SUCCESS);
}
Ejemplo n.º 7
0
int write_cert_asnums(
    void *cert,
    void *val)
{

    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    struct Extension *extp;
    char *ptr,
       *next,
       *buf;
    int ptr_len;
    char token = ',';
    int num = 0;

    extp = make_extension(&tbsp->extensions, id_pe_autonomousSysNum);
    write_casn_num(&extp->critical, 1);
    struct ASNum *asNump = &extp->extnValue.autonomousSysNum;


    // if it is inherit - set that and done
    if (strncasecmp(val, "inherit", strlen("inherit")) == 0)
    {
        struct ASIdentifierChoiceA *asidChoice = &asNump->asnum;
        write_casn(&asidChoice->inherit, (uchar *) "", 0);
        return SUCCESS;
    }

    // go through all as numbers listed and add them to the block
    ptr = val;
    while (ptr != NULL)
    {
        next = strchr(ptr, token);
        while (isspace((int)(unsigned char)*ptr))
            ptr++;              // strip leading spaces
        if (next == NULL)
            ptr_len = strlen(ptr);
        else
        {
            ptr_len = (char *)next - (char *)ptr;
            next++;
        }

        if ((buf = strndup(ptr, ptr_len)) == NULL)
            return -1;

        if (write_ASNums(asNump, buf, num++) < 0)
            return -1;

        free(buf);
        ptr = next;
    }

    return SUCCESS;
}
Ejemplo n.º 8
0
/*
 * Write the comma separated list of ascii strings into the CRL distribution
 * point extension
 */
int write_cert_crldp(
    void *cert,
    void *val)
{
    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    struct Extension *extp;
    struct Extensions *extsp = &tbsp->extensions;
    struct DistributionPoint *distp;
    struct GeneralName *gennamep;
    char *ptr,
       *next;
    int numpts = 0,
        ptr_len;
    char token = ',';

    if (selfSigned)
    {
        // warn ignored
        return SUCCESS;
    }
    // separate out the crldp's and write each one into the sequence
    extp = make_extension(extsp, id_cRLDistributionPoints);
    ptr = val;
    while (ptr != NULL)
    {
        next = strchr(ptr, token);
        while (isspace((int)(unsigned char)*ptr))
            ptr++;              // strip leading spaces
        if (next == NULL)
            ptr_len = strlen(ptr);
        else
        {
            ptr_len = (char *)next - (char *)ptr;
            next++;
        }

        distp =
            (struct DistributionPoint *)inject_casn(&extp->extnValue.
                                                    cRLDistributionPoints.self,
                                                    numpts++);
        if (!distp)
            return -1;
        gennamep =
            (struct GeneralName *)inject_casn(&distp->distributionPoint.
                                              fullName.self, 0);
        if (!gennamep)
            return -1;
        write_casn(&gennamep->url, (uchar *) ptr, ptr_len);
        ptr = next;
    }

    return SUCCESS;
}
Ejemplo n.º 9
0
int write_key_identifier(
    struct Certificate *cert,
    char *id,
    char *val)
{
    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    int str_len,
        ki_len;
    char *str_ki = val;
    unsigned char *ki = NULL;
    int bytes_written;
    struct Extension *extp;
    struct Extensions *extsp = &tbsp->extensions;

    // strip off leading spaces and the 0x
    while (isspace((int)(unsigned char)*str_ki))
        str_ki++;
    if (strncmp(str_ki, "0x", 2) != 0)
        return -1;
    str_ki += 2;

    str_len = strlen(str_ki);

    ki_len = (str_len + 1) / 2;

    ki = calloc(ki_len, sizeof(char));
    if ((bytes_written = read_hex_val(str_ki, str_len, ki)) <= 0)
    {
        fprintf(stdout, "error converting key identifier (%s)\n", (char *)val);
        return -1;
    }

    // if it is there, clear it first
    extp = make_extension(extsp, id);
    if (strncmp(id, id_subjectKeyIdentifier, strlen(id_subjectKeyIdentifier))
        == 0)
    {
        write_casn(&extp->extnValue.subjectKeyIdentifier, ki, bytes_written);
        free(ki);
    }
    else if (strncmp(id, id_authKeyId, strlen(id_authKeyId)) == 0)
    {
        write_casn(&extp->extnValue.authKeyId.keyIdentifier, ki,
                   bytes_written);
        free(ki);
    }
    else
        return -1;

    return SUCCESS;
}
Ejemplo n.º 10
0
int main(
    int argc,
    char *argv[])
{

    int delete_existing = 0;    /* delete existing SIA access descriptions */
    const char *file = NULL;    /* certificate file */
    struct Certificate cert;    /* ASN.1 certificate object */
    struct Extension *extp;     /* ASN.1 X.509 extension pointer */
    struct SubjectInfoAccess *siap;     /* ASN.1 SIA pointer */

    int c = 0;                  /* getopt option character */
    int i;                      /* loop counter */
    int ret;                    /* return value */

    /*
     * Parse command line arguments.
     */
    opterr = 0;
    while ((c = getopt(argc, argv, "dr:m:s:h")) != -1)
    {
        switch (c)
        {
        case 'd':
            delete_existing = 1;
            break;
        case 'r':              /* id-ad-caRepository */
            if (add_sia_request('r', optarg) != 0)
            {
                fprintf(stderr, "Error: failed to add URI request -r %s\n",
                        optarg);
                return -1;
            }
            break;
        case 'm':              /* id-ad-rpkiManifest */
            if (add_sia_request('m', optarg) != 0)
            {
                fprintf(stderr, "Error: failed to add URI request -m %s\n",
                        optarg);
                return -1;
            }
            break;
        case 's':              /* id-ad-signedObject */
            if (add_sia_request('s', optarg) != 0)
            {
                fprintf(stderr, "Error: failed to add URI request -s %s\n",
                        optarg);
                return -1;
            }
            break;
        case 'h':
            usage(argc, argv);
            return -1;
        case '?':
            if (isprint(optopt))
                fprintf(stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
            usage(argc, argv);
            return -1;
        default:
            usage(argc, argv);
            return -1;
        }
    }
    if (optind >= argc)
    {                           /* no arguments remain? */
        usage(argc, argv);
        return -1;
    }
    file = argv[optind];

    /*
     * Parse certificate.
     */
    Certificate(&cert, (unsigned short)0);      /* constructor */
    ret = get_casn_file(&cert.self, (char *)file, 0);
    if (ret < 0)
    {
        fprintf(stderr, "Could not open file: %s\n", file);
        return -2;
    }

    /*
     * Find or create SIA extension.
     */
    extp = find_extension(&cert.toBeSigned.extensions,
                          id_pe_subjectInfoAccess, false);
    if (!extp)
    {
        extp =
            make_extension(&cert.toBeSigned.extensions,
                          id_pe_subjectInfoAccess);
        if (!extp)
        {
            fprintf(stderr, "Could not create SIA extension.\n");
            return -3;
        }
    }
    siap = &extp->extnValue.subjectInfoAccess;

    /*
     * Optionally delete existing AccessDescriptions.
     */
    if (delete_existing)
    {
        clear_casn(&siap->self);        /* This messes up the "DEFINED BY"
                                         * flag, so we need to set it again in
                                         * the next line.  */
        if (write_objid(&extp->extnID, id_pe_subjectInfoAccess) < 0)
        {
            fprintf(stderr, "Error clearing existing URIs.\n");
            return -1;
        }
    }

    /*
     * For each AccessDescription request, insert it.
     */
    for (i = 0; i < num_sia_requests; i++)
    {
        int current_size;
        struct AccessDescription *adp;  /* ASN.1 AccessDescription pointer */

        /*
         * Append new entry.
         */
        current_size = num_items(&siap->self);
        adp =
            (struct AccessDescription *)inject_casn(&siap->self, current_size);
        if (!adp)
        {
            fprintf(stderr, "Error: failed to append access description.\n");
            return -1;
        }

        if (write_objid(&adp->accessMethod,
                        (char *)sia_requests[i].accessMethod) < 0)
        {
            fprintf(stderr, "Error: failed to set access method.\n");
            return -1;
        }

        if (write_casn(&adp->accessLocation.url,
                       (unsigned char *)sia_requests[i].accessLocation,
                       strlen(sia_requests[i].accessLocation)) < 0)
        {
            fprintf(stderr, "Error: failed to set access location.\n");
            return -1;
        }
    }

    /*
     * Check for non-empty SIA (RFC 5280)
     */
    if (num_items(&siap->self) == 0)
    {
        fprintf(stderr,
                "SIA must have at least one AccessDescription, per RFC5280.\n");
        return -1;
    }

    /*
     * Write to file.
     */
    if (put_casn_file(&cert.self, (char *)file, 0) < 0)
    {
        fprintf(stderr, "Error: failed to write %s\n", file);
        return -4;
    }

    /*
     * Clean up.
     */
    delete_casn(&cert.self);
    return 0;
}
Ejemplo n.º 11
0
/*
 * ipv4 address are a comma separated list of either prefix or range
 * specifications for ipv4 addresses
 */
int write_cert_addrs(
    void *cert,
    void *val,
    int type)
{
    struct CertificateToBeSigned *tbsp =
        &((struct Certificate *)cert)->toBeSigned;
    struct Extension *extp;
    struct Extensions *extsp = &tbsp->extensions;
    struct IPAddressFamilyA *famp;
    char *ptr,
       *next,
       *buf;
    int ptr_len;
    char token = ',';
    char family[2];
    int num = 0;

    family[0] = 0;
    if (type == IPv4)
        family[1] = 1;
    else
        family[1] = 2;

    extp = find_extension(extsp, id_pe_ipAddrBlock, false);
    if (!extp)
    {
        extp = make_extension(extsp, id_pe_ipAddrBlock);
        write_casn_num(&extp->critical, 1);
    }

    if (type == IPv6)
        famp =
            (struct IPAddressFamilyA *)inject_casn(&extp->extnValue.
                                                   ipAddressBlock.self,
                                                   num_items(&extp->extnValue.
                                                             ipAddressBlock.
                                                             self));
    else
        famp =
            (struct IPAddressFamilyA *)inject_casn(&extp->extnValue.
                                                   ipAddressBlock.self, 0);

    write_casn(&famp->addressFamily, (unsigned char *)family, 2);

    // if it is inherit - set that and done
    if (strncmp(val, "inherit", strlen("inherit")) == 0)
    {
        struct IPAddressChoiceA *addrChoice = &famp->ipAddressChoice;
        write_casn(&addrChoice->inherit, (uchar *) "", 0);
        return SUCCESS;
    }

    // go through all addresses listed and add them to the block
    ptr = val;
    while (ptr != NULL)
    {
        next = strchr(ptr, token);
        while (isspace((int)(unsigned char)*ptr))
            ptr++;              // strip leading spaces
        if (next == NULL)
            ptr_len = strlen(ptr);
        else
        {
            ptr_len = (char *)next - (char *)ptr;
            next++;
        }
        if ((buf = strndup(ptr, ptr_len)) == NULL)
            return -1;

        if (write_family(famp, buf, num++) < 0)
            return -1;
        ptr = next;
    }

    return SUCCESS;
}