Exemplo n.º 1
0
/**
 * Construct a new x509 object.
 * @return 0 if ok. < 0 if there was a problem.
 */
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
    int begin_tbs, end_tbs;
    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
    X509_CTX *x509_ctx;
    BI_CTX *bi_ctx;

    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
    x509_ctx = *ctx;

    /* get the certificate size */
    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    begin_tbs = offset;         /* start of the tbs */
    end_tbs = begin_tbs;        /* work out the end of the tbs */
    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    if (cert[offset] == ASN1_EXPLICIT_TAG)   /* optional version */
    {
        if (asn1_version(cert, &offset, x509_ctx))
            goto end_cert;
    }

    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* make sure the signature is ok */
    if (asn1_signature_type(cert, &offset, x509_ctx))
    {
        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
        goto end_cert;
    }

    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
            asn1_validity(cert, &offset, x509_ctx) ||
            asn1_name(cert, &offset, x509_ctx->cert_dn) ||
            asn1_public_key(cert, &offset, x509_ctx))
    {
        goto end_cert;
    }

    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;

    x509_ctx->fingerprint = malloc(SHA1_SIZE);
    SHA1_CTX sha_fp_ctx;
    SHA1_Init(&sha_fp_ctx);
    SHA1_Update(&sha_fp_ctx, &cert[0], cert_size);
    SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx);

#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    /* use the appropriate signature algorithm (SHA1/MD5/MD2) */
    if (x509_ctx->sig_type == SIG_TYPE_MD5)
    {
        MD5_CTX md5_ctx;
        uint8_t md5_dgst[MD5_SIZE];
        MD5_Init(&md5_ctx);
        MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD5_Final(md5_dgst, &md5_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_SHA1)
    {
        SHA1_CTX sha_ctx;
        uint8_t sha_dgst[SHA1_SIZE];
        SHA1_Init(&sha_ctx);
        SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        SHA1_Final(sha_dgst, &sha_ctx);
        x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
    }
    else if (x509_ctx->sig_type == SIG_TYPE_MD2)
    {
        MD2_CTX md2_ctx;
        uint8_t md2_dgst[MD2_SIZE];
        MD2_Init(&md2_ctx);
        MD2_Update(&md2_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
        MD2_Final(md2_dgst, &md2_ctx);
        x509_ctx->digest = bi_import(bi_ctx, md2_dgst, MD2_SIZE);
    }

    if (cert[offset] == ASN1_V3_DATA)
    {
        int suboffset;

        ++offset;
        get_asn1_length(cert, &offset);

        if ((suboffset = asn1_find_subjectaltname(cert, offset)) > 0)
        {
            if (asn1_next_obj(cert, &suboffset, ASN1_OCTET_STRING) > 0)
            {
                int altlen;

                if ((altlen = asn1_next_obj(cert,
                                            &suboffset, ASN1_SEQUENCE)) > 0)
                {
                    int endalt = suboffset + altlen;
                    int totalnames = 0;

                    while (suboffset < endalt)
                    {
                        int type = cert[suboffset++];
                        int dnslen = get_asn1_length(cert, &suboffset);

                        if (type == ASN1_CONTEXT_DNSNAME)
                        {
                            x509_ctx->subject_alt_dnsnames = (char**)
                                                             realloc(x509_ctx->subject_alt_dnsnames,
                                                                     (totalnames + 2) * sizeof(char*));
                            x509_ctx->subject_alt_dnsnames[totalnames] =
                                (char*)malloc(dnslen + 1);
                            x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
                            memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
                                   cert + suboffset, dnslen);
                            x509_ctx->subject_alt_dnsnames[
                                totalnames][dnslen] = 0;
                            ++totalnames;
                        }

                        suboffset += dnslen;
                    }
                }
            }
        }
    }

    offset = end_tbs;   /* skip the rest of v3 data */
    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
            asn1_signature(cert, &offset, x509_ctx))
        goto end_cert;
#endif
    ret = X509_OK;
