{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1756843895,
"reponame":"openssl",
"desc":"OpenSSL",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://warmcat.com/repo/openssl",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"be78cd4980459a61433c2f5bf286ca0a",
"commit": {"type":"commit",
"time": 1478549094,
"time_ofs": 60,
"oid_tree": { "oid": "d519d9b8d3b385df8551e560abf46568c1016a8f", "alias": []},
"oid":{ "oid": "608a026494c1e7a14f6d6cfcc5e4994fe2728836", "alias": []},
"msg": "Implement RSASSA-PKCS1-v1_5 as specified.",
"sig_commit": { "git_time": { "time": 1478549094, "offset": 60 }, "name": "Kurt Roeckx", "email": "kurt@roeckx.be", "md5": "07d47d7a232d566ec15a49b65d5dd9c1" },
"sig_author": { "git_time": { "time": 1471714517, "offset": -240 }, "name": "David Benjamin", "email": "davidben@google.com", "md5": "97b59b4df088a52a925e8639cefc6fcc" }},
"body": "Implement RSASSA-PKCS1-v1_5 as specified.\n\nRFC 3447, section 8.2.2, steps 3 and 4 states that verifiers must encode\nthe DigestInfo struct and then compare the result against the public key\noperation result. This implies that one and only one encoding is legal.\n\nOpenSSL instead parses with crypto/asn1, then checks that the encoding\nround-trips, and allows some variations for the parameter. Sufficient\nlaxness in this area can allow signature forgeries, as described in\nhttps://www.imperialviolet.org/2014/09/26/pkcs1.html\n\nAlthough there aren't known attacks against OpenSSL's current scheme,\nthis change makes OpenSSL implement the algorithm as specified. This\navoids the uncertainty and, more importantly, helps grow a healthy\necosystem. Laxness beyond the spec, particularly in implementations\nwhich enjoy wide use, risks harm to the ecosystem for all. A signature\nproducer which only tests against OpenSSL may not notice bugs and\naccidentally become widely deployed. Thus implementations have a\nresponsibility to honor the specification as tightly as is practical.\n\nIn some cases, the damage is permanent and the spec deviation and\nsecurity risk becomes a tax all implementors must forever pay, but not\nhere. Both BoringSSL and Go successfully implemented and deployed\nRSASSA-PKCS1-v1_5 as specified since their respective beginnings, so\nthis change should be compatible enough to pin down in future OpenSSL\nreleases.\n\nSee also https://tools.ietf.org/html/draft-thomson-postel-was-wrong-00\n\nAs a bonus, by not having to deal with sign/verify differences, this\nversion is also somewhat clearer. It also more consistently enforces\ndigest lengths in the verify_recover codepath. The NID_md5_sha1 codepath\nwasn't quite doing this right.\n\nReviewed-by: Kurt Roeckx \u003ckurt@roeckx.be\u003e\nReviewed-by: Rich Salz \u003crsalz@openssl.org\u003e\n\nGH: #1474\n"
,
"diff": "diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c\nindex 210709e..45e12e0 100644\n--- a/crypto/rsa/rsa_err.c\n+++ b/crypto/rsa/rsa_err.c\n@@ -20,6 +20,7 @@\n \n static ERR_STRING_DATA RSA_str_functs[] \u003d {\n {ERR_FUNC(RSA_F_CHECK_PADDING_MD), \u0022check_padding_md\u0022},\n+ {ERR_FUNC(RSA_F_ENCODE_PKCS1), \u0022encode_pkcs1\u0022},\n {ERR_FUNC(RSA_F_INT_RSA_VERIFY), \u0022int_rsa_verify\u0022},\n {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), \u0022old_rsa_priv_decode\u0022},\n {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), \u0022pkey_rsa_ctrl\u0022},\ndiff --git a/crypto/rsa/rsa_sign.c b/crypto/rsa/rsa_sign.c\nindex 8946e19..952d24f 100644\n--- a/crypto/rsa/rsa_sign.c\n+++ b/crypto/rsa/rsa_sign.c\n@@ -19,208 +19,230 @@\n /* Size of an SSL signature: MD5+SHA1 */\n #define SSL_SIG_LENGTH 36\n \n-int RSA_sign(int type, const unsigned char *m, unsigned int m_len,\n- unsigned char *sigret, unsigned int *siglen, RSA *rsa)\n+/*\n+ * encode_pkcs1 encodes a DigestInfo prefix of hash |type| and digest |m|, as\n+ * described in EMSA-PKCS1-v1_5-ENCODE, RFC 3447 section 9.2 step 2. This\n+ * encodes the DigestInfo (T and tLen) but does not add the padding.\n+ *\n+ * On success, it returns one and sets |*out| to a newly allocated buffer\n+ * containing the result and |*out_len| to its length. The caller must free\n+ * |*out| with |OPENSSL_free|. Otherwise, it returns zero.\n+ */\n+static int encode_pkcs1(unsigned char **out, int *out_len, int type,\n+ const unsigned char *m, unsigned int m_len)\n {\n X509_SIG sig;\n- ASN1_TYPE parameter;\n- int i, j, ret \u003d 1;\n- unsigned char *p, *tmps \u003d NULL;\n- const unsigned char *s \u003d NULL;\n X509_ALGOR algor;\n+ ASN1_TYPE parameter;\n ASN1_OCTET_STRING digest;\n+ uint8_t *der \u003d NULL;\n+ int len;\n+\n+ sig.algor \u003d \u0026algor;\n+ sig.algor-\u003ealgorithm \u003d OBJ_nid2obj(type);\n+ if (sig.algor-\u003ealgorithm \u003d\u003d NULL) {\n+ RSAerr(RSA_F_ENCODE_PKCS1, RSA_R_UNKNOWN_ALGORITHM_TYPE);\n+ return 0;\n+ }\n+ if (OBJ_length(sig.algor-\u003ealgorithm) \u003d\u003d 0) {\n+ RSAerr(RSA_F_ENCODE_PKCS1,\n+ RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);\n+ return 0;\n+ }\n+ parameter.type \u003d V_ASN1_NULL;\n+ parameter.value.ptr \u003d NULL;\n+ sig.algor-\u003eparameter \u003d \u0026parameter;\n+\n+ sig.digest \u003d \u0026digest;\n+ sig.digest-\u003edata \u003d (unsigned char *)m;\n+ sig.digest-\u003elength \u003d m_len;\n+\n+ len \u003d i2d_X509_SIG(\u0026sig, \u0026der);\n+ if (len \u003c 0)\n+ return 0;\n+\n+ *out \u003d der;\n+ *out_len \u003d len;\n+ return 1;\n+}\n+\n+int RSA_sign(int type, const unsigned char *m, unsigned int m_len,\n+ unsigned char *sigret, unsigned int *siglen, RSA *rsa)\n+{\n+ int encrypt_len, encoded_len \u003d 0, ret \u003d 0;\n+ unsigned char *tmps \u003d NULL;\n+ const unsigned char *encoded \u003d NULL;\n+\n if (rsa-\u003emeth-\u003ersa_sign) {\n return rsa-\u003emeth-\u003ersa_sign(type, m, m_len, sigret, siglen, rsa);\n }\n- /* Special case: SSL signature, just check the length */\n+\n+ /* Compute the encoded digest. */\n if (type \u003d\u003d NID_md5_sha1) {\n+ /*\n+ * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and\n+ * earlier. It has no DigestInfo wrapper but otherwise is\n+ * RSASSA-PKCS1-v1_5.\n+ */\n if (m_len !\u003d SSL_SIG_LENGTH) {\n RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH);\n- return (0);\n+ return 0;\n }\n- i \u003d SSL_SIG_LENGTH;\n- s \u003d m;\n+ encoded_len \u003d SSL_SIG_LENGTH;\n+ encoded \u003d m;\n } else {\n- sig.algor \u003d \u0026algor;\n- sig.algor-\u003ealgorithm \u003d OBJ_nid2obj(type);\n- if (sig.algor-\u003ealgorithm \u003d\u003d NULL) {\n- RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE);\n- return (0);\n- }\n- if (OBJ_length(sig.algor-\u003ealgorithm) \u003d\u003d 0) {\n- RSAerr(RSA_F_RSA_SIGN,\n- RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);\n- return (0);\n- }\n- parameter.type \u003d V_ASN1_NULL;\n- parameter.value.ptr \u003d NULL;\n- sig.algor-\u003eparameter \u003d \u0026parameter;\n-\n- sig.digest \u003d \u0026digest;\n- sig.digest-\u003edata \u003d (unsigned char *)m; /* TMP UGLY CAST */\n- sig.digest-\u003elength \u003d m_len;\n-\n- i \u003d i2d_X509_SIG(\u0026sig, NULL);\n+ if (!encode_pkcs1(\u0026tmps, \u0026encoded_len, type, m, m_len))\n+ goto err;\n+ encoded \u003d tmps;\n }\n- j \u003d RSA_size(rsa);\n- if (i \u003e (j - RSA_PKCS1_PADDING_SIZE)) {\n+\n+ if (encoded_len \u003e RSA_size(rsa) - RSA_PKCS1_PADDING_SIZE) {\n RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);\n- return (0);\n- }\n- if (type !\u003d NID_md5_sha1) {\n- tmps \u003d OPENSSL_malloc((unsigned int)j + 1);\n- if (tmps \u003d\u003d NULL) {\n- RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE);\n- return (0);\n- }\n- p \u003d tmps;\n- i2d_X509_SIG(\u0026sig, \u0026p);\n- s \u003d tmps;\n+ goto err;\n }\n- i \u003d RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING);\n- if (i \u003c\u003d 0)\n- ret \u003d 0;\n- else\n- *siglen \u003d i;\n-\n- if (type !\u003d NID_md5_sha1)\n- OPENSSL_clear_free(tmps, (unsigned int)j + 1);\n- return (ret);\n-}\n+ encrypt_len \u003d RSA_private_encrypt(encoded_len, encoded, sigret, rsa,\n+ RSA_PKCS1_PADDING);\n+ if (encrypt_len \u003c\u003d 0)\n+ goto err;\n \n-/*\n- * Check DigestInfo structure does not contain extraneous data by reencoding\n- * using DER and checking encoding against original.\n- */\n-static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo,\n- int dinfolen)\n-{\n- unsigned char *der \u003d NULL;\n- int derlen;\n- int ret \u003d 0;\n- derlen \u003d i2d_X509_SIG(sig, \u0026der);\n- if (derlen \u003c\u003d 0)\n- return 0;\n- if (derlen \u003d\u003d dinfolen \u0026\u0026 !memcmp(dinfo, der, derlen))\n- ret \u003d 1;\n- OPENSSL_clear_free(der, derlen);\n+ *siglen \u003d encrypt_len;\n+ ret \u003d 1;\n+\n+err:\n+ OPENSSL_clear_free(tmps, (size_t)encoded_len);\n return ret;\n }\n \n-int int_rsa_verify(int dtype, const unsigned char *m,\n- unsigned int m_len,\n+/*\n+ * int_rsa_verify verifies an RSA signature in |sigbuf| using |rsa|. It may be\n+ * called in two modes. If |rm| is NULL, it verifies the signature for digest\n+ * |m|. Otherwise, it recovers the digest from the signature, writing the digest\n+ * to |rm| and the length to |*prm_len|. |type| is the NID of the digest\n+ * algorithm to use. It returns one on successful verification and zero\n+ * otherwise.\n+ */\n+int int_rsa_verify(int type, const unsigned char *m, unsigned int m_len,\n unsigned char *rm, size_t *prm_len,\n const unsigned char *sigbuf, size_t siglen, RSA *rsa)\n {\n- int i, ret \u003d 0, sigtype;\n- unsigned char *s;\n- X509_SIG *sig \u003d NULL;\n+ int decrypt_len, ret \u003d 0, encoded_len \u003d 0;\n+ unsigned char *decrypt_buf \u003d NULL, *encoded \u003d NULL;\n \n- if (siglen !\u003d (unsigned int)RSA_size(rsa)) {\n+ if (siglen !\u003d (size_t)RSA_size(rsa)) {\n RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH);\n- return (0);\n- }\n-\n- if ((dtype \u003d\u003d NID_md5_sha1) \u0026\u0026 rm) {\n- i \u003d RSA_public_decrypt((int)siglen,\n- sigbuf, rm, rsa, RSA_PKCS1_PADDING);\n- if (i \u003c\u003d 0)\n- return 0;\n- *prm_len \u003d i;\n- return 1;\n+ return 0;\n }\n \n- s \u003d OPENSSL_malloc((unsigned int)siglen);\n- if (s \u003d\u003d NULL) {\n+ /* Recover the encoded digest. */\n+ decrypt_buf \u003d OPENSSL_malloc(siglen);\n+ if (decrypt_buf \u003d\u003d NULL) {\n RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE);\n goto err;\n }\n- if ((dtype \u003d\u003d NID_md5_sha1) \u0026\u0026 (m_len !\u003d SSL_SIG_LENGTH)) {\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);\n- goto err;\n- }\n- i \u003d RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING);\n \n- if (i \u003c\u003d 0)\n+ decrypt_len \u003d RSA_public_decrypt((int)siglen, sigbuf, decrypt_buf, rsa,\n+ RSA_PKCS1_PADDING);\n+ if (decrypt_len \u003c\u003d 0)\n goto err;\n- /*\n- * Oddball MDC2 case: signature can be OCTET STRING. check for correct\n- * tag and length octets.\n- */\n- if (dtype \u003d\u003d NID_mdc2 \u0026\u0026 i \u003d\u003d 18 \u0026\u0026 s[0] \u003d\u003d 0x04 \u0026\u0026 s[1] \u003d\u003d 0x10) {\n- if (rm) {\n- memcpy(rm, s + 2, 16);\n- *prm_len \u003d 16;\n- ret \u003d 1;\n- } else if (memcmp(m, s + 2, 16)) {\n+\n+ if (type \u003d\u003d NID_md5_sha1) {\n+ /*\n+ * NID_md5_sha1 corresponds to the MD5/SHA1 combination in TLS 1.1 and\n+ * earlier. It has no DigestInfo wrapper but otherwise is\n+ * RSASSA-PKCS1-v1_5.\n+ */\n+ if (decrypt_len !\u003d SSL_SIG_LENGTH) {\n RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n- } else {\n- ret \u003d 1;\n+ goto err;\n }\n- } else if (dtype \u003d\u003d NID_md5_sha1) {\n- /* Special case: SSL signature */\n- if ((i !\u003d SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH))\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n- else\n- ret \u003d 1;\n- } else {\n- const unsigned char *p \u003d s;\n- sig \u003d d2i_X509_SIG(NULL, \u0026p, (long)i);\n \n- if (sig \u003d\u003d NULL)\n- goto err;\n+ if (rm !\u003d NULL) {\n+ memcpy(rm, decrypt_buf, SSL_SIG_LENGTH);\n+ *prm_len \u003d SSL_SIG_LENGTH;\n+ } else {\n+ if (m_len !\u003d SSL_SIG_LENGTH) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);\n+ goto err;\n+ }\n \n- /* Excess data can be used to create forgeries */\n- if (p !\u003d s + i || !rsa_check_digestinfo(sig, s, i)) {\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n- goto err;\n+ if (memcmp(decrypt_buf, m, SSL_SIG_LENGTH) !\u003d 0) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n+ goto err;\n+ }\n }\n+ } else if (type \u003d\u003d NID_mdc2 \u0026\u0026 decrypt_len \u003d\u003d 2 + 16\n+ \u0026\u0026 decrypt_buf[0] \u003d\u003d 0x04 \u0026\u0026 decrypt_buf[1] \u003d\u003d 0x10) {\n+ /*\n+ * Oddball MDC2 case: signature can be OCTET STRING. check for correct\n+ * tag and length octets.\n+ */\n+ if (rm !\u003d NULL) {\n+ memcpy(rm, decrypt_buf + 2, 16);\n+ *prm_len \u003d 16;\n+ } else {\n+ if (m_len !\u003d 16) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH);\n+ goto err;\n+ }\n \n+ if (memcmp(m, decrypt_buf + 2, 16) !\u003d 0) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n+ goto err;\n+ }\n+ }\n+ } else {\n /*\n- * Parameters to the signature algorithm can also be used to create\n- * forgeries\n+ * If recovering the digest, extract a digest-sized output from the end\n+ * of |decrypt_buf| for |encode_pkcs1|, then compare the decryption\n+ * output as in a standard verification.\n */\n- if (sig-\u003ealgor-\u003eparameter\n- \u0026\u0026 ASN1_TYPE_get(sig-\u003ealgor-\u003eparameter) !\u003d V_ASN1_NULL) {\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n- goto err;\n+ if (rm !\u003d NULL) {\n+ const EVP_MD *md \u003d EVP_get_digestbynid(type);\n+ if (md \u003d\u003d NULL) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_UNKNOWN_ALGORITHM_TYPE);\n+ goto err;\n+ }\n+\n+ m_len \u003d EVP_MD_size(md);\n+ if (m_len \u003e (size_t)decrypt_len) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);\n+ goto err;\n+ }\n+ m \u003d decrypt_buf + decrypt_len - m_len;\n }\n \n- sigtype \u003d OBJ_obj2nid(sig-\u003ealgor-\u003ealgorithm);\n+ /* Construct the encoded digest and ensure it matches. */\n+ if (!encode_pkcs1(\u0026encoded, \u0026encoded_len, type, m, m_len))\n+ goto err;\n \n- if (sigtype !\u003d dtype) {\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH);\n+ if (encoded_len !\u003d decrypt_len\n+ || memcmp(encoded, decrypt_buf, encoded_len) !\u003d 0) {\n+ RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n goto err;\n }\n- if (rm) {\n- const EVP_MD *md;\n- md \u003d EVP_get_digestbynid(dtype);\n- if (md \u0026\u0026 (EVP_MD_size(md) !\u003d sig-\u003edigest-\u003elength))\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);\n- else {\n- memcpy(rm, sig-\u003edigest-\u003edata, sig-\u003edigest-\u003elength);\n- *prm_len \u003d sig-\u003edigest-\u003elength;\n- ret \u003d 1;\n- }\n- } else if (((unsigned int)sig-\u003edigest-\u003elength !\u003d m_len) ||\n- (memcmp(m, sig-\u003edigest-\u003edata, m_len) !\u003d 0)) {\n- RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE);\n- } else\n- ret \u003d 1;\n+\n+ /* Output the recovered digest. */\n+ if (rm !\u003d NULL) {\n+ memcpy(rm, m, m_len);\n+ *prm_len \u003d m_len;\n+ }\n }\n- err:\n- X509_SIG_free(sig);\n- OPENSSL_clear_free(s, (unsigned int)siglen);\n- return (ret);\n+\n+ ret \u003d 1;\n+\n+err:\n+ OPENSSL_clear_free(encoded, (size_t)encoded_len);\n+ OPENSSL_clear_free(decrypt_buf, siglen);\n+ return ret;\n }\n \n-int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len,\n+int RSA_verify(int type, const unsigned char *m, unsigned int m_len,\n const unsigned char *sigbuf, unsigned int siglen, RSA *rsa)\n {\n \n if (rsa-\u003emeth-\u003ersa_verify) {\n- return rsa-\u003emeth-\u003ersa_verify(dtype, m, m_len, sigbuf, siglen, rsa);\n+ return rsa-\u003emeth-\u003ersa_verify(type, m, m_len, sigbuf, siglen, rsa);\n }\n \n- return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa);\n+ return int_rsa_verify(type, m, m_len, NULL, NULL, sigbuf, siglen, rsa);\n }\ndiff --git a/include/openssl/rsa.h b/include/openssl/rsa.h\nindex 9721218..4d6e9cc 100644\n--- a/include/openssl/rsa.h\n+++ b/include/openssl/rsa.h\n@@ -462,6 +462,7 @@ int ERR_load_RSA_strings(void);\n \n /* Function codes. */\n # define RSA_F_CHECK_PADDING_MD 140\n+# define RSA_F_ENCODE_PKCS1 146\n # define RSA_F_INT_RSA_VERIFY 145\n # define RSA_F_OLD_RSA_PRIV_DECODE 147\n # define RSA_F_PKEY_RSA_CTRL 143\ndiff --git a/test/evptests.txt b/test/evptests.txt\nindex 147c8a4..775371f 100644\n--- a/test/evptests.txt\n+++ b/test/evptests.txt\n@@ -2535,11 +2535,12 @@ Input \u003d \u00220123456789ABCDEF1233\u0022\n Output \u003d c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ae\n Result \u003d VERIFY_ERROR\n \n-# parameter is not NULL: should verify OK\n+# parameter is not NULL\n Verify \u003d RSA-2048\n Ctrl \u003d digest:sha1\n Input \u003d \u00220123456789ABCDEF1234\u0022\n Output \u003d 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e75b4f6b37f67edd9c60c800f9ab941c0c157d7d880ca9de40c951d60fd293ae220d4bc510b1572d6e85a1bbbd8605b52e05f1c64fafdae59a1c2fbed214b7844d0134619de62851d5a0522e32e556e5950f3f97b8150e3f0dffee612c924201c27cd9bc8b423a71533380c276d3d59fcba35a2e80a1a192ec266a6c2255012cd86a349fe90a542b355fa3355b04da6cdf1df77f0e7bd44a90e880e1760266d233e465226f5db1c68857847d82072861ee266ddfc2e596845b77e1803274a579835ab5e4975d81d20b7df9cec7795489e4a2bdb8c1cf6a6b359945ac92c\n+Result \u003d VERIFY_ERROR\n \n # embedded digest too long\n Verify \u003d RSA-2048\n","s":{"c":1756843895,"u": 33042}}
],"g": 36503,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}