示例#1
0
int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex)
{
    unsigned char *bin;
    long binlen;
    int rv = -1;

    bin = OPENSSL_hexstr2buf(hex, &binlen);
    if (bin == NULL)
        return 0;
    if (binlen <= INT_MAX)
        rv = ctx->pmeth->ctrl(ctx, cmd, binlen, bin);
    OPENSSL_free(bin);
    return rv;
}
static int load_record(SSL3_RECORD *rec, RECORD_DATA *recd, unsigned char **key,
                       unsigned char *iv, size_t ivlen, unsigned char *seq)
{
    unsigned char *pt = NULL, *sq = NULL, *ivtmp = NULL;
    size_t ptlen;

    *key = OPENSSL_hexstr2buf(recd->key, NULL);
    ivtmp = OPENSSL_hexstr2buf(recd->iv, NULL);
    sq = OPENSSL_hexstr2buf(recd->seq, NULL);
    pt = multihexstr2buf(recd->plaintext, &ptlen);

    if (*key == NULL || ivtmp == NULL || sq == NULL || pt == NULL)
        goto err;

    rec->data = rec->input = OPENSSL_malloc(ptlen + EVP_GCM_TLS_TAG_LEN);

    if (rec->data == NULL)
        goto err;

    rec->length = ptlen;
    memcpy(rec->data, pt, ptlen);
    OPENSSL_free(pt);
    memcpy(seq, sq, SEQ_NUM_SIZE);
    OPENSSL_free(sq);
    memcpy(iv, ivtmp, ivlen);
    OPENSSL_free(ivtmp);

    return 1;
 err:
    OPENSSL_free(*key);
    *key = NULL;
    OPENSSL_free(ivtmp);
    OPENSSL_free(sq);
    OPENSSL_free(pt);
    return 0;
}
示例#3
0
/* Create a generic extension: for now just handle DER type */
static X509_EXTENSION *v3_generic_extension(const char *ext, const char *value,
                                            int crit, int gen_type,
                                            X509V3_CTX *ctx)
{
    unsigned char *ext_der = NULL;
    long ext_len = 0;
    ASN1_OBJECT *obj = NULL;
    ASN1_OCTET_STRING *oct = NULL;
    X509_EXTENSION *extension = NULL;

    if ((obj = OBJ_txt2obj(ext, 0)) == NULL) {
        X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
                  X509V3_R_EXTENSION_NAME_ERROR);
        ERR_add_error_data(2, "name=", ext);
        goto err;
    }

    if (gen_type == 1)
        ext_der = OPENSSL_hexstr2buf(value, &ext_len);
    else if (gen_type == 2)
        ext_der = generic_asn1(value, ctx, &ext_len);

    if (ext_der == NULL) {
        X509V3err(X509V3_F_V3_GENERIC_EXTENSION,
                  X509V3_R_EXTENSION_VALUE_ERROR);
        ERR_add_error_data(2, "value=", value);
        goto err;
    }

    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
        X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    oct->data = ext_der;
    oct->length = ext_len;
    ext_der = NULL;

    extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct);

 err:
    ASN1_OBJECT_free(obj);
    ASN1_OCTET_STRING_free(oct);
    OPENSSL_free(ext_der);
    return extension;

}
示例#4
0
文件: kdf_util.c 项目: Ana06/openssl
int kdf_hex2ctrl(EVP_KDF_IMPL *impl,
                 int (*ctrl)(EVP_KDF_IMPL *impl, int cmd, va_list args),
                 int cmd, const char *hex)
{
    unsigned char *bin;
    long binlen;
    int ret = -1;

    bin = OPENSSL_hexstr2buf(hex, &binlen);
    if (bin == NULL)
        return 0;

    if (binlen <= INT_MAX)
        ret = call_ctrl(ctrl, impl, cmd, bin, (size_t)binlen);
    OPENSSL_free(bin);
    return ret;
}
示例#5
0
文件: ts.c 项目: Beatzevo/openssl
static int create_digest(BIO *input, char *digest, const EVP_MD *md,
                         unsigned char **md_value)
{
    int md_value_len;
    int rv = 0;
    EVP_MD_CTX *md_ctx = NULL;

    md_value_len = EVP_MD_size(md);
    if (md_value_len < 0)
        return 0;

    if (input) {
        unsigned char buffer[4096];
        int length;

        md_ctx = EVP_MD_CTX_new();
        if (md_ctx == NULL)
            return 0;
        *md_value = app_malloc(md_value_len, "digest buffer");
        if (!EVP_DigestInit(md_ctx, md))
            goto err;
        while ((length = BIO_read(input, buffer, sizeof(buffer))) > 0) {
            if (!EVP_DigestUpdate(md_ctx, buffer, length))
                goto err;
        }
        if (!EVP_DigestFinal(md_ctx, *md_value, NULL))
            goto err;
        md_value_len = EVP_MD_size(md);
    } else {
        long digest_len;
        *md_value = OPENSSL_hexstr2buf(digest, &digest_len);
        if (!*md_value || md_value_len != digest_len) {
            OPENSSL_free(*md_value);
            *md_value = NULL;
            BIO_printf(bio_err, "bad digest, %d bytes "
                       "must be specified\n", md_value_len);
            return 0;
        }
    }
    rv = md_value_len;
 err:
    EVP_MD_CTX_free(md_ctx);
    return rv;
}
示例#6
0
ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
                                         X509V3_CTX *ctx, const char *str)
{
    ASN1_OCTET_STRING *oct;
    long length;

    if ((oct = ASN1_OCTET_STRING_new()) == NULL) {
        X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if ((oct->data = OPENSSL_hexstr2buf(str, &length)) == NULL) {
        ASN1_OCTET_STRING_free(oct);
        return NULL;
    }

    oct->length = length;

    return oct;

}
示例#7
0
static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx,
                              const char *type, const char *value)
{
    if (!value) {
        return 0;
    }
    if (strcmp(type, "key") == 0) {
        void *p = (void *)value;
        return ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p);
    }
    if (strcmp(type, "hexkey") == 0) {
        unsigned char *key;
        int r;
        long keylen;
        key = OPENSSL_hexstr2buf(value, &keylen);
        if (!key)
            return 0;
        r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key);
        OPENSSL_free(key);
        return r;
    }
    return -2;
}
示例#8
0
文件: ts.c 项目: Beatzevo/openssl
static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest,
                                        char *queryfile,
                                        char *CApath, char *CAfile,
                                        char *untrusted,
                                        X509_VERIFY_PARAM *vpm)
{
    TS_VERIFY_CTX *ctx = NULL;
    BIO *input = NULL;
    TS_REQ *request = NULL;
    int ret = 0;
    int f = 0;

    if (data != NULL || digest != NULL) {
        if ((ctx = TS_VERIFY_CTX_new()) == NULL)
            goto err;
        f = TS_VFY_VERSION | TS_VFY_SIGNER;
        if (data != NULL) {
            f |= TS_VFY_DATA;
            if (TS_VERIFY_CTX_set_data(ctx, BIO_new_file(data, "rb")) == NULL)
                goto err;
        } else if (digest != NULL) {
            long imprint_len;
            unsigned char *hexstr = OPENSSL_hexstr2buf(digest, &imprint_len);
            f |= TS_VFY_IMPRINT;
            if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) {
                BIO_printf(bio_err, "invalid digest string\n");
                goto err;
            }
        }

    } else if (queryfile != NULL) {
        if ((input = BIO_new_file(queryfile, "rb")) == NULL)
            goto err;
        if ((request = d2i_TS_REQ_bio(input, NULL)) == NULL)
            goto err;
        if ((ctx = TS_REQ_to_TS_VERIFY_CTX(request, NULL)) == NULL)
            goto err;
    } else
        return NULL;

    /* Add the signature verification flag and arguments. */
    TS_VERIFY_CTX_add_flags(ctx, f | TS_VFY_SIGNATURE);

    /* Initialising the X509_STORE object. */
    if (TS_VERIFY_CTX_set_store(ctx, create_cert_store(CApath, CAfile, vpm))
            == NULL)
        goto err;

    /* Loading untrusted certificates. */
    if (untrusted
        && TS_VERIFY_CTS_set_certs(ctx, TS_CONF_load_certs(untrusted)) == NULL)
        goto err;
    ret = 1;

 err:
    if (!ret) {
        TS_VERIFY_CTX_free(ctx);
        ctx = NULL;
    }
    BIO_free_all(input);
    TS_REQ_free(request);
    return ctx;
}
示例#9
0
文件: v3_pci.c 项目: 1234-/openssl
static int process_pci_value(CONF_VALUE *val,
                             ASN1_OBJECT **language, ASN1_INTEGER **pathlen,
                             ASN1_OCTET_STRING **policy)
{
    int free_policy = 0;

    if (strcmp(val->name, "language") == 0) {
        if (*language) {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                      X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
            X509V3_conf_err(val);
            return 0;
        }
        if ((*language = OBJ_txt2obj(val->value, 0)) == NULL) {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                      X509V3_R_INVALID_OBJECT_IDENTIFIER);
            X509V3_conf_err(val);
            return 0;
        }
    } else if (strcmp(val->name, "pathlen") == 0) {
        if (*pathlen) {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                      X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
            X509V3_conf_err(val);
            return 0;
        }
        if (!X509V3_get_value_int(val, pathlen)) {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                      X509V3_R_POLICY_PATH_LENGTH);
            X509V3_conf_err(val);
            return 0;
        }
    } else if (strcmp(val->name, "policy") == 0) {
        unsigned char *tmp_data = NULL;
        long val_len;
        if (!*policy) {
            *policy = ASN1_OCTET_STRING_new();
            if (*policy == NULL) {
                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
                X509V3_conf_err(val);
                return 0;
            }
            free_policy = 1;
        }
        if (strncmp(val->value, "hex:", 4) == 0) {
            unsigned char *tmp_data2 =
                OPENSSL_hexstr2buf(val->value + 4, &val_len);

            if (!tmp_data2) {
                X509V3_conf_err(val);
                goto err;
            }

            tmp_data = OPENSSL_realloc((*policy)->data,
                                       (*policy)->length + val_len + 1);
            if (tmp_data) {
                (*policy)->data = tmp_data;
                memcpy(&(*policy)->data[(*policy)->length],
                       tmp_data2, val_len);
                (*policy)->length += val_len;
                (*policy)->data[(*policy)->length] = '\0';
            } else {
                OPENSSL_free(tmp_data2);
                /*
                 * realloc failure implies the original data space is b0rked
                 * too!
                 */
                OPENSSL_free((*policy)->data);
                (*policy)->data = NULL;
                (*policy)->length = 0;
                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
                X509V3_conf_err(val);
                goto err;
            }
            OPENSSL_free(tmp_data2);
        } else if (strncmp(val->value, "file:", 5) == 0) {
            unsigned char buf[2048];
            int n;
            BIO *b = BIO_new_file(val->value + 5, "r");
            if (!b) {
                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
                X509V3_conf_err(val);
                goto err;
            }
            while ((n = BIO_read(b, buf, sizeof(buf))) > 0
                   || (n == 0 && BIO_should_retry(b))) {
                if (!n)
                    continue;

                tmp_data = OPENSSL_realloc((*policy)->data,
                                           (*policy)->length + n + 1);

                if (!tmp_data) {
                    OPENSSL_free((*policy)->data);
                    (*policy)->data = NULL;
                    (*policy)->length = 0;
                    X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                              ERR_R_MALLOC_FAILURE);
                    X509V3_conf_err(val);
                    BIO_free_all(b);
                    goto err;
                }

                (*policy)->data = tmp_data;
                memcpy(&(*policy)->data[(*policy)->length], buf, n);
                (*policy)->length += n;
                (*policy)->data[(*policy)->length] = '\0';
            }
            BIO_free_all(b);

            if (n < 0) {
                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB);
                X509V3_conf_err(val);
                goto err;
            }
        } else if (strncmp(val->value, "text:", 5) == 0) {
            val_len = strlen(val->value + 5);
            tmp_data = OPENSSL_realloc((*policy)->data,
                                       (*policy)->length + val_len + 1);
            if (tmp_data) {
                (*policy)->data = tmp_data;
                memcpy(&(*policy)->data[(*policy)->length],
                       val->value + 5, val_len);
                (*policy)->length += val_len;
                (*policy)->data[(*policy)->length] = '\0';
            } else {
                /*
                 * realloc failure implies the original data space is b0rked
                 * too!
                 */
                OPENSSL_free((*policy)->data);
                (*policy)->data = NULL;
                (*policy)->length = 0;
                X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
                X509V3_conf_err(val);
                goto err;
            }
        } else {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE,
                      X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
            X509V3_conf_err(val);
            goto err;
        }
        if (!tmp_data) {
            X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE);
            X509V3_conf_err(val);
            goto err;
        }
    }
    return 1;
 err:
    if (free_policy) {
        ASN1_OCTET_STRING_free(*policy);
        *policy = NULL;
    }
    return 0;
}
示例#10
0
static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
{
    ASN1_TYPE *atmp = NULL;
    CONF_VALUE vtmp;
    unsigned char *rdata;
    long rdlen;
    int no_unused = 1;

    if ((atmp = ASN1_TYPE_new()) == NULL) {
        ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }

    if (!str)
        str = "";

    switch (utype) {

    case V_ASN1_NULL:
        if (str && *str) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE);
            goto bad_form;
        }
        break;

    case V_ASN1_BOOLEAN:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        vtmp.name = NULL;
        vtmp.section = NULL;
        vtmp.value = (char *)str;
        if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN);
            goto bad_str;
        }
        break;

    case V_ASN1_INTEGER:
    case V_ASN1_ENUMERATED:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if ((atmp->value.integer
                    = s2i_ASN1_INTEGER(NULL, str)) == NULL) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER);
            goto bad_str;
        }
        break;

    case V_ASN1_OBJECT:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if ((atmp->value.object = OBJ_txt2obj(str, 0)) == NULL) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT);
            goto bad_str;
        }
        break;

    case V_ASN1_UTCTIME:
    case V_ASN1_GENERALIZEDTIME:
        if (format != ASN1_GEN_FORMAT_ASCII) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT);
            goto bad_form;
        }
        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }
        if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }
        atmp->value.asn1_string->type = utype;
        if (!ASN1_TIME_check(atmp->value.asn1_string)) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE);
            goto bad_str;
        }

        break;

    case V_ASN1_BMPSTRING:
    case V_ASN1_PRINTABLESTRING:
    case V_ASN1_IA5STRING:
    case V_ASN1_T61STRING:
    case V_ASN1_UTF8STRING:
    case V_ASN1_VISIBLESTRING:
    case V_ASN1_UNIVERSALSTRING:
    case V_ASN1_GENERALSTRING:
    case V_ASN1_NUMERICSTRING:
        if (format == ASN1_GEN_FORMAT_ASCII)
            format = MBSTRING_ASC;
        else if (format == ASN1_GEN_FORMAT_UTF8)
            format = MBSTRING_UTF8;
        else {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT);
            goto bad_form;
        }

        if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
                               -1, format, ASN1_tag2bit(utype)) <= 0) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_str;
        }

        break;

    case V_ASN1_BIT_STRING:
    case V_ASN1_OCTET_STRING:
        if ((atmp->value.asn1_string = ASN1_STRING_new()) == NULL) {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE);
            goto bad_form;
        }

        if (format == ASN1_GEN_FORMAT_HEX) {
            if ((rdata = OPENSSL_hexstr2buf(str, &rdlen)) == NULL) {
                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX);
                goto bad_str;
            }
            atmp->value.asn1_string->data = rdata;
            atmp->value.asn1_string->length = rdlen;
            atmp->value.asn1_string->type = utype;
        } else if (format == ASN1_GEN_FORMAT_ASCII)
            ASN1_STRING_set(atmp->value.asn1_string, str, -1);
        else if ((format == ASN1_GEN_FORMAT_BITLIST)
                 && (utype == V_ASN1_BIT_STRING)) {
            if (!CONF_parse_list
                (str, ',', 1, bitstr_cb, atmp->value.bit_string)) {
                ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR);
                goto bad_str;
            }
            no_unused = 0;

        } else {
            ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
            goto bad_form;
        }

        if ((utype == V_ASN1_BIT_STRING) && no_unused) {
            atmp->value.asn1_string->flags
                &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
            atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT;
        }

        break;

    default:
        ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE);
        goto bad_str;
    }

    atmp->type = utype;
    return atmp;

 bad_str:
    ERR_add_error_data(2, "string=", str);
 bad_form:

    ASN1_TYPE_free(atmp);
    return NULL;

}
示例#11
0
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
                             const char *type, const char *value)
{
    if (value == NULL) {
        RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
        return 0;
    }
    if (strcmp(type, "rsa_padding_mode") == 0) {
        int pm;
        if (strcmp(value, "pkcs1") == 0) {
            pm = RSA_PKCS1_PADDING;
        } else if (strcmp(value, "sslv23") == 0) {
            pm = RSA_SSLV23_PADDING;
        } else if (strcmp(value, "none") == 0) {
            pm = RSA_NO_PADDING;
        } else if (strcmp(value, "oeap") == 0) {
            pm = RSA_PKCS1_OAEP_PADDING;
        } else if (strcmp(value, "oaep") == 0) {
            pm = RSA_PKCS1_OAEP_PADDING;
        } else if (strcmp(value, "x931") == 0) {
            pm = RSA_X931_PADDING;
        } else if (strcmp(value, "pss") == 0) {
            pm = RSA_PKCS1_PSS_PADDING;
        } else {
            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE);
            return -2;
        }
        return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
    }

    if (strcmp(type, "rsa_pss_saltlen") == 0) {
        int saltlen;
        if (!strcmp(value, "digest"))
            saltlen = RSA_PSS_SALTLEN_DIGEST;
        else if (!strcmp(value, "max"))
            saltlen = RSA_PSS_SALTLEN_MAX;
        else if (!strcmp(value, "auto"))
            saltlen = RSA_PSS_SALTLEN_AUTO;
        else
            saltlen = atoi(value);
        return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
    }

    if (strcmp(type, "rsa_keygen_bits") == 0) {
        int nbits;
        nbits = atoi(value);
        return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
    }

    if (strcmp(type, "rsa_keygen_pubexp") == 0) {
        int ret;
        BIGNUM *pubexp = NULL;
        if (!BN_asc2bn(&pubexp, value))
            return 0;
        ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
        if (ret <= 0)
            BN_free(pubexp);
        return ret;
    }

    if (strcmp(type, "rsa_mgf1_md") == 0)
        return EVP_PKEY_CTX_md(ctx,
                               EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT,
                               EVP_PKEY_CTRL_RSA_MGF1_MD, value);

    if (pkey_ctx_is_pss(ctx)) {

        if (strcmp(type, "rsa_pss_keygen_mgf1_md") == 0)
            return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN,
                                   EVP_PKEY_CTRL_RSA_MGF1_MD, value);

        if (strcmp(type, "rsa_pss_keygen_md") == 0)
            return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_KEYGEN,
                                   EVP_PKEY_CTRL_MD, value);

        if (strcmp(type, "rsa_pss_keygen_saltlen") == 0) {
            int saltlen = atoi(value);

            return EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(ctx, saltlen);
        }
    }

    if (strcmp(type, "rsa_oaep_md") == 0)
        return EVP_PKEY_CTX_md(ctx, EVP_PKEY_OP_TYPE_CRYPT,
                               EVP_PKEY_CTRL_RSA_OAEP_MD, value);

    if (strcmp(type, "rsa_oaep_label") == 0) {
        unsigned char *lab;
        long lablen;
        int ret;
        lab = OPENSSL_hexstr2buf(value, &lablen);
        if (!lab)
            return 0;
        ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
        if (ret <= 0)
            OPENSSL_free(lab);
        return ret;
    }

    return -2;
}
示例#12
0
文件: rsa_pmeth.c 项目: 4ker/openssl
static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx,
                             const char *type, const char *value)
{
    if (!value) {
        RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING);
        return 0;
    }
    if (strcmp(type, "rsa_padding_mode") == 0) {
        int pm;
        if (strcmp(value, "pkcs1") == 0)
            pm = RSA_PKCS1_PADDING;
        else if (strcmp(value, "sslv23") == 0)
            pm = RSA_SSLV23_PADDING;
        else if (strcmp(value, "none") == 0)
            pm = RSA_NO_PADDING;
        else if (strcmp(value, "oeap") == 0)
            pm = RSA_PKCS1_OAEP_PADDING;
        else if (strcmp(value, "oaep") == 0)
            pm = RSA_PKCS1_OAEP_PADDING;
        else if (strcmp(value, "x931") == 0)
            pm = RSA_X931_PADDING;
        else if (strcmp(value, "pss") == 0)
            pm = RSA_PKCS1_PSS_PADDING;
        else {
            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE);
            return -2;
        }
        return EVP_PKEY_CTX_set_rsa_padding(ctx, pm);
    }

    if (strcmp(type, "rsa_pss_saltlen") == 0) {
        int saltlen;
        saltlen = atoi(value);
        return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen);
    }

    if (strcmp(type, "rsa_keygen_bits") == 0) {
        int nbits;
        nbits = atoi(value);
        return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits);
    }

    if (strcmp(type, "rsa_keygen_pubexp") == 0) {
        int ret;
        BIGNUM *pubexp = NULL;
        if (!BN_asc2bn(&pubexp, value))
            return 0;
        ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp);
        if (ret <= 0)
            BN_free(pubexp);
        return ret;
    }

    if (strcmp(type, "rsa_mgf1_md") == 0) {
        const EVP_MD *md;
        if ((md = EVP_get_digestbyname(value)) == NULL) {
            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
            return 0;
        }
        return EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md);
    }

    if (strcmp(type, "rsa_oaep_md") == 0) {
        const EVP_MD *md;
        if ((md = EVP_get_digestbyname(value)) == NULL) {
            RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_INVALID_DIGEST);
            return 0;
        }
        return EVP_PKEY_CTX_set_rsa_oaep_md(ctx, md);
    }
    if (strcmp(type, "rsa_oaep_label") == 0) {
        unsigned char *lab;
        long lablen;
        int ret;
        lab = OPENSSL_hexstr2buf(value, &lablen);
        if (!lab)
            return 0;
        ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen);
        if (ret <= 0)
            OPENSSL_free(lab);
        return ret;
    }

    return -2;
}
示例#13
0
文件: cms.c 项目: Muffo/openssl
int cms_main(int argc, char **argv)
{
    ASN1_OBJECT *econtent_type = NULL;
    BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
    CMS_ContentInfo *cms = NULL, *rcms = NULL;
    CMS_ReceiptRequest *rr = NULL;
    ENGINE *e = NULL;
    EVP_PKEY *key = NULL;
    const EVP_CIPHER *cipher = NULL, *wrap_cipher = NULL;
    const EVP_MD *sign_md = NULL;
    STACK_OF(OPENSSL_STRING) *rr_to = NULL, *rr_from = NULL;
    STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL;
    STACK_OF(X509) *encerts = NULL, *other = NULL;
    X509 *cert = NULL, *recip = NULL, *signer = NULL;
    X509_STORE *store = NULL;
    X509_VERIFY_PARAM *vpm = NULL;
    char *certfile = NULL, *keyfile = NULL, *contfile = NULL;
    const char *CAfile = NULL, *CApath = NULL;
    char *certsoutfile = NULL;
    int noCAfile = 0, noCApath = 0;
    char *infile = NULL, *outfile = NULL, *rctfile = NULL, *inrand = NULL;
    char *passinarg = NULL, *passin = NULL, *signerfile = NULL, *recipfile =
        NULL;
    char *to = NULL, *from = NULL, *subject = NULL, *prog;
    cms_key_param *key_first = NULL, *key_param = NULL;
    int flags = CMS_DETACHED, noout = 0, print = 0, keyidx = -1, vpmtouched =
        0;
    int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
    int need_rand = 0, operation = 0, ret = 1, rr_print = 0, rr_allorfirst =
        -1;
    int verify_retcode = 0, rctformat = FORMAT_SMIME, keyform = FORMAT_PEM;
    size_t secret_keylen = 0, secret_keyidlen = 0;
    unsigned char *pwri_pass = NULL, *pwri_tmp = NULL;
    unsigned char *secret_key = NULL, *secret_keyid = NULL;
    long ltmp;
    const char *mime_eol = "\n";
    OPTION_CHOICE o;

    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
        return 1;

    prog = opt_init(argc, argv, cms_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(cms_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat))
                goto opthelp;
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat))
                goto opthelp;
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_ENCRYPT:
            operation = SMIME_ENCRYPT;
            break;
        case OPT_DECRYPT:
            operation = SMIME_DECRYPT;
            break;
        case OPT_SIGN:
            operation = SMIME_SIGN;
            break;
        case OPT_SIGN_RECEIPT:
            operation = SMIME_SIGN_RECEIPT;
            break;
        case OPT_RESIGN:
            operation = SMIME_RESIGN;
            break;
        case OPT_VERIFY:
            operation = SMIME_VERIFY;
            break;
        case OPT_VERIFY_RETCODE:
            verify_retcode = 1;
            break;
        case OPT_VERIFY_RECEIPT:
            operation = SMIME_VERIFY_RECEIPT;
            rctfile = opt_arg();
            break;
        case OPT_CMSOUT:
            operation = SMIME_CMSOUT;
            break;
        case OPT_DATA_OUT:
            operation = SMIME_DATAOUT;
            break;
        case OPT_DATA_CREATE:
            operation = SMIME_DATA_CREATE;
            break;
        case OPT_DIGEST_VERIFY:
            operation = SMIME_DIGEST_VERIFY;
            break;
        case OPT_DIGEST_CREATE:
            operation = SMIME_DIGEST_CREATE;
            break;
        case OPT_COMPRESS:
            operation = SMIME_COMPRESS;
            break;
        case OPT_UNCOMPRESS:
            operation = SMIME_UNCOMPRESS;
            break;
        case OPT_ED_DECRYPT:
            operation = SMIME_ENCRYPTED_DECRYPT;
            break;
        case OPT_ED_ENCRYPT:
            operation = SMIME_ENCRYPTED_ENCRYPT;
            break;
        case OPT_DEBUG_DECRYPT:
            flags |= CMS_DEBUG_DECRYPT;
            break;
        case OPT_TEXT:
            flags |= CMS_TEXT;
            break;
        case OPT_ASCIICRLF:
            flags |= CMS_ASCIICRLF;
            break;
        case OPT_NOINTERN:
            flags |= CMS_NOINTERN;
            break;
        case OPT_NOVERIFY:
            flags |= CMS_NO_SIGNER_CERT_VERIFY;
            break;
        case OPT_NOCERTS:
            flags |= CMS_NOCERTS;
            break;
        case OPT_NOATTR:
            flags |= CMS_NOATTR;
            break;
        case OPT_NODETACH:
            flags &= ~CMS_DETACHED;
            break;
        case OPT_NOSMIMECAP:
            flags |= CMS_NOSMIMECAP;
            break;
        case OPT_BINARY:
            flags |= CMS_BINARY;
            break;
        case OPT_KEYID:
            flags |= CMS_USE_KEYID;
            break;
        case OPT_NOSIGS:
            flags |= CMS_NOSIGS;
            break;
        case OPT_NO_CONTENT_VERIFY:
            flags |= CMS_NO_CONTENT_VERIFY;
            break;
        case OPT_NO_ATTR_VERIFY:
            flags |= CMS_NO_ATTR_VERIFY;
            break;
        case OPT_INDEF:
            flags |= CMS_STREAM;
            break;
        case OPT_NOINDEF:
            flags &= ~CMS_STREAM;
            break;
        case OPT_NOOLDMIME:
            flags |= CMS_NOOLDMIMETYPE;
            break;
        case OPT_CRLFEOL:
            mime_eol = "\r\n";
            flags |= CMS_CRLFEOL;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_RR_PRINT:
            rr_print = 1;
            break;
        case OPT_RR_ALL:
            rr_allorfirst = 0;
            break;
        case OPT_RR_FIRST:
            rr_allorfirst = 1;
            break;
        case OPT_RCTFORM:
            if (rctformat == FORMAT_SMIME)
                rcms = SMIME_read_CMS(rctin, NULL);
            else if (rctformat == FORMAT_PEM)
                rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
            else if (rctformat == FORMAT_ASN1)
                if (!opt_format(opt_arg(),
                                OPT_FMT_PEMDER | OPT_FMT_SMIME, &rctformat))
                    goto opthelp;
            break;
        case OPT_CERTFILE:
            certfile = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_NOCAFILE:
            noCAfile = 1;
            break;
        case OPT_NOCAPATH:
            noCApath = 1;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_CONTENT:
            contfile = opt_arg();
            break;
        case OPT_RR_FROM:
            if (rr_from == NULL
                && (rr_from = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            sk_OPENSSL_STRING_push(rr_from, opt_arg());
            break;
        case OPT_RR_TO:
            if (rr_to == NULL
                && (rr_to = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            sk_OPENSSL_STRING_push(rr_to, opt_arg());
            break;
        case OPT_PRINT:
            noout = print = 1;
            break;
        case OPT_SECRETKEY:
            secret_key = OPENSSL_hexstr2buf(opt_arg(), &ltmp);
            if (secret_key == NULL) {
                BIO_printf(bio_err, "Invalid key %s\n", opt_arg());
                goto end;
            }
            secret_keylen = (size_t)ltmp;
            break;
        case OPT_SECRETKEYID:
            secret_keyid = OPENSSL_hexstr2buf(opt_arg(), &ltmp);
            if (secret_keyid == NULL) {
                BIO_printf(bio_err, "Invalid id %s\n", opt_arg());
                goto opthelp;
            }
            secret_keyidlen = (size_t)ltmp;
            break;
        case OPT_PWRI_PASSWORD:
            pwri_pass = (unsigned char *)opt_arg();
            break;
        case OPT_ECONTENT_TYPE:
            econtent_type = OBJ_txt2obj(opt_arg(), 0);
            if (econtent_type == NULL) {
                BIO_printf(bio_err, "Invalid OID %s\n", opt_arg());
                goto opthelp;
            }
            break;
        case OPT_RAND:
            inrand = opt_arg();
            need_rand = 1;
            break;
        case OPT_ENGINE:
            e = setup_engine(opt_arg(), 0);
            break;
        case OPT_PASSIN:
            passinarg = opt_arg();
            break;
        case OPT_TO:
            to = opt_arg();
            break;
        case OPT_FROM:
            from = opt_arg();
            break;
        case OPT_SUBJECT:
            subject = opt_arg();
            break;
        case OPT_CERTSOUT:
            certsoutfile = opt_arg();
            break;
        case OPT_MD:
            if (!opt_md(opt_arg(), &sign_md))
                goto end;
            break;
        case OPT_SIGNER:
            /* If previous -signer argument add signer to list */
            if (signerfile) {
                if (sksigners == NULL
                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
                    goto end;
                sk_OPENSSL_STRING_push(sksigners, signerfile);
                if (keyfile == NULL)
                    keyfile = signerfile;
                if (skkeys == NULL
                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
                    goto end;
                sk_OPENSSL_STRING_push(skkeys, keyfile);
                keyfile = NULL;
            }
            signerfile = opt_arg();
            break;
        case OPT_INKEY:
            /* If previous -inkey argument add signer to list */
            if (keyfile) {
                if (signerfile == NULL) {
                    BIO_puts(bio_err, "Illegal -inkey without -signer\n");
                    goto end;
                }
                if (sksigners == NULL
                    && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
                    goto end;
                sk_OPENSSL_STRING_push(sksigners, signerfile);
                signerfile = NULL;
                if (skkeys == NULL
                    && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
                    goto end;
                sk_OPENSSL_STRING_push(skkeys, keyfile);
            }
            keyfile = opt_arg();
            break;
        case OPT_KEYFORM:
            if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform))
                goto opthelp;
            break;
        case OPT_RECIP:
            if (operation == SMIME_ENCRYPT) {
                if (encerts == NULL && (encerts = sk_X509_new_null()) == NULL)
                    goto end;
                cert = load_cert(opt_arg(), FORMAT_PEM,
                                 "recipient certificate file");
                if (cert == NULL)
                    goto end;
                sk_X509_push(encerts, cert);
                cert = NULL;
            } else
                recipfile = opt_arg();
            break;
        case OPT_CIPHER:
            if (!opt_cipher(opt_unknown(), &cipher))
                goto end;
            break;
        case OPT_KEYOPT:
            keyidx = -1;
            if (operation == SMIME_ENCRYPT) {
                if (encerts)
                    keyidx += sk_X509_num(encerts);
            } else {
                if (keyfile || signerfile)
                    keyidx++;
                if (skkeys)
                    keyidx += sk_OPENSSL_STRING_num(skkeys);
            }
            if (keyidx < 0) {
                BIO_printf(bio_err, "No key specified\n");
                goto opthelp;
            }
            if (key_param == NULL || key_param->idx != keyidx) {
                cms_key_param *nparam;
                nparam = app_malloc(sizeof(*nparam), "key param buffer");
                nparam->idx = keyidx;
                if ((nparam->param = sk_OPENSSL_STRING_new_null()) == NULL)
                    goto end;
                nparam->next = NULL;
                if (key_first == NULL)
                    key_first = nparam;
                else
                    key_param->next = nparam;
                key_param = nparam;
            }
            sk_OPENSSL_STRING_push(key_param->param, opt_arg());
            break;
        case OPT_V_CASES:
            if (!opt_verify(o, vpm))
                goto end;
            vpmtouched++;
            break;
        case OPT_3DES_WRAP:
# ifndef OPENSSL_NO_DES
            wrap_cipher = EVP_des_ede3_wrap();
# endif
            break;
        case OPT_AES128_WRAP:
            wrap_cipher = EVP_aes_128_wrap();
            break;
        case OPT_AES192_WRAP:
            wrap_cipher = EVP_aes_192_wrap();
            break;
        case OPT_AES256_WRAP:
            wrap_cipher = EVP_aes_256_wrap();
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (((rr_allorfirst != -1) || rr_from) && !rr_to) {
        BIO_puts(bio_err, "No Signed Receipts Recipients\n");
        goto opthelp;
    }

    if (!(operation & SMIME_SIGNERS) && (rr_to || rr_from)) {
        BIO_puts(bio_err, "Signed receipts only allowed with -sign\n");
        goto opthelp;
    }
    if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) {
        BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
        goto opthelp;
    }

    if (operation & SMIME_SIGNERS) {
        if (keyfile && !signerfile) {
            BIO_puts(bio_err, "Illegal -inkey without -signer\n");
            goto opthelp;
        }
        /* Check to see if any final signer needs to be appended */
        if (signerfile) {
            if (!sksigners
                && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            sk_OPENSSL_STRING_push(sksigners, signerfile);
            if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL)
                goto end;
            if (!keyfile)
                keyfile = signerfile;
            sk_OPENSSL_STRING_push(skkeys, keyfile);
        }
        if (!sksigners) {
            BIO_printf(bio_err, "No signer certificate specified\n");
            goto opthelp;
        }
        signerfile = NULL;
        keyfile = NULL;
        need_rand = 1;
    }

    else if (operation == SMIME_DECRYPT) {
        if (!recipfile && !keyfile && !secret_key && !pwri_pass) {
            BIO_printf(bio_err,
                       "No recipient certificate or key specified\n");
            goto opthelp;
        }
    } else if (operation == SMIME_ENCRYPT) {
        if (*argv == NULL && !secret_key && !pwri_pass && !encerts) {
            BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n");
            goto opthelp;
        }
        need_rand = 1;
    } else if (!operation)
        goto opthelp;

    if (!app_passwd(passinarg, NULL, &passin, NULL)) {
        BIO_printf(bio_err, "Error getting password\n");
        goto end;
    }

    if (need_rand) {
        app_RAND_load_file(NULL, (inrand != NULL));
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));
    }

    ret = 2;

    if (!(operation & SMIME_SIGNERS))
        flags &= ~CMS_DETACHED;

    if (!(operation & SMIME_OP)) {
        if (flags & CMS_BINARY)
            outformat = FORMAT_BINARY;
    }

    if (!(operation & SMIME_IP)) {
        if (flags & CMS_BINARY)
            informat = FORMAT_BINARY;
    }

    if (operation == SMIME_ENCRYPT) {
        if (!cipher) {
# ifndef OPENSSL_NO_DES
            cipher = EVP_des_ede3_cbc();
# else
            BIO_printf(bio_err, "No cipher selected\n");
            goto end;
# endif
        }

        if (secret_key && !secret_keyid) {
            BIO_printf(bio_err, "No secret key id\n");
            goto end;
        }

        if (*argv && !encerts)
            if ((encerts = sk_X509_new_null()) == NULL)
                goto end;
        while (*argv) {
            if ((cert = load_cert(*argv, FORMAT_PEM,
                                  "recipient certificate file")) == NULL)
                goto end;
            sk_X509_push(encerts, cert);
            cert = NULL;
            argv++;
        }
    }

    if (certfile) {
        if (!load_certs(certfile, &other, FORMAT_PEM, NULL,
                        "certificate file")) {
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (recipfile && (operation == SMIME_DECRYPT)) {
        if ((recip = load_cert(recipfile, FORMAT_PEM,
                               "recipient certificate file")) == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (operation == SMIME_SIGN_RECEIPT) {
        if ((signer = load_cert(signerfile, FORMAT_PEM,
                                "receipt signer certificate file")) == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }
    }

    if (operation == SMIME_DECRYPT) {
        if (!keyfile)
            keyfile = recipfile;
    } else if ((operation == SMIME_SIGN) || (operation == SMIME_SIGN_RECEIPT)) {
        if (!keyfile)
            keyfile = signerfile;
    } else
        keyfile = NULL;

    if (keyfile) {
        key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
        if (!key)
            goto end;
    }

    in = bio_open_default(infile, 'r', informat);
    if (in == NULL)
        goto end;

    if (operation & SMIME_IP) {
        if (informat == FORMAT_SMIME)
            cms = SMIME_read_CMS(in, &indata);
        else if (informat == FORMAT_PEM)
            cms = PEM_read_bio_CMS(in, NULL, NULL, NULL);
        else if (informat == FORMAT_ASN1)
            cms = d2i_CMS_bio(in, NULL);
        else {
            BIO_printf(bio_err, "Bad input format for CMS file\n");
            goto end;
        }

        if (!cms) {
            BIO_printf(bio_err, "Error reading S/MIME message\n");
            goto end;
        }
        if (contfile) {
            BIO_free(indata);
            if ((indata = BIO_new_file(contfile, "rb")) == NULL) {
                BIO_printf(bio_err, "Can't read content file %s\n", contfile);
                goto end;
            }
        }
        if (certsoutfile) {
            STACK_OF(X509) *allcerts;
            allcerts = CMS_get1_certs(cms);
            if (!save_certs(certsoutfile, allcerts)) {
                BIO_printf(bio_err,
                           "Error writing certs to %s\n", certsoutfile);
                ret = 5;
                goto end;
            }
            sk_X509_pop_free(allcerts, X509_free);
        }
    }

    if (rctfile) {
        char *rctmode = (rctformat == FORMAT_ASN1) ? "rb" : "r";
        if ((rctin = BIO_new_file(rctfile, rctmode)) == NULL) {
            BIO_printf(bio_err, "Can't open receipt file %s\n", rctfile);
            goto end;
        }

        if (rctformat == FORMAT_SMIME)
            rcms = SMIME_read_CMS(rctin, NULL);
        else if (rctformat == FORMAT_PEM)
            rcms = PEM_read_bio_CMS(rctin, NULL, NULL, NULL);
        else if (rctformat == FORMAT_ASN1)
            rcms = d2i_CMS_bio(rctin, NULL);
        else {
            BIO_printf(bio_err, "Bad input format for receipt\n");
            goto end;
        }

        if (!rcms) {
            BIO_printf(bio_err, "Error reading receipt\n");
            goto end;
        }
    }

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if ((operation == SMIME_VERIFY) || (operation == SMIME_VERIFY_RECEIPT)) {
        if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
            goto end;
        X509_STORE_set_verify_cb(store, cms_cb);
        if (vpmtouched)
            X509_STORE_set1_param(store, vpm);
    }

    ret = 3;

    if (operation == SMIME_DATA_CREATE) {
        cms = CMS_data_create(in, flags);
    } else if (operation == SMIME_DIGEST_CREATE) {
        cms = CMS_digest_create(in, sign_md, flags);
    } else if (operation == SMIME_COMPRESS) {
        cms = CMS_compress(in, -1, flags);
    } else if (operation == SMIME_ENCRYPT) {
        int i;
        flags |= CMS_PARTIAL;
        cms = CMS_encrypt(NULL, in, cipher, flags);
        if (!cms)
            goto end;
        for (i = 0; i < sk_X509_num(encerts); i++) {
            CMS_RecipientInfo *ri;
            cms_key_param *kparam;
            int tflags = flags;
            X509 *x = sk_X509_value(encerts, i);
            for (kparam = key_first; kparam; kparam = kparam->next) {
                if (kparam->idx == i) {
                    tflags |= CMS_KEY_PARAM;
                    break;
                }
            }
            ri = CMS_add1_recipient_cert(cms, x, tflags);
            if (!ri)
                goto end;
            if (kparam) {
                EVP_PKEY_CTX *pctx;
                pctx = CMS_RecipientInfo_get0_pkey_ctx(ri);
                if (!cms_set_pkey_param(pctx, kparam->param))
                    goto end;
            }
            if (CMS_RecipientInfo_type(ri) == CMS_RECIPINFO_AGREE
                && wrap_cipher) {
                EVP_CIPHER_CTX *wctx;
                wctx = CMS_RecipientInfo_kari_get0_ctx(ri);
                EVP_EncryptInit_ex(wctx, wrap_cipher, NULL, NULL, NULL);
            }
        }

        if (secret_key) {
            if (!CMS_add0_recipient_key(cms, NID_undef,
                                        secret_key, secret_keylen,
                                        secret_keyid, secret_keyidlen,
                                        NULL, NULL, NULL))
                goto end;
            /* NULL these because call absorbs them */
            secret_key = NULL;
            secret_keyid = NULL;
        }
        if (pwri_pass) {
            pwri_tmp = (unsigned char *)OPENSSL_strdup((char *)pwri_pass);
            if (!pwri_tmp)
                goto end;
            if (!CMS_add0_recipient_password(cms,
                                             -1, NID_undef, NID_undef,
                                             pwri_tmp, -1, NULL))
                goto end;
            pwri_tmp = NULL;
        }
        if (!(flags & CMS_STREAM)) {
            if (!CMS_final(cms, in, NULL, flags))
                goto end;
        }
    } else if (operation == SMIME_ENCRYPTED_ENCRYPT) {
        cms = CMS_EncryptedData_encrypt(in, cipher,
                                        secret_key, secret_keylen, flags);

    } else if (operation == SMIME_SIGN_RECEIPT) {
        CMS_ContentInfo *srcms = NULL;
        STACK_OF(CMS_SignerInfo) *sis;
        CMS_SignerInfo *si;
        sis = CMS_get0_SignerInfos(cms);
        if (!sis)
            goto end;
        si = sk_CMS_SignerInfo_value(sis, 0);
        srcms = CMS_sign_receipt(si, signer, key, other, flags);
        if (!srcms)
            goto end;
        CMS_ContentInfo_free(cms);
        cms = srcms;
    } else if (operation & SMIME_SIGNERS) {
        int i;
        /*
         * If detached data content we enable streaming if S/MIME output
         * format.
         */
        if (operation == SMIME_SIGN) {

            if (flags & CMS_DETACHED) {
                if (outformat == FORMAT_SMIME)
                    flags |= CMS_STREAM;
            }
            flags |= CMS_PARTIAL;
            cms = CMS_sign(NULL, NULL, other, in, flags);
            if (!cms)
                goto end;
            if (econtent_type)
                CMS_set1_eContentType(cms, econtent_type);

            if (rr_to) {
                rr = make_receipt_request(rr_to, rr_allorfirst, rr_from);
                if (!rr) {
                    BIO_puts(bio_err,
                             "Signed Receipt Request Creation Error\n");
                    goto end;
                }
            }
        } else
            flags |= CMS_REUSE_DIGEST;
        for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) {
            CMS_SignerInfo *si;
            cms_key_param *kparam;
            int tflags = flags;
            signerfile = sk_OPENSSL_STRING_value(sksigners, i);
            keyfile = sk_OPENSSL_STRING_value(skkeys, i);

            signer = load_cert(signerfile, FORMAT_PEM, "signer certificate");
            if (!signer)
                goto end;
            key = load_key(keyfile, keyform, 0, passin, e, "signing key file");
            if (!key)
                goto end;
            for (kparam = key_first; kparam; kparam = kparam->next) {
                if (kparam->idx == i) {
                    tflags |= CMS_KEY_PARAM;
                    break;
                }
            }
            si = CMS_add1_signer(cms, signer, key, sign_md, tflags);
            if (!si)
                goto end;
            if (kparam) {
                EVP_PKEY_CTX *pctx;
                pctx = CMS_SignerInfo_get0_pkey_ctx(si);
                if (!cms_set_pkey_param(pctx, kparam->param))
                    goto end;
            }
            if (rr && !CMS_add1_ReceiptRequest(si, rr))
                goto end;
            X509_free(signer);
            signer = NULL;
            EVP_PKEY_free(key);
            key = NULL;
        }
        /* If not streaming or resigning finalize structure */
        if ((operation == SMIME_SIGN) && !(flags & CMS_STREAM)) {
            if (!CMS_final(cms, in, NULL, flags))
                goto end;
        }
    }

    if (!cms) {
        BIO_printf(bio_err, "Error creating CMS structure\n");
        goto end;
    }

    ret = 4;
    if (operation == SMIME_DECRYPT) {
        if (flags & CMS_DEBUG_DECRYPT)
            CMS_decrypt(cms, NULL, NULL, NULL, NULL, flags);

        if (secret_key) {
            if (!CMS_decrypt_set1_key(cms,
                                      secret_key, secret_keylen,
                                      secret_keyid, secret_keyidlen)) {
                BIO_puts(bio_err, "Error decrypting CMS using secret key\n");
                goto end;
            }
        }

        if (key) {
            if (!CMS_decrypt_set1_pkey(cms, key, recip)) {
                BIO_puts(bio_err, "Error decrypting CMS using private key\n");
                goto end;
            }
        }

        if (pwri_pass) {
            if (!CMS_decrypt_set1_password(cms, pwri_pass, -1)) {
                BIO_puts(bio_err, "Error decrypting CMS using password\n");
                goto end;
            }
        }

        if (!CMS_decrypt(cms, NULL, NULL, indata, out, flags)) {
            BIO_printf(bio_err, "Error decrypting CMS structure\n");
            goto end;
        }
    } else if (operation == SMIME_DATAOUT) {
        if (!CMS_data(cms, out, flags))
            goto end;
    } else if (operation == SMIME_UNCOMPRESS) {
        if (!CMS_uncompress(cms, indata, out, flags))
            goto end;
    } else if (operation == SMIME_DIGEST_VERIFY) {
        if (CMS_digest_verify(cms, indata, out, flags) > 0)
            BIO_printf(bio_err, "Verification successful\n");
        else {
            BIO_printf(bio_err, "Verification failure\n");
            goto end;
        }
    } else if (operation == SMIME_ENCRYPTED_DECRYPT) {
        if (!CMS_EncryptedData_decrypt(cms, secret_key, secret_keylen,
                                       indata, out, flags))
            goto end;
    } else if (operation == SMIME_VERIFY) {
        if (CMS_verify(cms, other, store, indata, out, flags) > 0)
            BIO_printf(bio_err, "Verification successful\n");
        else {
            BIO_printf(bio_err, "Verification failure\n");
            if (verify_retcode)
                ret = verify_err + 32;
            goto end;
        }
        if (signerfile) {
            STACK_OF(X509) *signers;
            signers = CMS_get0_signers(cms);
            if (!save_certs(signerfile, signers)) {
                BIO_printf(bio_err,
                           "Error writing signers to %s\n", signerfile);
                ret = 5;
                goto end;
            }
            sk_X509_free(signers);
        }
        if (rr_print)
            receipt_request_print(cms);

    } else if (operation == SMIME_VERIFY_RECEIPT) {
        if (CMS_verify_receipt(rcms, cms, other, store, flags) > 0)
            BIO_printf(bio_err, "Verification successful\n");
        else {
            BIO_printf(bio_err, "Verification failure\n");
            goto end;
        }
    } else {
        if (noout) {
            if (print)
                CMS_ContentInfo_print_ctx(out, cms, 0, NULL);
        } else if (outformat == FORMAT_SMIME) {
            if (to)
                BIO_printf(out, "To: %s%s", to, mime_eol);
            if (from)
                BIO_printf(out, "From: %s%s", from, mime_eol);
            if (subject)
                BIO_printf(out, "Subject: %s%s", subject, mime_eol);
            if (operation == SMIME_RESIGN)
                ret = SMIME_write_CMS(out, cms, indata, flags);
            else
                ret = SMIME_write_CMS(out, cms, in, flags);
        } else if (outformat == FORMAT_PEM)
            ret = PEM_write_bio_CMS_stream(out, cms, in, flags);
        else if (outformat == FORMAT_ASN1)
            ret = i2d_CMS_bio_stream(out, cms, in, flags);
        else {
            BIO_printf(bio_err, "Bad output format for CMS file\n");
            goto end;
        }
        if (ret <= 0) {
            ret = 6;
            goto end;
        }
    }
    ret = 0;
 end:
    if (ret)
        ERR_print_errors(bio_err);
    if (need_rand)
        app_RAND_write_file(NULL);
    sk_X509_pop_free(encerts, X509_free);
    sk_X509_pop_free(other, X509_free);
    X509_VERIFY_PARAM_free(vpm);
    sk_OPENSSL_STRING_free(sksigners);
    sk_OPENSSL_STRING_free(skkeys);
    OPENSSL_free(secret_key);
    OPENSSL_free(secret_keyid);
    OPENSSL_free(pwri_tmp);
    ASN1_OBJECT_free(econtent_type);
    CMS_ReceiptRequest_free(rr);
    sk_OPENSSL_STRING_free(rr_to);
    sk_OPENSSL_STRING_free(rr_from);
    for (key_param = key_first; key_param;) {
        cms_key_param *tparam;
        sk_OPENSSL_STRING_free(key_param->param);
        tparam = key_param->next;
        OPENSSL_free(key_param);
        key_param = tparam;
    }
    X509_STORE_free(store);
    X509_free(cert);
    X509_free(recip);
    X509_free(signer);
    EVP_PKEY_free(key);
    CMS_ContentInfo_free(cms);
    CMS_ContentInfo_free(rcms);
    BIO_free(rctin);
    BIO_free(in);
    BIO_free(indata);
    BIO_free_all(out);
    OPENSSL_free(passin);
    return (ret);
}
示例#14
0
文件: ecdsatest.c 项目: tiran/openssl
/*-
 * This function hijacks the RNG to feed it the chosen ECDSA key and nonce.
 * The ECDSA KATs are from:
 * - the X9.62 draft (4)
 * - NIST CAVP (720)
 *
 * It uses the low-level ECDSA_sign_setup instead of EVP to control the RNG.
 * NB: This is not how applications should use ECDSA; this is only for testing.
 *
 * Tests the library can successfully:
 * - generate public keys that matches those KATs
 * - create ECDSA signatures that match those KATs
 * - accept those signatures as valid
 */
static int x9_62_tests(int n)
{
    int nid, md_nid, ret = 0;
    const char *r_in = NULL, *s_in = NULL, *tbs = NULL;
    unsigned char *pbuf = NULL, *qbuf = NULL, *message = NULL;
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int dgst_len = 0;
    long q_len, msg_len = 0;
    size_t p_len;
    EVP_MD_CTX *mctx = NULL;
    EC_KEY *key = NULL;
    ECDSA_SIG *signature = NULL;
    BIGNUM *r = NULL, *s = NULL;
    BIGNUM *kinv = NULL, *rp = NULL;
    const BIGNUM *sig_r = NULL, *sig_s = NULL;

    nid = ecdsa_cavs_kats[n].nid;
    md_nid = ecdsa_cavs_kats[n].md_nid;
    r_in = ecdsa_cavs_kats[n].r;
    s_in = ecdsa_cavs_kats[n].s;
    tbs = ecdsa_cavs_kats[n].msg;
    numbers[0] = ecdsa_cavs_kats[n].d;
    numbers[1] = ecdsa_cavs_kats[n].k;

    TEST_info("ECDSA KATs for curve %s", OBJ_nid2sn(nid));

    if (!TEST_ptr(mctx = EVP_MD_CTX_new())
        /* get the message digest */
        || !TEST_ptr(message = OPENSSL_hexstr2buf(tbs, &msg_len))
        || !TEST_true(EVP_DigestInit_ex(mctx, EVP_get_digestbynid(md_nid), NULL))
        || !TEST_true(EVP_DigestUpdate(mctx, message, msg_len))
        || !TEST_true(EVP_DigestFinal_ex(mctx, digest, &dgst_len))
        /* create the key */
        || !TEST_ptr(key = EC_KEY_new_by_curve_name(nid))
        /* load KAT variables */
        || !TEST_ptr(r = BN_new())
        || !TEST_ptr(s = BN_new())
        || !TEST_true(BN_hex2bn(&r, r_in))
        || !TEST_true(BN_hex2bn(&s, s_in))
        /* swap the RNG source */
        || !TEST_true(change_rand()))
        goto err;

    /* public key must match KAT */
    use_fake = 1;
    if (!TEST_true(EC_KEY_generate_key(key))
        || !TEST_true(p_len = EC_KEY_key2buf(key, POINT_CONVERSION_UNCOMPRESSED,
                                             &pbuf, NULL))
        || !TEST_ptr(qbuf = OPENSSL_hexstr2buf(ecdsa_cavs_kats[n].Q, &q_len))
        || !TEST_int_eq(q_len, p_len)
        || !TEST_mem_eq(qbuf, q_len, pbuf, p_len))
        goto err;

    /* create the signature via ECDSA_sign_setup to avoid use of ECDSA nonces */
    use_fake = 1;
    if (!TEST_true(ECDSA_sign_setup(key, NULL, &kinv, &rp))
        || !TEST_ptr(signature = ECDSA_do_sign_ex(digest, dgst_len,
                                                  kinv, rp, key))
        /* verify the signature */
        || !TEST_int_eq(ECDSA_do_verify(digest, dgst_len, signature, key), 1))
        goto err;

    /* compare the created signature with the expected signature */
    ECDSA_SIG_get0(signature, &sig_r, &sig_s);
    if (!TEST_BN_eq(sig_r, r)
        || !TEST_BN_eq(sig_s, s))
        goto err;

    ret = 1;

 err:
    /* restore the RNG source */
    if (!TEST_true(restore_rand()))
        ret = 0;

    OPENSSL_free(message);
    OPENSSL_free(pbuf);
    OPENSSL_free(qbuf);
    EC_KEY_free(key);
    ECDSA_SIG_free(signature);
    BN_free(r);
    BN_free(s);
    EVP_MD_CTX_free(mctx);
    BN_clear_free(kinv);
    BN_clear_free(rp);
    return ret;
}