end_cert:
    if (len)
    {
        *len = cert_size;
    }

    if (ret)
    {
#ifdef CONFIG_SSL_FULL_MODE
        printf("Error: Invalid X509 ASN.1 file (%s)\n",
               x509_display_error(ret));
#endif
        x509_free(x509_ctx);
        *ctx = NULL;
    }

    return ret;
}
Exemplo n.º 2
0
/**
 * Construct a new x509 object.
 * @return 0 if ok. < 0 if there was a problem.
 */
int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
{
    int begin_tbs, end_tbs, begin_spki, end_spki;
    int ret = X509_NOT_OK, offset = 0, cert_size = 0;
    int version = 0;
    X509_CTX *x509_ctx;
#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    BI_CTX *bi_ctx;
#endif

    *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
    x509_ctx = *ctx;

    /* get the certificate size */
    asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE); 

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    begin_tbs = offset;         /* start of the tbs */
    end_tbs = begin_tbs;        /* work out the end of the tbs */
    asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);

    if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* optional version */
    if (cert[offset] == ASN1_EXPLICIT_TAG && 
            asn1_version(cert, &offset, &version) == X509_NOT_OK)
        goto end_cert;

    if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */ 
            asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
        goto end_cert;

    /* make sure the signature is ok */
    if (asn1_signature_type(cert, &offset, x509_ctx))
    {
        ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
        goto end_cert;
    }

    if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) || 
            asn1_validity(cert, &offset, x509_ctx) ||
            asn1_name(cert, &offset, x509_ctx->cert_dn))
    {
        goto end_cert;
    }
    begin_spki = offset;
    if (asn1_public_key(cert, &offset, x509_ctx))
        goto end_cert;
    end_spki = offset;

    x509_ctx->fingerprint = malloc(SHA1_SIZE);
    SHA1_CTX sha_fp_ctx;
    SHA1_Init(&sha_fp_ctx);
    SHA1_Update(&sha_fp_ctx, &cert[0], cert_size);
    SHA1_Final(x509_ctx->fingerprint, &sha_fp_ctx);

    x509_ctx->spki_sha256 = malloc(SHA256_SIZE);
    SHA256_CTX spki_hash_ctx;
    SHA256_Init(&spki_hash_ctx);
    SHA256_Update(&spki_hash_ctx, &cert[begin_spki], end_spki-begin_spki);
    SHA256_Final(x509_ctx->spki_sha256, &spki_hash_ctx);

#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
    bi_ctx = x509_ctx->rsa_ctx->bi_ctx;

    /* use the appropriate signature algorithm */
    switch (x509_ctx->sig_type)
    {
        case SIG_TYPE_MD5:
        {
            MD5_CTX md5_ctx;
            uint8_t md5_dgst[MD5_SIZE];
            MD5_Init(&md5_ctx);
            MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            MD5_Final(md5_dgst, &md5_ctx);
            x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
        }
            break;

        case SIG_TYPE_SHA1:
        {
            SHA1_CTX sha_ctx;
            uint8_t sha_dgst[SHA1_SIZE];
            SHA1_Init(&sha_ctx);
            SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA1_Final(sha_dgst, &sha_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
        }
            break;

        case SIG_TYPE_SHA256:
        {
            SHA256_CTX sha256_ctx;
            uint8_t sha256_dgst[SHA256_SIZE];
            SHA256_Init(&sha256_ctx);
            SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA256_Final(sha256_dgst, &sha256_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE);
        }
            break;

        case SIG_TYPE_SHA384:
        {
            SHA384_CTX sha384_ctx;
            uint8_t sha384_dgst[SHA384_SIZE];
            SHA384_Init(&sha384_ctx);
            SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA384_Final(sha384_dgst, &sha384_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE);
        }
            break;

        case SIG_TYPE_SHA512:
        {
            SHA512_CTX sha512_ctx;
            uint8_t sha512_dgst[SHA512_SIZE];
            SHA512_Init(&sha512_ctx);
            SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
            SHA512_Final(sha512_dgst, &sha512_ctx);
            x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE);
        }
            break;
    }

    if (version == 2 && asn1_next_obj(cert, &offset, ASN1_V3_DATA) > 0)
    {
        x509_v3_subject_alt_name(cert, offset, x509_ctx);
        x509_v3_basic_constraints(cert, offset, x509_ctx);
        x509_v3_key_usage(cert, offset, x509_ctx);
    }

    offset = end_tbs;   /* skip the rest of v3 data */
    if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) || 
            asn1_signature(cert, &offset, x509_ctx))
        goto end_cert;

    /* Saves a few bytes of memory */
    bi_clear_cache(bi_ctx);
