static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; if (rctx->md) { if (tbslen != (size_t)EVP_MD_size(rctx->md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } if (EVP_MD_type(rctx->md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_X931_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; memcpy(rctx->tbuf, tbs, tbslen); rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md, rctx->mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); } else return -1; } else ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, rctx->pad_mode); if (ret < 0) return ret; *siglen = ret; return 1; }
BOOL PriSign(RSAKEY PrivateKey, const UCHAR *msg, UINT32 msglen, UCHAR *sigret, UINT32 *siglen, INT32 type) { assert(PrivateKey != NULL); RSA* pPriKey = (RSA*)PrivateKey; //RSA_sign 这里如果使用此函数,可输入msglen不可超过36 INT32 nRet = RSA_sign_ASN1_OCTET_STRING(type, msg, msglen, sigret, siglen, pPriKey); if(nRet != 1) { return FALSE; } return TRUE; }
static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, const unsigned char *tbs, size_t tbslen) { int ret; RSA_PKEY_CTX *rctx = ctx->data; RSA *rsa = ctx->pkey->pkey.rsa; #ifdef OPENSSL_FIPS ret = pkey_fips_check_ctx(ctx); if (ret < 0) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); return -1; } #endif if (rctx->md) { if (tbslen != (size_t)EVP_MD_size(rctx->md)) { RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); return -1; } #ifdef OPENSSL_FIPS if (ret > 0) { unsigned int slen; ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, rctx->pad_mode, rctx->saltlen, rctx->mgf1md, sig, &slen); if (ret > 0) *siglen = slen; else *siglen = 0; return ret; } #endif if (EVP_MD_type(rctx->md) == NID_mdc2) { unsigned int sltmp; if (rctx->pad_mode != RSA_PKCS1_PADDING) return -1; ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_X931_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; memcpy(rctx->tbuf, tbs, tbslen); rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, sig, rsa, RSA_X931_PADDING); } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { unsigned int sltmp; ret = RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &sltmp, rsa); if (ret <= 0) return ret; ret = sltmp; } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { if (!setup_tbuf(rctx, ctx)) return -1; if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, rctx->tbuf, tbs, rctx->md, rctx->mgf1md, rctx->saltlen)) return -1; ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, sig, rsa, RSA_NO_PADDING); } else return -1; } else ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, rctx->pad_mode); if (ret < 0) return ret; *siglen = ret; return 1; }
/* * Sign an assertion. */ static char * keynote_sign_assertion(struct assertion *as, char *sigalg, void *key, int keyalg, int verifyflag) { int slen, i, hashlen = 0, hashtype, alg, encoding, internalenc; unsigned char *sig = NULL, *finalbuf = NULL; unsigned char res2[LARGEST_HASH_SIZE], *sbuf = NULL; BIO *biokey = NULL; DSA *dsa = NULL; RSA *rsa = NULL; SHA_CTX shscontext; MD5_CTX md5context; int len; if (as->as_signature_string_s == NULL || as->as_startofsignature == NULL || as->as_allbutsignature == NULL || as->as_allbutsignature - as->as_startofsignature <= 0 || as->as_authorizer == NULL || key == NULL || as->as_signeralgorithm == KEYNOTE_ALGORITHM_NONE) { keynote_errno = ERROR_SYNTAX; return NULL; } alg = keynote_get_sig_algorithm(sigalg, &hashtype, &encoding, &internalenc); if (((alg != as->as_signeralgorithm) && !((alg == KEYNOTE_ALGORITHM_RSA) && (as->as_signeralgorithm == KEYNOTE_ALGORITHM_X509)) && !((alg == KEYNOTE_ALGORITHM_X509) && (as->as_signeralgorithm == KEYNOTE_ALGORITHM_RSA))) || ((alg != keyalg) && !((alg == KEYNOTE_ALGORITHM_RSA) && (keyalg == KEYNOTE_ALGORITHM_X509)) && !((alg == KEYNOTE_ALGORITHM_X509) && (keyalg == KEYNOTE_ALGORITHM_RSA)))) { keynote_errno = ERROR_SYNTAX; return NULL; } sig = strchr(sigalg, ':'); if (sig == NULL) { keynote_errno = ERROR_SYNTAX; return NULL; } sig++; switch (hashtype) { case KEYNOTE_HASH_SHA1: hashlen = 20; memset(res2, 0, hashlen); SHA1_Init(&shscontext); SHA1_Update(&shscontext, as->as_startofsignature, as->as_allbutsignature - as->as_startofsignature); SHA1_Update(&shscontext, sigalg, (char *) sig - sigalg); SHA1_Final(res2, &shscontext); break; case KEYNOTE_HASH_MD5: hashlen = 16; memset(res2, 0, hashlen); MD5_Init(&md5context); MD5_Update(&md5context, as->as_startofsignature, as->as_allbutsignature - as->as_startofsignature); MD5_Update(&md5context, sigalg, (char *) sig - sigalg); MD5_Final(res2, &md5context); break; case KEYNOTE_HASH_NONE: break; } if ((alg == KEYNOTE_ALGORITHM_DSA) && (hashtype == KEYNOTE_HASH_SHA1) && (internalenc == INTERNAL_ENC_ASN1) && ((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) { dsa = (DSA *) key; sbuf = calloc(DSA_size(dsa), sizeof(unsigned char)); if (sbuf == NULL) { keynote_errno = ERROR_MEMORY; return NULL; } if (DSA_sign(0, res2, hashlen, sbuf, &slen, dsa) <= 0) { free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } } else if ((alg == KEYNOTE_ALGORITHM_RSA) && ((hashtype == KEYNOTE_HASH_SHA1) || (hashtype == KEYNOTE_HASH_MD5)) && (internalenc == INTERNAL_ENC_PKCS1) && ((encoding == ENCODING_HEX) || (encoding == ENCODING_BASE64))) { rsa = (RSA *) key; sbuf = calloc(RSA_size(rsa), sizeof(unsigned char)); if (sbuf == NULL) { keynote_errno = ERROR_MEMORY; return NULL; } if (RSA_sign_ASN1_OCTET_STRING(RSA_PKCS1_PADDING, res2, hashlen, sbuf, &slen, rsa) <= 0) { free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } } else if ((alg == KEYNOTE_ALGORITHM_X509) && (hashtype == KEYNOTE_HASH_SHA1) && (internalenc == INTERNAL_ENC_ASN1)) { if ((biokey = BIO_new(BIO_s_mem())) == NULL) { keynote_errno = ERROR_SYNTAX; return NULL; } if (BIO_write(biokey, key, strlen(key) + 1) <= 0) { BIO_free(biokey); keynote_errno = ERROR_SYNTAX; return NULL; } /* RSA-specific */ rsa = (RSA *) PEM_read_bio_RSAPrivateKey(biokey, NULL, NULL, NULL); if (rsa == NULL) { BIO_free(biokey); keynote_errno = ERROR_SYNTAX; return NULL; } sbuf = calloc(RSA_size(rsa), sizeof(char)); if (sbuf == NULL) { BIO_free(biokey); RSA_free(rsa); keynote_errno = ERROR_MEMORY; return NULL; } if (RSA_sign(NID_shaWithRSAEncryption, res2, hashlen, sbuf, &slen, rsa) <= 0) { BIO_free(biokey); RSA_free(rsa); free(sbuf); keynote_errno = ERROR_SIGN_FAILURE; return NULL; } BIO_free(biokey); RSA_free(rsa); } else /* Other algorithms here */ { keynote_errno = ERROR_SYNTAX; return NULL; } /* ASCII encoding */ switch (encoding) { case ENCODING_HEX: i = kn_encode_hex(sbuf, (char **) &finalbuf, slen); free(sbuf); if (i != 0) return NULL; break; case ENCODING_BASE64: finalbuf = calloc(2 * slen, sizeof(unsigned char)); if (finalbuf == NULL) { keynote_errno = ERROR_MEMORY; free(sbuf); return NULL; } if ((slen = kn_encode_base64(sbuf, slen, finalbuf, 2 * slen)) == -1) { free(sbuf); return NULL; } break; default: free(sbuf); keynote_errno = ERROR_SYNTAX; return NULL; } /* Replace as->as_signature */ len = strlen(sigalg) + strlen(finalbuf) + 1; as->as_signature = calloc(len, sizeof(char)); if (as->as_signature == NULL) { free(finalbuf); keynote_errno = ERROR_MEMORY; return NULL; } /* Concatenate algorithm name and signature value */ snprintf(as->as_signature, len, "%s%s", sigalg, finalbuf); free(finalbuf); finalbuf = as->as_signature; /* Verify the newly-created signature if requested */ if (verifyflag) { /* Do the signature verification */ if (keynote_sigverify_assertion(as) != SIGRESULT_TRUE) { as->as_signature = NULL; free(finalbuf); if (keynote_errno == 0) keynote_errno = ERROR_SYNTAX; return NULL; } as->as_signature = NULL; } else as->as_signature = NULL; /* Everything ok */ return (char *) finalbuf; }