#endif
    ret = X509_OK;
end_cert:
    if (len)
    {
        *len = cert_size;
    }

    if (ret)
    {
#ifdef CONFIG_SSL_FULL_MODE
        char buff[64];
        printf("Error: Invalid X509 ASN.1 file (%s)\n",
                        x509_display_error(ret, buff));
#endif
        x509_free(x509_ctx);
        *ctx = NULL;
    }

    return ret;
}
Exemplo n.º 3
0
void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
{
    if (cert == NULL)
        return;

    printf("=== CERTIFICATE ISSUED TO ===\n");
    printf("Common Name (CN):\t\t");
    printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
           cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);

    printf("Organization (O):\t\t");
    printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
           cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);

    printf("Organizational Unit (OU):\t");
    printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT] ?
           cert->cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);

    printf("=== CERTIFICATE ISSUED BY ===\n");
    printf("Common Name (CN):\t\t");
    printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
           cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);

    printf("Organization (O):\t\t");
    printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
           cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);

    printf("Organizational Unit (OU):\t");
    printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] ?
           cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT] : not_part_of_cert);

    printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
    printf("Not After:\t\t\t%s", ctime(&cert->not_after));
    printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
    printf("Sig Type:\t\t\t");
    switch (cert->sig_type)
    {
    case SIG_TYPE_MD5:
        printf("MD5\n");
        break;
    case SIG_TYPE_SHA1:
        printf("SHA1\n");
        break;
    case SIG_TYPE_MD2:
        printf("MD2\n");
        break;
    default:
        printf("Unrecognized: %d\n", cert->sig_type);
        break;
    }

    if (ca_cert_ctx)
    {
        printf("Verify:\t\t\t\t%s\n",
               x509_display_error(x509_verify(ca_cert_ctx, cert)));
    }

#if 0
    print_blob("Signature", cert->signature, cert->sig_len);
    bi_print("Modulus", cert->rsa_ctx->m);
    bi_print("Pub Exp", cert->rsa_ctx->e);
#endif

    if (ca_cert_ctx)
    {
        x509_print(cert->next, ca_cert_ctx);
    }

    TTY_FLUSH();
}
Exemplo n.º 4
0
void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx) 
{
    if (cert == NULL)
        return;

    printf("=== CERTIFICATE ISSUED TO ===\n");
    printf("Common Name (CN):\t\t");
    printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
                    cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);

    printf("Organization (O):\t\t");
    printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
        cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);

    if (cert->cert_dn[X509_ORGANIZATIONAL_UNIT]) 
    {
        printf("Organizational Unit (OU):\t");
        printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT]);
    }

    if (cert->cert_dn[X509_LOCATION]) 
    {
        printf("Location (L):\t\t\t");
        printf("%s\n", cert->cert_dn[X509_LOCATION]);
    }

    if (cert->cert_dn[X509_COUNTRY]) 
    {
        printf("Country (C):\t\t\t");
        printf("%s\n", cert->cert_dn[X509_COUNTRY]);
    }

    if (cert->cert_dn[X509_STATE]) 
    {
        printf("State (ST):\t\t\t");
        printf("%s\n", cert->cert_dn[X509_STATE]);
    }

    if (cert->basic_constraint_present)
    {
        printf("Basic Constraints:\t\t%sCA:%s, pathlen:%d\n",
                cert->basic_constraint_is_critical ? 
                    "critical, " : "",
                cert->basic_constraint_cA? "TRUE" : "FALSE",
                cert->basic_constraint_pathLenConstraint);
    }

    if (cert->key_usage_present)
    {
        printf("Key Usage:\t\t\t%s", cert->key_usage_is_critical ? 
                    "critical, " : "");
        bool has_started = false;

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DIGITAL_SIGNATURE))
        {
            printf("Digital Signature");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_NON_REPUDIATION))
        {
            if (has_started)
                printf(", ");

            printf("Non Repudiation");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_ENCIPHERMENT))
        {
            if (has_started)
                printf(", ");

            printf("Key Encipherment");
            has_started = true;
        }
        
        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DATA_ENCIPHERMENT))
        {
            if (has_started)
                printf(", ");

            printf("Data Encipherment");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_AGREEMENT))
        {
            if (has_started)
                printf(", ");

            printf("Key Agreement");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN))
        {
            if (has_started)
                printf(", ");

            printf("Key Cert Sign");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_CRL_SIGN))
        {
            if (has_started)
                printf(", ");

            printf("CRL Sign");
            has_started = true;
        }
       
        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_ENCIPHER_ONLY))
        {
            if (has_started)
                printf(", ");

            printf("Encipher Only");
            has_started = true;
        }

        if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DECIPHER_ONLY))
        {
            if (has_started)
                printf(", ");

            printf("Decipher Only");
            has_started = true;
        }

        printf("\n");
    }

    if (cert->subject_alt_name_present)
    {
        printf("Subject Alt Name:\t\t%s", cert->subject_alt_name_is_critical 
                ?  "critical, " : "");
        if (cert->subject_alt_dnsnames)
        {
            int i = 0;

            while (cert->subject_alt_dnsnames[i])
                printf("%s ", cert->subject_alt_dnsnames[i++]);
        }
        printf("\n");

    }

    printf("=== CERTIFICATE ISSUED BY ===\n");
    printf("Common Name (CN):\t\t");
    printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
                    cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);

    printf("Organization (O):\t\t");
    printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
        cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);

    if (cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]) 
    {
        printf("Organizational Unit (OU):\t");
        printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]);
    }

    if (cert->ca_cert_dn[X509_LOCATION]) 
    {
        printf("Location (L):\t\t\t");
        printf("%s\n", cert->ca_cert_dn[X509_LOCATION]);
    }

    if (cert->ca_cert_dn[X509_COUNTRY]) 
    {
        printf("Country (C):\t\t\t");
        printf("%s\n", cert->ca_cert_dn[X509_COUNTRY]);
    }

    if (cert->ca_cert_dn[X509_STATE]) 
    {
        printf("State (ST):\t\t\t");
        printf("%s\n", cert->ca_cert_dn[X509_STATE]);
    }

    printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
    printf("Not After:\t\t\t%s", ctime(&cert->not_after));
    printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
    printf("Sig Type:\t\t\t");
    switch (cert->sig_type)
    {
        case SIG_TYPE_MD5:
            printf("MD5\n");
            break;
        case SIG_TYPE_SHA1:
            printf("SHA1\n");
            break;
        case SIG_TYPE_SHA256:
            printf("SHA256\n");
            break;
        case SIG_TYPE_SHA384:
            printf("SHA384\n");
            break;
        case SIG_TYPE_SHA512:
            printf("SHA512\n");
            break;
        default:
            printf("Unrecognized: %d\n", cert->sig_type);
            break;
    }

    if (ca_cert_ctx)
    {
        int pathLenConstraint = 0;
        char buff[64];
        printf("Verify:\t\t\t\t%s\n",
                x509_display_error(x509_verify(ca_cert_ctx, cert,
                        &pathLenConstraint), buff));
    }

#if 0
    print_blob("Signature", cert->signature, cert->sig_len);
    bi_print("Modulus", cert->rsa_ctx->m);
    bi_print("Pub Exp", cert->rsa_ctx->e);
#endif

    if (ca_cert_ctx)
    {
        x509_print(cert->next, ca_cert_ctx);
    }

    TTY_FLUSH();
}