From 3259ab99df8d8746a46ca7469635751f604e42fc Mon Sep 17 00:00:00 2001 From: Andrew Shadura Date: Wed, 25 Apr 2018 15:38:01 +0200 Subject: New upstream version 3.10.4+ds1 --- libdigidoc/CMakeLists.txt | 60 +++++---- libdigidoc/DigiDocCert.c | 73 +++++----- libdigidoc/DigiDocConfig.c | 3 +- libdigidoc/DigiDocConvert.c | 52 +++++--- libdigidoc/DigiDocDefs.h | 2 + libdigidoc/DigiDocDfExtract.c | 31 ++++- libdigidoc/DigiDocEnc.c | 54 +++++--- libdigidoc/DigiDocEncSAXParser.c | 44 ++++-- libdigidoc/DigiDocGen.c | 58 ++++++-- libdigidoc/DigiDocLib.c | 35 +++-- libdigidoc/DigiDocOCSP.c | 279 ++++++++++++++++++++------------------- libdigidoc/DigiDocObj.c | 150 +++++++++++++++------ libdigidoc/DigiDocSAXParser.c | 32 +++-- libdigidoc/DigiDocVerify.c | 99 +++++++++----- libdigidoc/cdigidoc.rc | 16 +-- libdigidoc/libdigidoc.rc | 16 +-- 16 files changed, 631 insertions(+), 373 deletions(-) (limited to 'libdigidoc') diff --git a/libdigidoc/CMakeLists.txt b/libdigidoc/CMakeLists.txt index eceebfe..87323e4 100644 --- a/libdigidoc/CMakeLists.txt +++ b/libdigidoc/CMakeLists.txt @@ -31,21 +31,18 @@ set( PUBLIC_HEADER ) if( WIN32 ) - add_definitions( -DWITH_SOAPDEFS_H ) + add_definitions( + -DWITH_SOAPDEFS_H + -D_CRT_NONSTDC_NO_DEPRECATE + -D_CRT_SECURE_NO_DEPRECATE + -D_CRT_SECURE_NO_WARNINGS + -D_SCL_SECURE_NO_WARNINGS + ) list( APPEND libdigidoc_SRCS DigiDocGlobals.c DigiDocCSP.c DigiCrypt.c DlgUnit.c DlgUnitS.c ) set( EXT_LIBRARIES Crypt32 Comctl32 ) endif() -if( MSVC ) - add_definitions( - -D_CRT_NONSTDC_NO_DEPRECATE - -D_CRT_SECURE_NO_DEPRECATE - -D_CRT_SECURE_NO_WARNINGS - -D_SCL_SECURE_NO_WARNINGS - ) -endif() - -add_library( digidoc SHARED +add_library( digidoc ${BUILD_TYPE} ${PUBLIC_HEADER} ${CMAKE_CURRENT_BINARY_DIR}/${DIGIDOC_CONF_NAME} ${libdigidoc_SRCS} @@ -75,11 +72,11 @@ add_library( digidoc SHARED ) target_link_libraries( digidoc - ${CMAKE_DL_LIBS} - ${LIBXML2_LIBRARIES} - ${OPENSSL_LIBRARIES} - ${ZLIB_LIBRARIES} - ${EXT_LIBRARIES} + ${CMAKE_DL_LIBS} + ${LIBXML2_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${ZLIB_LIBRARIES} + ${EXT_LIBRARIES} ) set_target_properties( digidoc PROPERTIES @@ -93,8 +90,10 @@ set_target_properties( digidoc PROPERTIES MACOSX_RPATH YES ) -add_executable(cdigidoc cdigidoc.c cdigidoc.rc) -target_link_libraries(cdigidoc digidoc) +if( BUILD_TOOLS ) + add_executable(cdigidoc cdigidoc.c cdigidoc.rc) + target_link_libraries(cdigidoc digidoc) +endif() install( TARGETS digidoc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -106,7 +105,7 @@ install( TARGETS digidoc ) if(WIN32) - install( DIRECTORY ${PROJECT_BINARY_DIR}/libdigidoc/ DESTINATION ${CMAKE_INSTALL_LIBDIR} FILES_MATCHING PATTERN "*.pdb" ) + install(FILES $ $ DESTINATION ${CMAKE_INSTALL_BINDIR} OPTIONAL) endif() if( FRAMEWORK ) @@ -119,14 +118,17 @@ if( FRAMEWORK ) add_custom_command( TARGET cdigidoc POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ $/Resources ) add_custom_target( codesign DEPENDS cdigidoc - COMMAND codesign -f -s \"$$SIGNCERT\" $/Resources/cdigidoc - COMMAND codesign -f -s \"$$SIGNCERT\" $/../.. + COMMAND codesign -f -s ${SIGNCERT} + $/Resources/cdigidoc + $/../.. COMMAND touch $ ) - add_custom_target( pkgbuild DEPENDS codesign - COMMAND make install DESTDIR=install \; pkgbuild - --root install - --sign \"$$INSTCERT\" + if(INSTCERT) + set(PKGEXTRA --sign ${INSTCERT}) + endif() + add_custom_target( pkgbuild DEPENDS cdigidoc + COMMAND make install DESTDIR=install + COMMAND pkgbuild --root install ${PKGEXTRA} ${CMAKE_BINARY_DIR}/libdigidoc_${VERSION}$ENV{VER_SUFFIX}.pkg ) add_custom_target( zipdebug DEPENDS cdigidoc @@ -135,12 +137,14 @@ if( FRAMEWORK ) COMMAND zip -r ${CMAKE_BINARY_DIR}/libdigidoc-dbg_${VERSION}$ENV{VER_SUFFIX}.zip libdigidoc.dSYM ) else() - install( TARGETS cdigidoc DESTINATION ${CMAKE_INSTALL_BINDIR} ) configure_file( libdigidoc.pc.cmake libdigidoc.pc @ONLY ) - configure_file( cdigidoc.1.cmake cdigidoc.1 ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libdigidoc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig ) - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/cdigidoc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 ) install( FILES ${CERTS} DESTINATION ${CMAKE_INSTALL_FULL_DATADIR}/libdigidoc ) + if( BUILD_TOOLS ) + install( TARGETS cdigidoc DESTINATION ${CMAKE_INSTALL_BINDIR} ) + configure_file( cdigidoc.1.cmake cdigidoc.1 ) + install( FILES ${CMAKE_CURRENT_BINARY_DIR}/cdigidoc.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 ) + endif() endif() #install( FILES diff --git a/libdigidoc/DigiDocCert.c b/libdigidoc/DigiDocCert.c index 3d248bd..6c2eec6 100644 --- a/libdigidoc/DigiDocCert.c +++ b/libdigidoc/DigiDocCert.c @@ -1107,16 +1107,17 @@ EXP_OPTION int readCertExtData(X509* pCert, DigiDocMemBuf* pMemBuf, int nExt, in pos = X509_get_ext_by_NID(pCert, nExt, -1); if(pos >= 0) { pExt = X509_get_ext(pCert, pos); - if(pExt && pExt->value && pExt->value->data) { + ASN1_OCTET_STRING *value = X509_EXTENSION_get_data(pExt); + if(pExt && value && value->data) { /* memset(buf1, 0, sizeof(buf1)); l1 = sizeof(buf1); bin2hex(pExt->value->data, pExt->value->length, buf1, &l1); ddocDebug(3, "readCertExtData", "Ext: %d len: %d data: %s", nExt, pExt->value->length, buf1);*/ - if(pExt->value->length > 20 && nOff) + if(value->length > 20 && nOff) //ddocMemAssignData(pMemBuf, ((char*)pExt->value->data) + (pExt->value->length - 20), 20); - ddocMemAssignData(pMemBuf, ((char*)pExt->value->data) + nOff, 20); + ddocMemAssignData(pMemBuf, ((char*)value->data) + nOff, 20); else - ddocMemAssignData(pMemBuf, ((char*)pExt->value->data), pExt->value->length); + ddocMemAssignData(pMemBuf, ((char*)value->data), value->length); } } return err; @@ -1277,6 +1278,7 @@ int ddocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) int err = ERR_OK; X509_NAME *pName = 0; X509_NAME_ENTRY *pNe = 0; + ASN1_STRING *data = 0; int i, n, l, t, b = 0; const char *s; unsigned char* p; @@ -1296,11 +1298,12 @@ int ddocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) else pName = X509_get_subject_name(pCert); RETURN_IF_NULL(pName) - for(i = 0; (err == ERR_OK) && (i < sk_X509_NAME_ENTRY_num(pName->entries)); i++) { - pNe = sk_X509_NAME_ENTRY_value(pName->entries, i); - n = OBJ_obj2nid(pNe->object); + for(i = 0; (err == ERR_OK) && (i < X509_NAME_entry_count(pName)); i++) { + pNe = X509_NAME_get_entry(pName, i); + n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(pNe)); s = OBJ_nid2sn(n); - t = pNe->value->type; + data = X509_NAME_ENTRY_get_data(pNe); + t = data->type; // mostly we find here: // V_ASN1_PRINTABLESTRING, V_ASN1_TELETEXSTRING or V_ASN1_BMPSTRING // that we convert to UTF, but V_ASN1_UTF8STRING allready is in UTF8 @@ -1309,10 +1312,10 @@ int ddocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) // convert to UTF8 only p = 0; if(t == V_ASN1_UTF8STRING) { - p = pNe->value->data; - l = pNe->value->length; + p = data->data; + l = data->length; } else - l = ASN1_STRING_to_UTF8(&p, pNe->value); + l = ASN1_STRING_to_UTF8(&p, data); ddocDebug(5, "ddocCertGetDN", "NameEntry nid: %d type: %d len: %d item: %s value: \'%s\'", n, t, l, s, (p ? (const char*)p : "NULL")); @@ -1371,6 +1374,7 @@ EXP_OPTION int ddocCertGetDNFromName(X509_NAME* pName, DigiDocMemBuf* pMemBuf) { int err = ERR_OK; X509_NAME_ENTRY *pNe = 0; + ASN1_STRING *data = 0; int i, n, l, t, b = 0; const char *s; unsigned char* p; @@ -1383,11 +1387,12 @@ EXP_OPTION int ddocCertGetDNFromName(X509_NAME* pName, DigiDocMemBuf* pMemBuf) pMemBuf->pMem = 0; pMemBuf->nLen = 0; - for(i = 0; (err == ERR_OK) && (i < sk_X509_NAME_ENTRY_num(pName->entries)); i++) { - pNe = sk_X509_NAME_ENTRY_value(pName->entries, i); - n = OBJ_obj2nid(pNe->object); + for(i = 0; (err == ERR_OK) && (i < X509_NAME_entry_count(pName)); i++) { + pNe = X509_NAME_get_entry(pName, i); + n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(pNe)); s = OBJ_nid2sn(n); - t = pNe->value->type; + data = X509_NAME_ENTRY_get_data(pNe); + t = data->type; // mostly we find here: // V_ASN1_PRINTABLESTRING, V_ASN1_TELETEXSTRING or V_ASN1_BMPSTRING // that we convert to UTF, but V_ASN1_UTF8STRING allready is in UTF8 @@ -1396,10 +1401,10 @@ EXP_OPTION int ddocCertGetDNFromName(X509_NAME* pName, DigiDocMemBuf* pMemBuf) // convert to UTF8 only p = 0; if(t == V_ASN1_UTF8STRING) { - p = pNe->value->data; - l = pNe->value->length; + p = data->data; + l = data->length; } else - l = ASN1_STRING_to_UTF8(&p, pNe->value); + l = ASN1_STRING_to_UTF8(&p, data); ddocDebug(5, "ddocCertGetDN", "NameEntry nid: %d type: %d len: %d item: %s value: \'%s\'", n, t, l, s, (p ? (const char*)p : "NULL")); @@ -1437,6 +1442,7 @@ int ddocCertGetDNPart(X509* pCert, DigiDocMemBuf* pMemBuf, int nNid, int bIssuer int err = ERR_OK; X509_NAME *pName = 0; X509_NAME_ENTRY *pNe = 0; + ASN1_STRING *data; int i, n, l, t, m, j; const char *s; unsigned char* p = 0; @@ -1455,11 +1461,12 @@ int ddocCertGetDNPart(X509* pCert, DigiDocMemBuf* pMemBuf, int nNid, int bIssuer pName = X509_get_issuer_name(pCert); else pName = X509_get_subject_name(pCert); - for(i = 0; (err == ERR_OK) && (i < sk_X509_NAME_ENTRY_num(pName->entries)); i++) { - pNe = sk_X509_NAME_ENTRY_value(pName->entries, i); - n = OBJ_obj2nid(pNe->object); + for(i = 0; (err == ERR_OK) && (i < X509_NAME_entry_count(pName)); i++) { + pNe = X509_NAME_get_entry(pName, i); + n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(pNe)); s = OBJ_nid2sn(n); - t = pNe->value->type; + data = X509_NAME_ENTRY_get_data(pNe); + t = data->type; // mostly we find here: // V_ASN1_PRINTABLESTRING, V_ASN1_TELETEXSTRING or V_ASN1_BMPSTRING // that we convert to UTF, but V_ASN1_UTF8STRING allready is in UTF8 @@ -1467,10 +1474,10 @@ int ddocCertGetDNPart(X509* pCert, DigiDocMemBuf* pMemBuf, int nNid, int bIssuer if(n == nNid && s != NULL) { // convert to UTF8 only if(t == V_ASN1_UTF8STRING) { - p = pNe->value->data; - l = pNe->value->length; + p = data->data; + l = data->length; } else - l = ASN1_STRING_to_UTF8(&p, pNe->value); + l = ASN1_STRING_to_UTF8(&p, data); // test for 0x0 m = (p ? strlen(p) : 0); if(m < l && p) { @@ -1650,6 +1657,7 @@ int bdocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) int err = ERR_OK; X509_NAME *pName = 0; X509_NAME_ENTRY *pNe = 0; + ASN1_STRING *data = NULL; int i, n, l, t, b = 0; const char *s; unsigned char* p; @@ -1668,11 +1676,12 @@ int bdocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) pName = X509_get_issuer_name(pCert); else pName = X509_get_subject_name(pCert); - for(i = 0; (err == ERR_OK) && (i < sk_X509_NAME_ENTRY_num(pName->entries)); i++) { - pNe = sk_X509_NAME_ENTRY_value(pName->entries, i); - n = OBJ_obj2nid(pNe->object); + for(i = 0; (err == ERR_OK) && (i < X509_NAME_entry_count(pName)); i++) { + pNe = X509_NAME_get_entry(pName, i); + data = X509_NAME_ENTRY_get_data(pNe); + n = OBJ_obj2nid(X509_NAME_ENTRY_get_object(pNe)); s = OBJ_nid2sn(n); - t = pNe->value->type; + t = data->type; // mostly we find here: // V_ASN1_PRINTABLESTRING, V_ASN1_TELETEXSTRING or V_ASN1_BMPSTRING // that we convert to UTF, but V_ASN1_UTF8STRING allready is in UTF8 @@ -1681,10 +1690,10 @@ int bdocCertGetDN(X509* pCert, DigiDocMemBuf* pMemBuf, int bIssuer) // convert to UTF8 only p = 0; if(t == V_ASN1_UTF8STRING) { - p = pNe->value->data; - l = pNe->value->length; + p = data->data; + l = data->length; } else - l = ASN1_STRING_to_UTF8(&p, pNe->value); + l = ASN1_STRING_to_UTF8(&p, data); ddocDebug(5, "ddocCertGetDN", "NameEntry nid: %d type: %d len: %d item: %s value: \'%s\'", n, t, l, s, (p ? (const char*)p : "NULL")); diff --git a/libdigidoc/DigiDocConfig.c b/libdigidoc/DigiDocConfig.c index 67db4d7..b6c733e 100644 --- a/libdigidoc/DigiDocConfig.c +++ b/libdigidoc/DigiDocConfig.c @@ -34,7 +34,9 @@ //AA 04/01/26 #ifdef WIN32 #include +#if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf +#endif #elif defined(__APPLE__) #include #endif @@ -310,7 +312,6 @@ EXP_OPTION int initConfigStore(const char* szConfigFile) snprintf(g_szGlobalConfigFile, _MAX_PATH, "%s/%s", g_frameworkResources, DIGIDOC_CONF_NAME); CFRelease(url); } - CFRelease(bundle); } CFRelease(identifier); #endif diff --git a/libdigidoc/DigiDocConvert.c b/libdigidoc/DigiDocConvert.c index d81b070..73f6484 100644 --- a/libdigidoc/DigiDocConvert.c +++ b/libdigidoc/DigiDocConvert.c @@ -40,7 +40,17 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif //==========< general fucntions >============ @@ -836,16 +846,18 @@ int ddocConvertFileName(char* dest, int destlen, const char* src) //============================================================ EXP_OPTION void encode(const byte* raw, int rawlen, byte* buf, int* buflen) { - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; RETURN_VOID_IF_NULL(raw); RETURN_VOID_IF_NULL(buf); RETURN_VOID_IF_NULL(buflen); memset(buf, 0, *buflen); - EVP_EncodeInit(&ectx); - EVP_EncodeUpdate(&ectx, buf, buflen, (byte*)raw, rawlen); - EVP_EncodeFinal(&ectx, (unsigned char*)strchr((const char*)buf, 0), buflen); + ectx = EVP_ENCODE_CTX_new(); + EVP_EncodeInit(ectx); + EVP_EncodeUpdate(ectx, buf, buflen, (byte*)raw, rawlen); + EVP_EncodeFinal(ectx, (unsigned char*)strchr((const char*)buf, 0), buflen); + EVP_ENCODE_CTX_free(ectx); *buflen = strlen((const char*)buf); while(buf[*buflen-1] == '\n' || buf[*buflen-1] == '\r' || buf[*buflen-1] == '-') { if(buf[*buflen-1] == '-') @@ -887,7 +899,7 @@ byte* breakToLinesOf64(byte* raw, int rawlen) //============================================================ EXP_OPTION void decode(const byte* raw, int rawlen, byte* buf, int* buflen) { - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; int l1 = 0; byte* p; @@ -897,21 +909,23 @@ EXP_OPTION void decode(const byte* raw, int rawlen, byte* buf, int* buflen) memset(buf, 0, *buflen); *buflen = 0; - EVP_DecodeInit(&ectx); + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); if((!strstr((const char*)raw, "\n") || !strstr((const char*)raw, "\r")) && strlen((const char*)raw) > 64) { p = breakToLinesOf64((byte*)raw, rawlen); l1 = strlen((const char*)p); - EVP_DecodeUpdate(&ectx, (unsigned char*)buf, &l1, + EVP_DecodeUpdate(ectx, (unsigned char*)buf, &l1, (unsigned char*)p, strlen((const char*)p)); *buflen += l1; free(p); } else - EVP_DecodeUpdate(&ectx, buf, buflen, (byte*)raw, rawlen); - EVP_DecodeFinal(&ectx, buf, &l1); + EVP_DecodeUpdate(ectx, buf, buflen, (byte*)raw, rawlen); + EVP_DecodeFinal(ectx, buf, &l1); + EVP_ENCODE_CTX_free(ectx); *buflen += l1; } @@ -939,7 +953,7 @@ EXP_OPTION int ddocDecodeBase64(DigiDocMemBuf* pMBufSrc, DigiDocMemBuf* pMBufDes { int err = ERR_OK, n; long lPos1 = 0, lPos2 = 0; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; char buf1[70]; RETURN_IF_NULL(pMBufSrc); RETURN_IF_NULL(pMBufDest); @@ -949,7 +963,8 @@ EXP_OPTION int ddocDecodeBase64(DigiDocMemBuf* pMBufSrc, DigiDocMemBuf* pMBufDes // alloc mem for result - it will get smaller so original length must be enough err = ddocMemSetLength(pMBufDest, pMBufSrc->nLen); if(err) return err; - EVP_DecodeInit(&ectx); + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); // decode base64 while(lPos1 < pMBufSrc->nLen) { // copy next input row @@ -965,13 +980,14 @@ EXP_OPTION int ddocDecodeBase64(DigiDocMemBuf* pMBufSrc, DigiDocMemBuf* pMBufDes strncat(buf1, "\n", sizeof(buf1) - strlen(buf1)); // decode this chunk n = pMBufDest->nLen - lPos2; - EVP_DecodeUpdate(&ectx, (unsigned char*)((char*)pMBufDest->pMem + lPos2), &n, + EVP_DecodeUpdate(ectx, (unsigned char*)((char*)pMBufDest->pMem + lPos2), &n, (unsigned char*)buf1, strlen((const char*)buf1)); lPos2 += n; } memset(buf1, 0, sizeof(buf1)); n = sizeof(buf1); - EVP_DecodeFinal(&ectx, (unsigned char*)buf1, &n); + EVP_DecodeFinal(ectx, (unsigned char*)buf1, &n); + EVP_ENCODE_CTX_free(ectx); lPos2 += n; pMBufDest->nLen = lPos2; return err; @@ -1005,7 +1021,7 @@ EXP_OPTION int ddocDecodeBase64Data(void* data, long len, DigiDocMemBuf* pMBufDe EXP_OPTION int ddocEncodeBase64(const DigiDocMemBuf* pMBufSrc, DigiDocMemBuf* pMBufDest) { int err = ERR_OK, nLen; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; RETURN_IF_NULL(pMBufSrc); RETURN_IF_NULL(pMBufDest); @@ -1015,14 +1031,16 @@ EXP_OPTION int ddocEncodeBase64(const DigiDocMemBuf* pMBufSrc, DigiDocMemBuf* pM // alloc mem for result err = ddocMemSetLength(pMBufDest, pMBufSrc->nLen * 2 + 10); if(err) return err; - EVP_EncodeInit(&ectx); + ectx = EVP_ENCODE_CTX_new(); + EVP_EncodeInit(ectx); // encode base64 nLen = pMBufDest->nLen; - EVP_EncodeUpdate(&ectx, (unsigned char*)pMBufDest->pMem, &nLen, + EVP_EncodeUpdate(ectx, (unsigned char*)pMBufDest->pMem, &nLen, (byte*)pMBufSrc->pMem, pMBufSrc->nLen); pMBufDest->nLen = nLen; nLen = (pMBufSrc->nLen * 2 + 10) - pMBufDest->nLen; - EVP_EncodeFinal(&ectx, (unsigned char*)pMBufDest->pMem + pMBufDest->nLen, &nLen); + EVP_EncodeFinal(ectx, (unsigned char*)pMBufDest->pMem + pMBufDest->nLen, &nLen); + EVP_ENCODE_CTX_free(ectx); pMBufDest->nLen += nLen; //strlen((const char*)pMBufDest->pMem); return err; } diff --git a/libdigidoc/DigiDocDefs.h b/libdigidoc/DigiDocDefs.h index 713369c..f691326 100644 --- a/libdigidoc/DigiDocDefs.h +++ b/libdigidoc/DigiDocDefs.h @@ -52,7 +52,9 @@ #define FILESEPARATOR "\\" #include #include + #if defined(_MSC_VER) && _MSC_VER < 1900 #define snprintf _snprintf + #endif #else #define FILESEPARATOR "/" #define DIGI_DOC_LIB diff --git a/libdigidoc/DigiDocDfExtract.c b/libdigidoc/DigiDocDfExtract.c index 28345e9..d28725b 100644 --- a/libdigidoc/DigiDocDfExtract.c +++ b/libdigidoc/DigiDocDfExtract.c @@ -38,6 +38,18 @@ #include #endif +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif + #define ST_START 0 #define ST_XML 1 #define ST_TAG_NM 2 @@ -71,7 +83,7 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, char chars[1050], tag[100], attr[100], con[1030], dec[70], b64line[70]; unsigned char b64 = 0, nNc = 0, bFound = 0; void *pBuf; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; #ifdef WIN32 wchar_t *convFileName = 0, *convDataFileName = 0; i= 0; err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i); @@ -156,7 +168,10 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, if(bFound) { eState = ST_DF_CON; if(b64) - EVP_DecodeInit(&ectx); + { + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); + } } else eState = ST_CON; // tag endded - content lc = 0; @@ -270,7 +285,10 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, lc = 0; con[lc] = 0; if(b64) - EVP_DecodeInit(&ectx); + { + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); + } } break; case ST_DF_CON: @@ -292,7 +310,7 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, b64line[lb] = 0; ld = sizeof(dec); dec[0] = 0; - EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb); + EVP_DecodeUpdate(ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb); lExtr += ld; if(ld > 0) fwrite(dec, 1, ld, fOut); @@ -349,7 +367,7 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, b64line[lb] = 0; ld = sizeof(dec); dec[0] = 0; - EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb); + EVP_DecodeUpdate(ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb); lExtr += ld; if(ld > 0) fwrite(dec, 1, ld, fOut); @@ -358,7 +376,8 @@ EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName, } ld = 0; dec[ld] = 0; - EVP_DecodeFinal(&ectx, (unsigned char*)dec, &ld); + EVP_DecodeFinal(ectx, (unsigned char*)dec, &ld); + EVP_ENCODE_CTX_free(ectx); lExtr += ld; if(ld) fwrite(dec, 1, ld, fOut); diff --git a/libdigidoc/DigiDocEnc.c b/libdigidoc/DigiDocEnc.c index 60752aa..ebe26d4 100644 --- a/libdigidoc/DigiDocEnc.c +++ b/libdigidoc/DigiDocEnc.c @@ -49,6 +49,17 @@ #define snprintf _snprintf #endif +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif //======================< DEncEncryptedData >============================== @@ -894,6 +905,7 @@ int dencEncryptWithCert(X509* pCert, const char* data, int dLen, char* result, i { int err = ERR_OK; EVP_PKEY* pkey; + RSA *rsa; // check parameters RETURN_IF_NULL_PARAM(pCert) @@ -905,7 +917,9 @@ int dencEncryptWithCert(X509* pCert, const char* data, int dLen, char* result, i if(err) return err; // encrypt data memset((char*)result, 0, *resLen); - *resLen = RSA_public_encrypt(dLen, (const unsigned char*)data, (unsigned char*)result, pkey->pkey.rsa, RSA_PKCS1_PADDING); + rsa = EVP_PKEY_get1_RSA(pkey); + *resLen = RSA_public_encrypt(dLen, (const unsigned char*)data, (unsigned char*)result, rsa, RSA_PKCS1_PADDING); + RSA_free(rsa); // cleanup EVP_PKEY_free(pkey); // should I ??? @@ -1317,7 +1331,7 @@ EXP_OPTION int dencEncryptedData_findEncryptedKeyByPKCS12(DEncEncryptedData* pEn int encryptDecrypt(DigiDocMemBuf *pInData, DigiDocMemBuf *pOutData, DigiDocMemBuf *pKey, int operation, const char* iv) { - EVP_CIPHER_CTX ectx; + EVP_CIPHER_CTX *ectx; int err = ERR_OK, len, i, nInLen, nOutLen; char padBuf[16], *pInMem; int lOrigLen, lEncLen; @@ -1364,8 +1378,9 @@ int encryptDecrypt(DigiDocMemBuf *pInData, DigiDocMemBuf *pOutData, // copy init vector to begin of output data if(operation == ENCRYPT) memcpy(pOutData->pMem, iv, 16); - EVP_CIPHER_CTX_init(&ectx); - EVP_CipherInit_ex(&ectx, EVP_aes_128_cbc(), NULL, (const unsigned char*)pKey->pMem, (const unsigned char*)iv, operation); + ectx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(ectx); + EVP_CipherInit_ex(ectx, EVP_aes_128_cbc(), NULL, (const unsigned char*)pKey->pMem, (const unsigned char*)iv, operation); //EVP_CIPHER_CTX_set_padding(&ectx, 1); //checkErrors(); lOrigLen += nInLen; @@ -1375,14 +1390,14 @@ int encryptDecrypt(DigiDocMemBuf *pInData, DigiDocMemBuf *pOutData, pOutData->nLen = 16; else pOutData->nLen = 0; - EVP_CipherUpdate(&ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i, (const unsigned char*)pInMem, nInLen); + EVP_CipherUpdate(ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i, (const unsigned char*)pInMem, nInLen); lEncLen += i; pOutData->nLen += i; ddocDebug(3, "encryptDecrypt", "Initial update: %d into: %d -> %d", nInLen, nOutLen, i); //TODO: in 1.1 don't check len if(len && operation == ENCRYPT) { - EVP_CipherUpdate(&ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i, (const unsigned char*)padBuf, len); + EVP_CipherUpdate(ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i, (const unsigned char*)padBuf, len); ddocDebug(3, "encryptDecrypt", "Padding update: %d -> %d", len, i); pOutData->nLen += i; lOrigLen += len; @@ -1390,12 +1405,12 @@ int encryptDecrypt(DigiDocMemBuf *pInData, DigiDocMemBuf *pOutData, lEncLen += i; } i = nOutLen; - EVP_CipherFinal_ex(&ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i); + EVP_CipherFinal_ex(ectx, (unsigned char*)pOutData->pMem + pOutData->nLen, &i); ddocDebug(3, "encryptDecrypt", "Final update: %d into: %d", i, nOutLen); pOutData->nLen += i; lEncLen += i; ddocDebug(3, "encryptDecrypt", "Total input: %d encrypted: %d", lOrigLen, lEncLen); - EVP_CIPHER_CTX_cleanup(&ectx); + EVP_CIPHER_CTX_free(ectx); if(operation == DECRYPT) { // check ANSI X.923 padding len = (int)(unsigned char)((char*)pOutData->pMem)[pOutData->nLen-1]; @@ -1803,8 +1818,8 @@ EXP_OPTION int dencEncryptFile(DEncEncryptedData* pEncData, { int err = ERR_OK, l1, l2, l3, i, nBlock; long lOrigLen, lEncSize, lWritten; - EVP_CIPHER_CTX ectx; - EVP_ENCODE_CTX bctx; + EVP_CIPHER_CTX *ectx; + EVP_ENCODE_CTX *bctx; char convInFileName[250], convOutFileName[250]; char buf1[4096], buf2[5120], buf3[6144], buf4[70], *p2; DigiDocMemBuf mbuf; @@ -1841,10 +1856,12 @@ EXP_OPTION int dencEncryptFile(DEncEncryptedData* pEncData, fwrite(mbuf.pMem, 1, mbuf.nLen, hOutFile); ddocMemBuf_free(&mbuf); // init encryption - EVP_CIPHER_CTX_init(&ectx); + ectx = EVP_CIPHER_CTX_new(); + EVP_CIPHER_CTX_init(ectx); // init encoding - EVP_EncodeInit(&bctx); - EVP_CipherInit_ex(&ectx, EVP_aes_128_cbc(), NULL, + bctx = EVP_ENCODE_CTX_new(); + EVP_EncodeInit(bctx); + EVP_CipherInit_ex(ectx, EVP_aes_128_cbc(), NULL, (const unsigned char*)pEncData->mbufTransportKey.pMem, (const unsigned char*)pEncData->initVector, ENCRYPT); //EVP_CIPHER_CTX_set_padding(&ectx, 1); @@ -1876,7 +1893,7 @@ EXP_OPTION int dencEncryptFile(DEncEncryptedData* pEncData, p2 += 16; l2 -= 16; } - EVP_CipherUpdate(&ectx, (unsigned char*)p2, &l2, (const unsigned char*)buf1, l1); + EVP_CipherUpdate(ectx, (unsigned char*)p2, &l2, (const unsigned char*)buf1, l1); ddocDebug(3, "dencEncryptFile", "Input: %d, block: %d, buf: %d encrypted: %d", l1, nBlock, sizeof(buf2), l2); lEncSize += l2; // if it's the final block @@ -1887,7 +1904,7 @@ EXP_OPTION int dencEncryptFile(DEncEncryptedData* pEncData, p2 += 16; l3 -= 16; } - EVP_CipherFinal_ex(&ectx, (unsigned char*)p2, &l3); + EVP_CipherFinal_ex(ectx, (unsigned char*)p2, &l3); ddocDebug(3, "dencEncryptFile", "Buf: %d Final encrypted: %d", sizeof(buf2) - l2, l3); l2 += l3; lEncSize += l3; @@ -1898,18 +1915,19 @@ EXP_OPTION int dencEncryptFile(DEncEncryptedData* pEncData, // encode also the IV vector at the beginning of first block if(nBlock == 0) l2 += 16; - EVP_EncodeUpdate(&bctx, (unsigned char*)buf3, &l3, (byte*)buf2, l2); + EVP_EncodeUpdate(bctx, (unsigned char*)buf3, &l3, (byte*)buf2, l2); lWritten += l3; fwrite(buf3, 1, l3, hOutFile); ddocDebug(3, "dencEncryptFile", "In: %d, encrypted: %d, base64: %d", l1, l2, l3); } nBlock++; } while(!err && l1 > 0); - EVP_CIPHER_CTX_cleanup(&ectx); + EVP_CIPHER_CTX_free(ectx); // write the last portion of line data l3 = sizeof(buf3); memset(buf3, 0, l3); - EVP_EncodeFinal(&bctx, (unsigned char*)buf3, &l3); + EVP_EncodeFinal(bctx, (unsigned char*)buf3, &l3); + EVP_ENCODE_CTX_free(bctx); lWritten += l3; fwrite(buf3, 1, l3, hOutFile); ddocDebug(4, "dencEncryptFile", "Total input: %d, blocks: %d, encrypted: %d written: %d", lOrigLen, nBlock, lEncSize, lWritten); diff --git a/libdigidoc/DigiDocEncSAXParser.c b/libdigidoc/DigiDocEncSAXParser.c index bfd347b..cb38322 100644 --- a/libdigidoc/DigiDocEncSAXParser.c +++ b/libdigidoc/DigiDocEncSAXParser.c @@ -51,6 +51,18 @@ #include #include /* only for xmlNewInputFromFile() */ +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif + //===============< SAX handlers >============================== /* @@ -235,18 +247,20 @@ int dencSaxHandleEndCipherValue(DEncParse* pctx) { int err = ERR_OK, l = 0, i; char *p = 0; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; if(pctx->mbufContent.pMem && pctx->mbufContent.nLen) { l = pctx->mbufContent.nLen; // enough since it's shrinking p = (char*)malloc(l); RETURN_IF_BAD_ALLOC(p) //decode((const byte*)pctx->mbufContent.pMem, pctx->mbufContent.nLen, p, &l); - EVP_DecodeInit(&ectx); - EVP_DecodeUpdate(&ectx, (unsigned char*)p, &l, (unsigned char*)pctx->mbufContent.pMem, pctx->mbufContent.nLen); + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); + EVP_DecodeUpdate(ectx, (unsigned char*)p, &l, (unsigned char*)pctx->mbufContent.pMem, pctx->mbufContent.nLen); ddocDebug(3, "dencSaxHandleEndCipherValue", "Initial decoding: %d -> %d bytes", pctx->mbufContent.nLen, l); i = pctx->mbufContent.nLen - l; - EVP_DecodeFinal(&ectx, (unsigned char*)p+l, &i); + EVP_DecodeFinal(ectx, (unsigned char*)p+l, &i); + EVP_ENCODE_CTX_free(ectx); l += i; ddocDebug(3, "dencSaxHandleEndCipherValue", "Final decoding: %d bytes", i); ddocDebug(3, "dencSaxHandleEndCipherValue", "Decoding: %d bytes of base64 data, got: %d bytes", pctx->mbufContent.nLen, l); @@ -663,8 +677,8 @@ typedef struct DEncDecryptParse_st { char* szPin; int nSlot; long lB64Len, lBinLen, lDecLen; - EVP_ENCODE_CTX ectx; - EVP_CIPHER_CTX dctx; + EVP_ENCODE_CTX *ectx; + EVP_CIPHER_CTX *dctx; int nB64SkipMode; char errmsg[100]; char szCertSerial[100]; @@ -715,8 +729,9 @@ static void dencDecryptStartElementHandler(void *ctx, const xmlChar *name, const !ddocStackHasParentWithName(&(pctx->dencStack), (xmlChar*)"EncryptedKey", NULL)) { if(pctx->nB64SkipMode == 0) { ddocDebug(4, "dencDecryptStartElementHandler", "Decode init"); - EVP_DecodeInit(&(pctx->ectx)); - EVP_CIPHER_CTX_init(&(pctx->dctx)); + pctx->ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(pctx->ectx); + EVP_CIPHER_CTX_init(pctx->dctx); pctx->lB64Len = pctx->lBinLen = pctx->lDecLen = 0; } pctx->nB64SkipMode++; // increment skip mode @@ -825,14 +840,16 @@ static void dencDecryptEndElementHandler(void *ctx, const xmlChar *name) l1 = sizeof(buf1); memset(buf1, 0, l1); ddocDebug(4, "dencDecryptEndElementHandler", "Decoding: final into: %d", l1); - EVP_DecodeFinal(&(pctx->ectx), (unsigned char*)buf1, &l1); + EVP_DecodeFinal(pctx->ectx, (unsigned char*)buf1, &l1); + EVP_ENCODE_CTX_free(pctx->ectx); pctx->lBinLen += l1; ddocDebug(4, "dencDecryptEndElementHandler", "Decoded: final got: %d, total %d -> %d", l1, pctx->lB64Len, pctx->lBinLen); // decrypt decoded data l2 = sizeof(buf2); memset(buf2, 0, l2); ddocDebug(3, "dencDecryptEndElementHandler", "Decrypting: final into: %d", l2); - EVP_CipherFinal_ex(&(pctx->dctx), (unsigned char*)buf2, &l2); + EVP_CipherFinal_ex(pctx->dctx, (unsigned char*)buf2, &l2); + EVP_CIPHER_CTX_free(pctx->dctx); ddocDebug(4, "dencDecryptEndElementHandler", "Decrypted: final got: %d", l2); // write to file if(pctx->hOutFile) { @@ -902,7 +919,7 @@ static void dencDecryptCharactersHandler(void *ctx, const xmlChar *ch, int len) } memset(buf1, 0, l1); ddocDebug(4, "dencDecryptCharactersHandler", "Decoding: %d into: %d, skip: %d", len, l1, pctx->nB64SkipMode); - EVP_DecodeUpdate(&(pctx->ectx), (unsigned char*)buf1, &l1, (unsigned char*)ch, len); + EVP_DecodeUpdate(pctx->ectx, (unsigned char*)buf1, &l1, (unsigned char*)ch, len); ddocDebug(4, "dencDecryptCharactersHandler", "Decoded: %d got: %d, skip: %d", len, l1, pctx->nB64SkipMode); // if this was the first block of decoded base64 data // then use the first 16 bytes as the IV value @@ -911,7 +928,8 @@ static void dencDecryptCharactersHandler(void *ctx, const xmlChar *ch, int len) ddocDebug(4, "dencDecryptCharactersHandler", "Using 16 bytes for IV. Initing cipher"); p1 += 16; // don't decrypt the IV data l1 -= 16; - EVP_CipherInit_ex(&(pctx->dctx), EVP_aes_128_cbc(), NULL, + pctx->dctx = EVP_CIPHER_CTX_new(); + EVP_CipherInit_ex(pctx->dctx, EVP_aes_128_cbc(), NULL, (const unsigned char*)pctx->mbufTransportKey.pMem, (const unsigned char*)buf1, DECRYPT); } pctx->lBinLen += l1; @@ -927,7 +945,7 @@ static void dencDecryptCharactersHandler(void *ctx, const xmlChar *ch, int len) //if(pctx->nB64SkipMode == 4) // l1 += 16; // ??? ddocDebug(4, "dencDecryptCharactersHandler", "Decrypting: %d into: %d", l1, l2); - EVP_CipherUpdate(&(pctx->dctx), (unsigned char*)buf2, &l, (const unsigned char*)p1, l1); + EVP_CipherUpdate(pctx->dctx, (unsigned char*)buf2, &l, (const unsigned char*)p1, l1); ddocDebug(4, "dencDecryptCharactersHandler", "Decrypted: %d got: %d, skip: %d", l1, l, pctx->nB64SkipMode); if(buf1) free(buf1); diff --git a/libdigidoc/DigiDocGen.c b/libdigidoc/DigiDocGen.c index dc016b1..805b479 100644 --- a/libdigidoc/DigiDocGen.c +++ b/libdigidoc/DigiDocGen.c @@ -47,6 +47,25 @@ #include +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} + +static void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n) *n = r->n; + if (e) *e = r->e; + if (d) *d = r->d; +} +#endif + //-----------< helper functions >---------------------------- @@ -265,13 +284,13 @@ EXP_OPTION time_t convertStringToTimeT(const SignedDoc* pSigDoc, const char* szT } tm1.tm_year -= 1900; tm1.tm_mon -= 1; - tm1.tm_isdst = daylight; + tm1.tm_isdst = _daylight; t2 = mktime(&tm1); if(_daylight != 0) { if(_timezone < 0) - dmz = (_timezone / 3600) - daylight; + dmz = (_timezone / 3600) - _daylight; else - dmz = (_timezone / 3600) + daylight; + dmz = (_timezone / 3600) + _daylight; } else dmz = _timezone / 3600; @@ -1088,6 +1107,8 @@ int addSignatureInfoXML(DigiDocMemBuf *pMBufXML, SignedDoc* pSigDoc, SignatureIn unsigned char buf2[500], *buf1 = 0; int len2, len1; EVP_PKEY* pubKey = NULL; + const RSA *rsa = NULL; + const BIGNUM *n = NULL, *e = NULL; SignatureValue *pSigVal; DigiDocMemBuf mbuf1; @@ -1127,9 +1148,11 @@ int addSignatureInfoXML(DigiDocMemBuf *pMBufXML, SignedDoc* pSigDoc, SignatureIn // FIXME // modulus //AM 11.02.09 - if(!err && pubKey->type==NID_rsaEncryption) { + if(!err && EVP_PKEY_base_id(pubKey)==EVP_PKEY_RSA) { ddocMemAppendData(pMBufXML,"\n\n", -1); - len1 = BN_bn2bin(pubKey->pkey.rsa->n, buf1); + rsa = EVP_PKEY_get1_RSA(pubKey); + RSA_get0_key(rsa, &n, &e, NULL); + len1 = BN_bn2bin(n, buf1); // in version 1.1 we output modulus as it is // starting from 1.2 we convert it to big-endian /*len2 = sizeof(buf2); @@ -1148,7 +1171,7 @@ int addSignatureInfoXML(DigiDocMemBuf *pMBufXML, SignedDoc* pSigDoc, SignatureIn ddocMemAppendData(pMBufXML,"\n", -1); // exponent memset(buf1, 0, len1); - len1 = BN_bn2bin(pubKey->pkey.rsa->e, buf1); + len1 = BN_bn2bin(e, buf1); len2 = sizeof(buf2); memset(buf2, 0, len2); encode(buf1, len1, buf2, &len2); @@ -1156,7 +1179,8 @@ int addSignatureInfoXML(DigiDocMemBuf *pMBufXML, SignedDoc* pSigDoc, SignatureIn ddocMemAppendData(pMBufXML, (char*)buf2, -1); ddocMemAppendData(pMBufXML,"\n", -1); ddocMemAppendData(pMBufXML,"\n\n", -1); - } + RSA_free(rsa); + } // cert data ddocMemAppendData(pMBufXML,"\n", -1); } @@ -1237,7 +1261,7 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, char buf1[2050], buf2[5000], fixedFileName[1024], *p = 0; char *name, *value, *fName; FILE *fIn = 0; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; SHA_CTX sctx; DigiDocMemBuf mbuf1, mbuf2, mbuf3; #ifdef WIN32 @@ -1385,7 +1409,10 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, #endif ddocDebug(4, "generateDataFileXML", "Opened FILE01: %s", szDataFile); if(!strcmp(pSigDoc->szFormat, SK_XML_1_NAME)) - EVP_DecodeInit(&ectx); + { + ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(ectx); + } while((len1 = fread(buf1, 1, sizeof(buf1)-2, fIn)) > 0) { #ifdef WITH_BASE64_HASHING_HACK if(!strcmp(pDataFile->szContentType, CONTENT_EMBEDDED_BASE64)) { @@ -1407,7 +1434,7 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, while(*p == ' ' || *p == '\n' || *p == '\r') p++; ddocDebug(4, "generateDataFileXML", "decode: %s", p); len2 = sizeof(buf2); - EVP_DecodeUpdate(&ectx, (unsigned char*)buf2, &len2, (unsigned char*)p, strlen(p)); + EVP_DecodeUpdate(ectx, (unsigned char*)buf2, &len2, (unsigned char*)p, strlen(p)); ddocDebug(4, "generateDataFileXML", "sha1 update orig: %d: dec: %d", len1, len2); SHA1_Update(&sctx, (const char*)buf2, len2); //ddocDebugWriteFile(4, "df-data0.txt", &mbuf3); @@ -1427,7 +1454,8 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, fIn = 0; if(!strcmp(pSigDoc->szFormat, SK_XML_1_NAME)) { len2 = sizeof(buf2); - EVP_DecodeFinal(&ectx, (unsigned char*)buf2, &len2); + EVP_DecodeFinal(ectx, (unsigned char*)buf2, &len2); + EVP_ENCODE_CTX_free(ectx); SHA1_Update(&sctx, (const char*)buf2, len2); ddocDebug(4, "generateDataFileXML", "sha1 final dec: %d", len1, len2); len2 = sizeof(buf2); @@ -1455,10 +1483,11 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, ddocDebug(4, "generateDataFileXML", "Opened FILE2: %s", fixedFileName); // if encoded if(!strcmp(pDataFile->szContentType, CONTENT_EMBEDDED_BASE64)) { - EVP_EncodeInit(&ectx); + ectx = EVP_ENCODE_CTX_new(); + EVP_EncodeInit(ectx); while((len1 = fread(buf1, 1, sizeof(buf1), fIn)) > 0) { len2 = sizeof(buf2); - EVP_EncodeUpdate(&ectx, (unsigned char*)buf2, &len2, (unsigned char*)buf1, len1); + EVP_EncodeUpdate(ectx, (unsigned char*)buf2, &len2, (unsigned char*)buf1, len1); buf2[len2] = 0; #ifdef WITH_BASE64_HASHING_HACK ddocCanonicalizePCDATA(buf2); @@ -1474,7 +1503,8 @@ EXP_OPTION int generateDataFileXML(SignedDoc* pSigDoc, DataFile* pDataFile, if(hFile) fwrite(buf2, sizeof(char), len2, hFile); } - EVP_EncodeFinal(&ectx, (unsigned char*)buf2, &len2); + EVP_EncodeFinal(ectx, (unsigned char*)buf2, &len2); + EVP_ENCODE_CTX_free(ectx); buf2[len2] = 0; #ifdef WITH_BASE64_HASHING_HACK ddocCanonicalizePCDATA(buf2); diff --git a/libdigidoc/DigiDocLib.c b/libdigidoc/DigiDocLib.c index 4ec82e2..83509d1 100644 --- a/libdigidoc/DigiDocLib.c +++ b/libdigidoc/DigiDocLib.c @@ -125,6 +125,21 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_MD_CTX *EVP_MD_CTX_new() +{ + return (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX)); +} + +static void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#else +# define BIO_R_BAD_HOSTNAME_LOOKUP 102 +# define OCSP_R_SERVER_WRITE_ERROR 116 +#endif + long int tzone = -7200; /* default for Estonia, but see initDigiDocLib() */ int daylight = 0; /* default, but see initDigiDocLib() */ @@ -474,7 +489,7 @@ EXP_OPTION int calculateFileSignature(const char* szFileName, int nDigestType, const char *keyfile, const char* passwd) { int err = ERR_OK; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; byte buf[FILE_BUFSIZE]; int i; FILE *f = NULL; @@ -491,13 +506,15 @@ EXP_OPTION int calculateFileSignature(const char* szFileName, int nDigestType, if(*nSigLen >= SIGNATURE_LEN) { if((err = ReadPrivateKey(&pkey, keyfile, passwd, FILE_FORMAT_PEM)) == ERR_OK) { if((f = fopen(szFileName,"rb")) != NULL) { - EVP_SignInit(&ctx, EVP_sha1()); + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, EVP_sha1()); for (;;) { i = fread(buf, sizeof(char), FILE_BUFSIZE, f); if (i <= 0) break; - EVP_SignUpdate (&ctx, buf, (unsigned long)i); + EVP_SignUpdate (ctx, buf, (unsigned long)i); } - err = EVP_SignFinal(&ctx, pSigBuf, (unsigned int*)nSigLen, pkey); + err = EVP_SignFinal(ctx, pSigBuf, (unsigned int*)nSigLen, pkey); + EVP_MD_CTX_free(ctx); if(err == ERR_LIB_NONE) err = ERR_OK; fclose(f); @@ -535,7 +552,7 @@ EXP_OPTION int signData(const byte* data, int dlen, byte* pSigBuf, int* nSigLen, int nDigestType, const char *keyfile, const char* passwd) { int err = ERR_OK; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; EVP_PKEY* pkey; RETURN_IF_NULL_PARAM(data); @@ -548,9 +565,11 @@ EXP_OPTION int signData(const byte* data, int dlen, byte* pSigBuf, int* nSigLen, if(nDigestType == DIGEST_SHA1) { if(*nSigLen >= SIGNATURE_LEN) { if((err = ReadPrivateKey(&pkey, keyfile, passwd, FILE_FORMAT_PEM)) == ERR_OK) { - EVP_SignInit(&ctx, EVP_sha1()); - EVP_SignUpdate (&ctx, data, (unsigned long)dlen); - err = EVP_SignFinal(&ctx, pSigBuf, (unsigned int*)nSigLen, pkey); + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, EVP_sha1()); + EVP_SignUpdate (ctx, data, (unsigned long)dlen); + err = EVP_SignFinal(ctx, pSigBuf, (unsigned int*)nSigLen, pkey); + EVP_MD_CTX_free(ctx); if(err == ERR_LIB_NONE) err = ERR_OK; EVP_PKEY_free(pkey); diff --git a/libdigidoc/DigiDocOCSP.c b/libdigidoc/DigiDocOCSP.c index 48973e7..5c48aac 100644 --- a/libdigidoc/DigiDocOCSP.c +++ b/libdigidoc/DigiDocOCSP.c @@ -59,6 +59,58 @@ static int password_callback(char *buf, int bufsiz, int verify, void *cb_data) } #endif +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, const ASN1_OCTET_STRING **pid, const X509_NAME **pname) +{ + *pid = NULL; + *pname = NULL; + const OCSP_RESPID *rid = bs->tbsResponseData->responderId; + if (rid->type == V_OCSP_RESPID_NAME) + *pname = rid->value.byName; + else if (rid->type == V_OCSP_RESPID_KEY) + *pid = rid->value.byKey; + else + return 0; + return 1; +} + +static const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs) +{ + return bs->tbsResponseData->producedAt; +} + +static const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) +{ + return single->certId; +} + +static const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) +{ + return bs->signature; +} + +static const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) +{ + return x->cert_info->extensions; +} + +static const ASN1_TIME *X509_get0_notBefore(const X509 *x) +{ + return x->cert_info->validity->notBefore; +} + +static const ASN1_TIME *X509_get0_notAfter(const X509 *x) +{ + return x->cert_info->validity->notAfter; +} +#else +# define BIO_R_BAD_HOSTNAME_LOOKUP 102 +# define OCSP_R_NO_CONTENT 106 +# define OCSP_F_OCSP_SENDREQ_BIO 112 +# define OCSP_R_SERVER_READ_ERROR 113 +# define OCSP_R_SERVER_WRITE_ERROR 116 +#endif + //================< OCSP functions> ================================= static int ddocOcspProxyAuthInfo(char *authinfo, const char *user, const char *pass) @@ -309,20 +361,21 @@ int calcNotaryDigest(SignedDoc* pSigDoc, NotaryInfo* pNotary) int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, OCSP_RESPONSE *resp, X509 *notCert, int initDigest) { - int n, err = ERR_OK; + int n, err = ERR_OK, status = 0; char buf[500]; OCSP_RESPBYTES *rb = NULL; OCSP_BASICRESP *br = NULL; - OCSP_RESPDATA *rd = NULL; - OCSP_RESPID *rid = NULL; - // OCSP_CERTSTATUS *cst = NULL; OCSP_SINGLERESP *single = NULL; - OCSP_CERTID *cid = NULL; + const OCSP_CERTID *cid = NULL; X509_EXTENSION *nonce; + const ASN1_GENERALIZEDTIME *producedAt = NULL; //AM 26.09.08 DigiDocMemBuf mbuf1; mbuf1.pMem = 0; mbuf1.nLen = 0; + const ASN1_OCTET_STRING *id = NULL; + const X509_NAME *name = NULL; + ASN1_OBJECT *hashAlgorithm = NULL; RETURN_IF_NULL_PARAM(pNotary); @@ -348,69 +401,66 @@ int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, default: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNSUCCESSFUL); } - RETURN_IF_NULL_PARAM(resp->responseBytes); - rb = resp->responseBytes; - if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE); if((br = OCSP_response_get1_basic(resp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); ddocDebug(4, "initializeNotaryInfoWithOCSP", "test2"); - rd = br->tbsResponseData; - if(ASN1_INTEGER_get(rd->version) != 0) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION); - n = sk_OCSP_SINGLERESP_num(rd->responses); + n = OCSP_resp_count(br); if(n != 1) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE); - single = sk_OCSP_SINGLERESP_value(rd->responses, 0); + single = OCSP_resp_get0(br, 0); RETURN_IF_NULL(single); - cid = single->certId; + cid = OCSP_SINGLERESP_get0_id(single); RETURN_IF_NULL(cid); - ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", single->certStatus->type); + status = OCSP_single_get0_status(single, NULL, NULL, NULL, NULL); + ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", status); //printf("TYPE: %d\n", single->certStatus->type); - if(single->certStatus->type != 0) { - ddocDebug(4, "initializeNotaryInfoWithOCSP", "errcode: %d", handleOCSPCertStatus(single->certStatus->type)); - SET_LAST_ERROR_RETURN_CODE(handleOCSPCertStatus(single->certStatus->type)); + if(status != 0) { + ddocDebug(4, "initializeNotaryInfoWithOCSP", "errcode: %d", handleOCSPCertStatus(status)); + SET_LAST_ERROR_RETURN_CODE(handleOCSPCertStatus(status)); } //Removed 31.10.2003 //if(single->singleExtensions) // SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT); - if(!rd->responseExtensions || - (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) || - ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) + if((OCSP_BASICRESP_get_ext_count(br) != 1) || + ((nonce = OCSP_BASICRESP_get_ext(br, 0)) == NULL)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); - i2t_ASN1_OBJECT(buf,sizeof(buf),nonce->object); + i2t_ASN1_OBJECT(buf,sizeof(buf), X509_EXTENSION_get_object(nonce)); if(strcmp(buf, OCSP_NONCE_NAME)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); - rid = rd->responderId; - if(rid->type == V_OCSP_RESPID_NAME) { + OCSP_resp_get0_id(br, &id, &name); + if(name) { pNotary->nRespIdType = RESPID_NAME_TYPE; - } else if(rid->type == V_OCSP_RESPID_KEY) { + } else if(id) { pNotary->nRespIdType = RESPID_KEY_TYPE; } else { SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_RESPID); } // producedAt - err = asn1time2str(pSigDoc, rd->producedAt, buf, sizeof(buf)); + producedAt = OCSP_resp_get0_produced_at(br); + err = asn1time2str(pSigDoc, (ASN1_GENERALIZEDTIME*)producedAt, buf, sizeof(buf)); setString(&(pNotary->timeProduced), buf, -1); n = sizeof(buf); - if(rid->type == V_OCSP_RESPID_NAME){ + if(name){ //X509_NAME_oneline(rid->value.byName,buf,n); - err = ddocCertGetDNFromName(rid->value.byName, &mbuf1); + err = ddocCertGetDNFromName((X509_NAME*)name, &mbuf1); err = ddocNotInfo_SetResponderId(pNotary, (char*)mbuf1.pMem, -1); ddocMemBuf_free(&mbuf1); } - if(rid->type == V_OCSP_RESPID_KEY) { - err = ddocNotInfo_SetResponderId(pNotary, (const char*)rid->value.byKey->data, rid->value.byKey->length); + if(id) { + err = ddocNotInfo_SetResponderId(pNotary, (const char*)id->data, id->length); } + OCSP_id_get0_info(NULL, &hashAlgorithm, NULL, NULL, (OCSP_CERTID*)cid); // digest type - i2t_ASN1_OBJECT(buf,sizeof(buf),cid->hashAlgorithm->algorithm); + i2t_ASN1_OBJECT(buf,sizeof(buf),hashAlgorithm); //AM 24.11.09 why its needed? added if. 08.12.09 used for gen if(!pNotary->szDigestType){ setString(&(pNotary->szDigestType), buf, -1); } +#if OPENSSL_VERSION_NUMBER < 0x10010000L // signature algorithm i2t_ASN1_OBJECT(buf,sizeof(buf),br->signatureAlgorithm->algorithm); setString(&(pNotary->szSigType), buf, -1); +#endif // notary cert if(notCert && !err) err = addNotaryInfoCert(pSigDoc, pNotary, notCert); @@ -427,20 +477,22 @@ int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, int initializeNotaryInfoWithOCSP2(SignedDoc *pSigDoc, NotaryInfo *pNotary, OCSP_RESPONSE *resp, X509 *notCert, int initDigest) { - int n, err = ERR_OK; + int n, err = ERR_OK, status = 0; char buf[500]; OCSP_RESPBYTES *rb = NULL; OCSP_BASICRESP *br = NULL; - OCSP_RESPDATA *rd = NULL; - OCSP_RESPID *rid = NULL; // OCSP_CERTSTATUS *cst = NULL; OCSP_SINGLERESP *single = NULL; - OCSP_CERTID *cid = NULL; + const OCSP_CERTID *cid = NULL; X509_EXTENSION *nonce; + const ASN1_GENERALIZEDTIME *producedAt = NULL; //AM 26.09.08 DigiDocMemBuf mbuf1; mbuf1.pMem = 0; mbuf1.nLen = 0; + const ASN1_OCTET_STRING *id = NULL; + const X509_NAME *name = NULL; + ASN1_OBJECT *hashAlgorithm = NULL; RETURN_IF_NULL_PARAM(pNotary); @@ -462,23 +514,17 @@ int initializeNotaryInfoWithOCSP2(SignedDoc *pSigDoc, NotaryInfo *pNotary, default: SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNSUCCESSFUL); } - RETURN_IF_NULL_PARAM(resp->responseBytes);; - rb = resp->responseBytes; - if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE); if((br = OCSP_response_get1_basic(resp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); - rd = br->tbsResponseData; - if(ASN1_INTEGER_get(rd->version) != 0) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION); - n = sk_OCSP_SINGLERESP_num(rd->responses); + n = OCSP_resp_count(br); if(n != 1) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE); - single = sk_OCSP_SINGLERESP_value(rd->responses, 0); + single = OCSP_resp_get0(br, 0); RETURN_IF_NULL(single); - cid = single->certId; + cid = OCSP_SINGLERESP_get0_id(single); RETURN_IF_NULL(cid); - ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", single->certStatus->type); + status = OCSP_single_get0_status(single, NULL, NULL, NULL, NULL); + ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", status); //printf("TYPE: %d\n", single->certStatus->type); //Am test /*if(single->certStatus->type != 0) { @@ -488,40 +534,43 @@ int initializeNotaryInfoWithOCSP2(SignedDoc *pSigDoc, NotaryInfo *pNotary, //Removed 31.10.2003 //if(single->singleExtensions) // SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT); - if(!rd->responseExtensions || - (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) || - ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) + if((OCSP_BASICRESP_get_ext_count(br) != 1) || + ((nonce = OCSP_BASICRESP_get_ext(br, 0)) == NULL)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); - i2t_ASN1_OBJECT(buf,sizeof(buf),nonce->object); + i2t_ASN1_OBJECT(buf,sizeof(buf),X509_EXTENSION_get_object(nonce)); if(strcmp(buf, OCSP_NONCE_NAME)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); - rid = rd->responderId; - if(rid->type == V_OCSP_RESPID_NAME) { + OCSP_resp_get0_id(br, &id, &name); + if(name) { pNotary->nRespIdType = RESPID_NAME_TYPE; - } else if(rid->type == V_OCSP_RESPID_KEY) { + } else if(id) { pNotary->nRespIdType = RESPID_KEY_TYPE; } else { SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_RESPID); } // producedAt - err = asn1time2str(pSigDoc, rd->producedAt, buf, sizeof(buf)); + producedAt = OCSP_resp_get0_produced_at(br); + err = asn1time2str(pSigDoc, (ASN1_GENERALIZEDTIME*)producedAt, buf, sizeof(buf)); setString(&(pNotary->timeProduced), buf, -1); n = sizeof(buf); - if(rid->type == V_OCSP_RESPID_NAME){ - err = ddocCertGetDNFromName(rid->value.byName, &mbuf1); + if(name){ + err = ddocCertGetDNFromName((X509_NAME*)name, &mbuf1); RETURN_IF_NOT(err == ERR_OK, err); err = ddocNotInfo_SetResponderId(pNotary, (char*)mbuf1.pMem, -1); ddocMemBuf_free(&mbuf1); } - if(rid->type == V_OCSP_RESPID_KEY) { - err = ddocNotInfo_SetResponderId(pNotary, (const char*)rid->value.byKey->data, rid->value.byKey->length); + if(id) { + err = ddocNotInfo_SetResponderId(pNotary, (const char*)id->data, id->length); } + OCSP_id_get0_info(NULL, &hashAlgorithm, NULL, NULL, (OCSP_CERTID*)cid); // digest type - i2t_ASN1_OBJECT(buf,sizeof(buf),cid->hashAlgorithm->algorithm); + i2t_ASN1_OBJECT(buf,sizeof(buf),hashAlgorithm); setString(&(pNotary->szDigestType), buf, -1); +#if OPENSSL_VERSION_NUMBER < 0x10010000L // signature algorithm i2t_ASN1_OBJECT(buf,sizeof(buf),br->signatureAlgorithm->algorithm); setString(&(pNotary->szSigType), buf, -1); +#endif // notary cert if(notCert && !err) err = addNotaryInfoCert(pSigDoc, pNotary, notCert); @@ -716,6 +765,7 @@ unsigned char *get_authority_key(STACK_OF(X509_EXTENSION) *exts) int i, found=0; X509_EXTENSION *ex=0; ASN1_OBJECT *obj; + ASN1_OCTET_STRING *data = NULL; X509V3_EXT_METHOD *met; void *st = NULL; unsigned char *p; @@ -738,10 +788,11 @@ unsigned char *get_authority_key(STACK_OF(X509_EXTENSION) *exts) } met = (X509V3_EXT_METHOD*)X509V3_EXT_get(ex); - p = ex->value->data; + data = X509_EXTENSION_get_data(ex); + p = data->data; #if OPENSSL_VERSION_NUMBER > 0x00908000 // crashes here! - st = ASN1_item_d2i(NULL, (const unsigned char**)&p, ex->value->length, ASN1_ITEM_ptr(met->it)); + st = ASN1_item_d2i(NULL, (const unsigned char**)&p, data->length, ASN1_ITEM_ptr(met->it)); #else st = ASN1_item_d2i(NULL, &p, ex->value->length, ASN1_ITEM_ptr(met->it)); #endif @@ -799,19 +850,12 @@ OCSP_CERTID* createOCSPCertid(X509 *cert, X509* pCACert) { OCSP_CERTID *pId = NULL; X509_NAME *iname; - unsigned char *ikey = NULL; ASN1_INTEGER *sno; - const EVP_MD *dgst; - X509_ALGOR *alg; - unsigned char md[EVP_MAX_MD_SIZE], buf1[100]; - unsigned int len; - int l1; DigiDocMemBuf mbuf1, mbuf2; + AUTHORITY_KEYID *val = NULL; mbuf1.pMem = mbuf2.pMem = NULL; mbuf1.nLen = mbuf2.nLen = 0; - l1 = (int)sizeof(buf1); - memset(buf1, 0, l1); if(cert != NULL) { ddocCertGetSubjectDN(cert, &mbuf1); // standard variant would be @@ -824,48 +868,19 @@ OCSP_CERTID* createOCSPCertid(X509 *cert, X509* pCACert) } else { // CA unknown ddocDebug(3, "createOCSPCertid", "Create ocsp id for cert: %s unknown CA", (char*)mbuf1.pMem); // issuer name hashi arvutamine - iname = X509_get_issuer_name(cert); - dgst = EVP_sha1(); - len = sizeof(md); - if(X509_NAME_digest(iname, dgst, md, &len)) { - // issuer key hashi lugemine - //ikey = get_authority_key(cert->cert_info->extensions); - ikey = get_authority_key_from_cert(cert); - if(ikey != NULL) { - // serial numbri lugemine - sno = X509_get_serialNumber(cert); - // OCSP certid koostamine - if((pId = OCSP_CERTID_new()) != NULL) { - // replace default algorithm ??? - alg = pId->hashAlgorithm; - if(alg->algorithm != NULL) - ASN1_OBJECT_free(alg->algorithm); - alg->algorithm = OBJ_nid2obj(EVP_MD_type(dgst)); - if((alg->parameter = ASN1_TYPE_new()) != NULL) { - alg->parameter->type = V_ASN1_NULL; - ASN1_INTEGER_free(pId->serialNumber); - pId->serialNumber = ASN1_INTEGER_dup(sno); - if(!ASN1_OCTET_STRING_set(pId->issuerNameHash, md, len) || - !ASN1_OCTET_STRING_set(pId->issuerKeyHash, ikey, strlen((const char*)ikey)) || - !pId->serialNumber) - { - fprintf(stderr, "Unable to fill in CID\n"); - OCSP_CERTID_free(pId); - pId = NULL; - } - } // else - failed to create algorithm - } - // cleanup ikey - free(ikey); + val = (AUTHORITY_KEYID*)X509_get_ext_d2i(cert, NID_authority_key_identifier, NULL, NULL ); + if(!val) { + ddocDebug(4, "get_authority_key_from_cert", "Extension not found"); + return(NULL); } - } // else - SHA1 failed + sno = X509_get_serialNumber(cert); + iname = X509_get_issuer_name(cert); + pId = OCSP_cert_id_new(EVP_sha1(), iname, val->keyid, sno); } } ddocMemBuf_free(&mbuf1); ddocMemBuf_free(&mbuf2); - if(pId) - bin2hex((const byte*)pId->issuerKeyHash->data, pId->issuerKeyHash->length, (byte*)buf1, &l1); - ddocDebug(3, "createOCSPCertid", "Created ocsp id %s issuer-key-hash: %s", (pId ? "OK" : "ERR"), buf1); + ddocDebug(3, "createOCSPCertid", "Created ocsp id %s issuer-key-hash", (pId ? "OK" : "ERR")); return pId; } @@ -1310,8 +1325,8 @@ EXP_OPTION int signOCSPRequestPKCS12(OCSP_REQUEST *req, const char* filename, co time(&tNow); err = isCertValid(x509, tNow); #else - if( X509_cmp_current_time(x509->cert_info->validity->notBefore) >= 0 && - X509_cmp_current_time(x509->cert_info->validity->notAfter) <= 0) + if( X509_cmp_current_time(X509_get0_notBefore(x509)) >= 0 && + X509_cmp_current_time(X509_get0_notAfter(x509)) <= 0) err = ERR_CERT_INVALID; #endif if (err != ERR_OK) @@ -1575,8 +1590,6 @@ int verifyOCSPResponse(OCSP_RESPONSE* pResp, int err = ERR_OK; RETURN_IF_NULL_PARAM(pResp); - RETURN_IF_NOT(ASN1_ENUMERATED_get(pResp->responseStatus) == 0, ERR_OCSP_UNSUCCESSFUL); - RETURN_IF_NOT(OBJ_obj2nid(pResp->responseBytes->responseType) == NID_id_pkix_OCSP_basic, ERR_OCSP_UNKNOWN_TYPE); RETURN_IF_NOT(caCerts != NULL, ERR_OCSP_RESP_NOT_TRUSTED); RETURN_IF_NOT(notCert != NULL, ERR_OCSP_CERT_NOTFOUND); RETURN_IF_NOT((bs = OCSP_response_get1_basic(pResp)) != NULL, ERR_OCSP_NO_BASIC_RESP); @@ -1607,61 +1620,61 @@ int verifyOCSPResponse(OCSP_RESPONSE* pResp, int checkNonceAndCertbyOCSP(OCSP_RESPONSE* resp, X509* cert, byte* nonce1, int nonceLen) { - int err = ERR_OK, n; + int err = ERR_OK, n, status = 0; char buf[100]; OCSP_BASICRESP *br = NULL; - OCSP_RESPDATA *rd = NULL; OCSP_SINGLERESP *single = NULL; - OCSP_CERTID *cid = NULL; + const OCSP_CERTID *cid = NULL; X509_EXTENSION *nonce; X509_NAME *iname; unsigned char *ikey; + ASN1_INTEGER *serialNumber = NULL; + ASN1_OCTET_STRING *issuerNameHash = NULL, *issuerKeyHash = NULL, *nonceValue = NULL; RETURN_IF_NULL_PARAM(resp); RETURN_IF_NULL_PARAM(cert); if((br = OCSP_response_get1_basic(resp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); - rd = br->tbsResponseData; - n = sk_OCSP_SINGLERESP_num(rd->responses); + n = OCSP_resp_count(br); RETURN_IF_NOT(n == 1, ERR_OCSP_ONE_RESPONSE); - single = sk_OCSP_SINGLERESP_value(rd->responses, 0); + single = OCSP_resp_get0(br, 0); RETURN_IF_NOT(single, ERR_OCSP_ONE_RESPONSE); - cid = single->certId; + cid = OCSP_SINGLERESP_get0_id(single); RETURN_IF_NULL(cid); - err = handleOCSPCertStatus(single->certStatus->type); + status = OCSP_single_get0_status(single, NULL, NULL, NULL, NULL); + err = handleOCSPCertStatus(status); if(err) SET_LAST_ERROR_RETURN_CODE(err); - if(single->singleExtensions) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT); - if(!rd->responseExtensions || - (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) || - ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) + if((OCSP_BASICRESP_get_ext_count(br) != 1) || + ((nonce = OCSP_BASICRESP_get_ext(br, 0)) == NULL)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); - i2t_ASN1_OBJECT(buf, sizeof(buf), nonce->object); + i2t_ASN1_OBJECT(buf, sizeof(buf), X509_EXTENSION_get_object(nonce)); if(strcmp(buf, OCSP_NONCE_NAME)) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE); // check serial number - if(ASN1_INTEGER_cmp(X509_get_serialNumber(cert), cid->serialNumber) != 0) + OCSP_id_get0_info(&issuerNameHash, NULL, &issuerKeyHash, &serialNumber, (OCSP_CERTID*)cid); + if(ASN1_INTEGER_cmp(X509_get_serialNumber(cert), serialNumber) != 0) SET_LAST_ERROR_RETURN_CODE(ERR_WRONG_CERT); // check issuer name hash iname = X509_get_issuer_name(cert); n = sizeof(buf); X509_NAME_digest(iname, EVP_sha1(), (byte*)buf, (unsigned int*)&n); - err = compareByteArrays((byte*)buf, (unsigned int)n, cid->issuerNameHash->data, cid->issuerNameHash->length); + err = compareByteArrays((byte*)buf, (unsigned int)n, issuerNameHash->data, issuerNameHash->length); RETURN_IF_NOT(err == ERR_OK, err); // check issuer key hash - if((ikey = get_authority_key(cert->cert_info->extensions)) != NULL) { + if((ikey = get_authority_key(X509_get0_extensions(cert))) != NULL) { err = compareByteArrays(ikey, strlen((const char*)ikey), - cid->issuerKeyHash->data, cid->issuerKeyHash->length); + issuerKeyHash->data, issuerKeyHash->length); // cleanup ikey free(ikey); } // verify nonce value - if(nonce->value->length == DIGEST_LEN) - err = compareByteArrays(nonce->value->data, nonce->value->length, nonce1, nonceLen); + nonceValue = X509_EXTENSION_get_data(nonce); + if(nonceValue->length == DIGEST_LEN) + err = compareByteArrays(nonceValue->data, nonceValue->length, nonce1, nonceLen); else - err = compareByteArrays(nonce->value->data + 2, nonce->value->length - 2, nonce1, nonceLen); - ddocDebug(3, "checkNonceAndCertbyOCSP", "nonce1-len: %d nonce2-len: %d err: %d", nonce->value->length, nonceLen, err); + err = compareByteArrays(nonceValue->data + 2, nonceValue->length - 2, nonce1, nonceLen); + ddocDebug(3, "checkNonceAndCertbyOCSP", "nonce1-len: %d nonce2-len: %d err: %d", nonceValue->length, nonceLen, err); if (err != ERR_OK) SET_LAST_ERROR(err); if(br) OCSP_BASICRESP_free(br); diff --git a/libdigidoc/DigiDocObj.c b/libdigidoc/DigiDocObj.c index 4845f3e..6dba29f 100644 --- a/libdigidoc/DigiDocObj.c +++ b/libdigidoc/DigiDocObj.c @@ -35,6 +35,47 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_MD_CTX *EVP_MD_CTX_new() +{ + return (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX)); +} + +static void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + OPENSSL_free(ctx); +} + +static int OCSP_resp_get0_id(const OCSP_BASICRESP *bs, const ASN1_OCTET_STRING **pid, const X509_NAME **pname) +{ + *pid = NULL; + *pname = NULL; + const OCSP_RESPID *rid = bs->tbsResponseData->responderId; + if (rid->type == V_OCSP_RESPID_NAME) + *pname = rid->value.byName; + else if (rid->type == V_OCSP_RESPID_KEY) + *pid = rid->value.byKey; + else + return 0; + return 1; +} + +static const ASN1_GENERALIZEDTIME *OCSP_resp_get0_produced_at(const OCSP_BASICRESP* bs) +{ + return bs->tbsResponseData->producedAt; +} + +static const OCSP_CERTID *OCSP_SINGLERESP_get0_id(const OCSP_SINGLERESP *single) +{ + return single->certId; +} + +static const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) +{ + return bs->signature; +} +#endif + //============================================================ // Sets a string element of a struct to a new value // dest - element pointer @@ -3699,28 +3740,26 @@ int ddocGetOcspRespIdTypeAndValue(OCSP_RESPONSE* pResp, int err = ERR_OK; OCSP_BASICRESP *br = NULL; + const X509_NAME *name = NULL; + const ASN1_OCTET_STRING *id = NULL; RETURN_IF_NULL_PARAM(pResp); RETURN_IF_NULL_PARAM(pType); RETURN_IF_NULL_PARAM(pMbufRespId); if((br = OCSP_response_get1_basic(pResp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); if(!err && br) { - switch(br->tbsResponseData->responderId->type) { - case V_OCSP_RESPID_NAME: - *pType = RESPID_NAME_TYPE; - ddocMemSetLength(pMbufRespId, 300); + OCSP_resp_get0_id(br, &id, &name); + if(name) { + *pType = RESPID_NAME_TYPE; + ddocMemSetLength(pMbufRespId, 300); //X509_NAME_oneline(br->tbsResponseData->responderId->value.byName, (char*)pMbufRespId->pMem, pMbufRespId->nLen); //AM 26.09.08 - err = ddocCertGetDNFromName(br->tbsResponseData->responderId->value.byName, pMbufRespId); + err = ddocCertGetDNFromName((X509_NAME*)name, pMbufRespId); //RETURN_IF_NOT(err == ERR_OK, err); - break; - case V_OCSP_RESPID_KEY: - *pType = RESPID_KEY_TYPE; - err = ddocMemAssignData(pMbufRespId, - (const char*)br->tbsResponseData->responderId->value.byKey->data, - br->tbsResponseData->responderId->value.byKey->length); - break; - default: + } else if(id) { + *pType = RESPID_KEY_TYPE; + err = ddocMemAssignData(pMbufRespId, (const char*)id->data, id->length); + } else { SET_LAST_ERROR(ERR_OCSP_WRONG_RESPID); } } @@ -3800,7 +3839,7 @@ int ddocNotInfo_GetBasicResp(const NotaryInfo* pNotary, OCSP_RESPONSE **ppResp, *ppBasResp = OCSP_response_get1_basic(*ppResp); if(*ppBasResp) { if(ppSingle) - *ppSingle = sk_OCSP_SINGLERESP_value((*ppBasResp)->tbsResponseData->responses, 0); + *ppSingle = OCSP_resp_get0(*ppBasResp, 0); } else return ERR_OCSP_NO_BASIC_RESP; @@ -3818,17 +3857,20 @@ EXP_OPTION const char* ddocNotInfo_GetResponderId_Type(const NotaryInfo* pNotary int err = ERR_OK; OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; + const ASN1_OCTET_STRING *id = NULL; + const X509_NAME *name = NULL; char *p1 = RESPID_NAME_VALUE; // default value is name - usefull in format 1.0 where we had no good OCSP response RETURN_OBJ_IF_NULL(pNotary, NULL); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, NULL); if(!err && br) { - switch(br->tbsResponseData->responderId->type) { - case V_OCSP_RESPID_NAME: p1 = RESPID_NAME_VALUE; break; - case V_OCSP_RESPID_KEY: p1 = RESPID_KEY_VALUE; break; - default: + OCSP_resp_get0_id(br, &id, &name); + if(name) + p1 = RESPID_NAME_VALUE; + else if(id) + p1 = RESPID_KEY_VALUE; + else SET_LAST_ERROR(ERR_OCSP_WRONG_RESPID); - } } if(pResp) OCSP_RESPONSE_free(pResp); @@ -3850,15 +3892,17 @@ EXP_OPTION int ddocNotInfo_GetThisUpdate(const NotaryInfo* pNotary, DigiDocMemBu OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; + ASN1_GENERALIZEDTIME *thisUpdate = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBuf); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, &single); if(!err && br && single) { err = ddocMemSetLength(pMBuf, 50); - ddocDebug(3, "ddocNotInfo_GetThisUpdate", "This update: %s", single->thisUpdate); - if(!err && single->thisUpdate) - err = asn1time2str(NULL, single->thisUpdate, (char*)pMBuf->pMem, pMBuf->nLen); + OCSP_single_get0_status(single, NULL, NULL, &thisUpdate, NULL); + ddocDebug(3, "ddocNotInfo_GetThisUpdate", "This update: %s", thisUpdate); + if(!err && thisUpdate) + err = asn1time2str(NULL, thisUpdate, (char*)pMBuf->pMem, pMBuf->nLen); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -3881,13 +3925,15 @@ int ddocNotInfo_GetThisUpdate_timet(const NotaryInfo* pNotary, time_t* pTime) OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; + ASN1_GENERALIZEDTIME *thisUpdate = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pTime); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, &single); if(!err && br && single) { - if(!err && single->thisUpdate) - err = asn1time2time_t_local(single->thisUpdate, pTime); + OCSP_single_get0_status(single, NULL, NULL, &thisUpdate, NULL); + if(!err && thisUpdate) + err = asn1time2time_t_local(thisUpdate, pTime); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -3908,13 +3954,14 @@ int ddocNotInfo_GetProducedAt_timet(const NotaryInfo* pNotary, time_t* pTime) int err = ERR_OK; OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; - + const ASN1_GENERALIZEDTIME *producedAt = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pTime); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, NULL); - if(!err && br && br->tbsResponseData && br->tbsResponseData->producedAt) { - err = asn1time2time_t_local(br->tbsResponseData->producedAt, pTime); + producedAt = OCSP_resp_get0_produced_at(br); + if(!err && br && producedAt) { + err = asn1time2time_t_local((ASN1_GENERALIZEDTIME*)producedAt, pTime); } //AM 22.06.08 lets free br too if(br) @@ -3954,14 +4001,16 @@ EXP_OPTION int ddocNotInfo_GetNextUpdate(const NotaryInfo* pNotary, DigiDocMemBu OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; + ASN1_GENERALIZEDTIME *nextUpdate = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBuf); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, &single); if(!err && br && single) { err = ddocMemSetLength(pMBuf, 50); - if(!err && single->nextUpdate) - err = asn1time2str(NULL, single->nextUpdate, (char*)pMBuf->pMem, pMBuf->nLen); + OCSP_single_get0_status(single, NULL, NULL, NULL, &nextUpdate); + if(!err && nextUpdate) + err = asn1time2str(NULL, nextUpdate, (char*)pMBuf->pMem, pMBuf->nLen); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -3983,13 +4032,17 @@ int ddocNotInfo_GetIssuerNameHash(const NotaryInfo* pNotary, DigiDocMemBuf* pMBu OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; + ASN1_OCTET_STRING *issuerNameHash = NULL; + const OCSP_CERTID *cid = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBuf); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, &single); - if(!err && br && single->certId) { - err = ddocMemAssignData(pMBuf, (const char*)single->certId->issuerNameHash->data, - single->certId->issuerNameHash->length); + if(!err && br) { + cid = OCSP_SINGLERESP_get0_id(OCSP_resp_get0(br, 0)); + OCSP_id_get0_info(&issuerNameHash, NULL, NULL, NULL, (OCSP_CERTID*)cid); + err = ddocMemAssignData(pMBuf, (const char*)issuerNameHash->data, + issuerNameHash->length); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -4011,13 +4064,18 @@ int ddocNotInfo_GetIssuerKeyHash(const NotaryInfo* pNotary, DigiDocMemBuf* pMBuf OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; + ASN1_OCTET_STRING *issuerKeyHash = NULL; + const OCSP_CERTID *cid = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBuf); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, &single); - if(!err && br && single->certId) { - err = ddocMemAssignData(pMBuf, (const char*)single->certId->issuerKeyHash->data, - single->certId->issuerKeyHash->length); + + if(!err && br) { + cid = OCSP_SINGLERESP_get0_id(OCSP_resp_get0(br, 0)); + OCSP_id_get0_info(NULL, NULL, &issuerKeyHash, NULL, (OCSP_CERTID*)cid); + err = ddocMemAssignData(pMBuf, (const char*)issuerKeyHash->data, + issuerKeyHash->length); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -4040,6 +4098,7 @@ int ddocNotInfo_GetOcspRealDigest(const SignedDoc* pSigDoc, const NotaryInfo* pN OCSP_BASICRESP *br = NULL; OCSP_SINGLERESP *single = NULL; X509_EXTENSION *ext = NULL; + ASN1_OCTET_STRING *value = NULL; byte* p = 0, buf2[DIGEST_LEN256 * 2 + 2]; RETURN_IF_NULL_PARAM(pNotary); @@ -4051,8 +4110,9 @@ int ddocNotInfo_GetOcspRealDigest(const SignedDoc* pSigDoc, const NotaryInfo* pN if(nIdx >= 0) { ext = OCSP_BASICRESP_get_ext(br, nIdx); if(ext != NULL) { - int l1 = ASN1_STRING_length(ext->value); - p = ASN1_STRING_data(ext->value); + value = X509_EXTENSION_get_data(ext); + int l1 = ASN1_STRING_length(value); + p = ASN1_STRING_data(value); if(l1 > 20 && p[0] == V_ASN1_OCTET_STRING && p[1] == l1-2) err = ddocMemAssignData(pMBuf, (const char*)p+2, l1-2); else @@ -4093,13 +4153,15 @@ int ddocNotInfo_GetOcspSignatureValue(const NotaryInfo* pNotary, DigiDocMemBuf* int err = ERR_OK; OCSP_RESPONSE *pResp = 0; OCSP_BASICRESP *br = NULL; + const ASN1_OCTET_STRING *signature = NULL; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBuf); err = ddocNotInfo_GetBasicResp(pNotary, &pResp, &br, NULL); if(!err && br) { - err = ddocMemAssignData(pMBuf, (const char*)br->signature->data, - br->signature->length); + signature = OCSP_resp_get0_signature(br); + err = ddocMemAssignData(pMBuf, (const char*)signature->data, + signature->length); } if(pResp) OCSP_RESPONSE_free(pResp); @@ -4328,7 +4390,7 @@ EXP_OPTION int calculateSignatureWithPkcs12(SignedDoc* pSigDoc, SignatureInfo* p int l2; EVP_PKEY *pkey = 0; X509* x509 = 0; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; DigiDocMemBuf mbuf1; RETURN_IF_NULL_PARAM(pSigInfo); @@ -4397,9 +4459,11 @@ EXP_OPTION int calculateSignatureWithPkcs12(SignedDoc* pSigDoc, SignatureInfo* p sigLen = sizeof(signature); memset(signature, 0, sizeof(signature)); // sign data - EVP_SignInit(&ctx, EVP_sha1()); - EVP_SignUpdate(&ctx, buf1, (unsigned long)strlen(buf1)); - err = EVP_SignFinal(&ctx, signature, &sigLen, pkey); + ctx = EVP_MD_CTX_new(); + EVP_SignInit(ctx, EVP_sha1()); + EVP_SignUpdate(ctx, buf1, (unsigned long)strlen(buf1)); + err = EVP_SignFinal(ctx, signature, &sigLen, pkey); + EVP_MD_CTX_free(ctx); free(buf1); if(err == ERR_LIB_NONE) err = ERR_OK; diff --git a/libdigidoc/DigiDocSAXParser.c b/libdigidoc/DigiDocSAXParser.c index 0bebe63..4aa46e9 100644 --- a/libdigidoc/DigiDocSAXParser.c +++ b/libdigidoc/DigiDocSAXParser.c @@ -56,6 +56,18 @@ static char g_szDataFileFlush2[] = ""; #include #endif +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_ENCODE_CTX *EVP_ENCODE_CTX_new() +{ + return (EVP_ENCODE_CTX*)OPENSSL_malloc(sizeof(EVP_ENCODE_CTX)); +} + +static void EVP_ENCODE_CTX_free(EVP_ENCODE_CTX *ctx) +{ + OPENSSL_free(ctx); +} +#endif + extern int ddocCheckFormatAndVer(const char* format, const char* version); extern char* canonicalizeXML(char* source, int len); extern int escapeXMLSymbols(const char* src, int srclen, char** dest); @@ -79,7 +91,7 @@ typedef struct SigDocParse_st { char ctx4[300]; char ctx5[300]; BIO* bDataFile; - EVP_ENCODE_CTX ectx; + EVP_ENCODE_CTX *ectx; SHA_CTX sctx, sctx2; // sha1 digest context and alternat dig context int errcode; char* szInputFileName; @@ -405,7 +417,8 @@ void handleStartDataFile(SigDocParse* pctx, const xmlChar *name, const xmlChar * strncpy(pctx->ctx2, id, sizeof(pctx->ctx2)-1); ddocDebug(4, "handleStartDataFile", "Start DF: %s", id); if(ctype && !strcmp(ctype, CONTENT_EMBEDDED_BASE64)) { - EVP_DecodeInit(&(pctx->ectx)); + pctx->ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(pctx->ectx); ddocDebug(3, "handleStartDataFile", "Init sha1"); SHA1_Init(&(pctx->sctx)); SHA1_Init(&(pctx->sctx2)); @@ -494,7 +507,7 @@ void handleDataFile(SigDocParse* pctx, const xmlChar *value, int len) i = (i + 512 > len) ? len : i + 512; l = sizeof(buf); memset(buf, 0, sizeof(buf)); - EVP_DecodeUpdate(&(pctx->ectx), (unsigned char*)buf, &l, (unsigned char*)value + j, i - j); + EVP_DecodeUpdate(pctx->ectx, (unsigned char*)buf, &l, (unsigned char*)value + j, i - j); BIO_write(pctx->bDataFile, buf, l); j = i; } @@ -506,7 +519,7 @@ void handleDataFile(SigDocParse* pctx, const xmlChar *value, int len) i = (i + 512 > len) ? len : i + 512; l = sizeof(buf); memset(buf, 0, sizeof(buf)); - EVP_DecodeUpdate(&(pctx->ectx), (unsigned char*)buf, &l, (unsigned char*)value + j, i - j); + EVP_DecodeUpdate(pctx->ectx, (unsigned char*)buf, &l, (unsigned char*)value + j, i - j); if(pctx->bDataFile) BIO_write(pctx->bDataFile, buf, l); buf[l] = 0; @@ -553,7 +566,8 @@ void handleEndDataFile(SigDocParse* pctx, const xmlChar *name) if(pctx->bDataFile && !strcmp(pDf->szContentType, CONTENT_EMBEDDED_BASE64)) { l1 = sizeof(buf); - EVP_DecodeFinal(&(pctx->ectx), (unsigned char*)buf, &l1); + EVP_DecodeFinal(pctx->ectx, (unsigned char*)buf, &l1); + EVP_ENCODE_CTX_free(pctx->ectx); BIO_write(pctx->bDataFile, buf, l1); BIO_free(pctx->bDataFile); pctx->bDataFile = NULL; @@ -2135,7 +2149,8 @@ static void extractStartElementHandler(void *ctx, const xmlChar *name, const xml ddocDebug(4, "extractStartElementHandler", "Init collecting DF: %s mode: %s", pctx->ctx3, pctx->ctx1); if(!strcmp(pctx->ctx4, CONTENT_EMBEDDED_BASE64) && !pctx->bKeepBase64) { - EVP_DecodeInit(&(pctx->ectx)); + pctx->ectx = EVP_ENCODE_CTX_new(); + EVP_DecodeInit(pctx->ectx); pctx->b64pos = 0; pctx->lSize = 0; } @@ -2259,7 +2274,7 @@ void extractDecodeB64(SigDocParse* pctx, const char* ch, int len, int lastBlock) j = sizeof(decData); memset(decData, 0, j); ddocDebug(5, "extractDecodeB64", "decoding: %s", pctx->b64line); - EVP_DecodeUpdate(&(pctx->ectx), (unsigned char*)decData, &j, + EVP_DecodeUpdate(pctx->ectx, (unsigned char*)decData, &j, (unsigned char*)pctx->b64line, pctx->b64pos + 1); ddocDebug(4, "extractDecodeB64", "decoding: %d -> got: %d", pctx->b64pos, j); if(pctx->pMemBufDF) @@ -2273,7 +2288,8 @@ void extractDecodeB64(SigDocParse* pctx, const char* ch, int len, int lastBlock) if(l == len && lastBlock) { j = sizeof(decData); memset(decData, 0, j); - EVP_DecodeFinal(&(pctx->ectx), (unsigned char*)decData, &j); + EVP_DecodeFinal(pctx->ectx, (unsigned char*)decData, &j); + EVP_ENCODE_CTX_free(pctx->ectx); ddocDebug(4, "extractDecodeB64", "decoding final got: %d", j); if(j > 0) { if(pctx->pMemBufDF) diff --git a/libdigidoc/DigiDocVerify.c b/libdigidoc/DigiDocVerify.c index 237e285..7a8e82b 100644 --- a/libdigidoc/DigiDocVerify.c +++ b/libdigidoc/DigiDocVerify.c @@ -47,6 +47,28 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x10010000L +static EVP_MD_CTX *EVP_MD_CTX_new() +{ + return (EVP_MD_CTX*)OPENSSL_malloc(sizeof(EVP_MD_CTX)); +} + +static void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + OPENSSL_free(ctx); +} + +static const ASN1_OCTET_STRING *OCSP_resp_get0_signature(const OCSP_BASICRESP *bs) +{ + return bs->signature; +} + +static X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) +{ + return ctx->param; +} +#endif + //--------------------< ddoc structure def >----------------------- const XmlElemDef eTransform = {"Transform", 'Y', NULL}; /* 1.0 */ @@ -393,7 +415,7 @@ EXP_OPTION int verifyFileSignature(const char* szFileName, int nDigestType, const char *certfile) { int err = ERR_OK; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; unsigned char buf[FILE_BUFSIZE]; int i; FILE *f; @@ -406,13 +428,15 @@ EXP_OPTION int verifyFileSignature(const char* szFileName, int nDigestType, if(nDigestType == DIGEST_SHA1) { if((err = ReadPublicKey(&pkey, certfile)) == ERR_OK) { if((f = fopen(szFileName,"rb")) != NULL) { - EVP_VerifyInit(&ctx, EVP_sha1()); + ctx = EVP_MD_CTX_new(); + EVP_VerifyInit(ctx, EVP_sha1()); for (;;) { i = fread(buf, sizeof(char), FILE_BUFSIZE, f); if (i <= 0) break; - EVP_VerifyUpdate (&ctx, buf, (unsigned long)i); + EVP_VerifyUpdate (ctx, buf, (unsigned long)i); } - err = EVP_VerifyFinal(&ctx, pSigBuf, nSigLen, pkey); + err = EVP_VerifyFinal(ctx, pSigBuf, nSigLen, pkey); + EVP_MD_CTX_free(ctx); if(err == ERR_LIB_NONE) err = ERR_OK; fclose(f); @@ -447,7 +471,7 @@ EXP_OPTION int verifySignature(const char* szData, unsigned long dataLen, int nD byte* pSigBuf, int nSigLen, X509* cert) { int err = ERR_OK; - EVP_MD_CTX ctx; + EVP_MD_CTX *ctx; EVP_PKEY* pkey = NULL; RETURN_IF_NULL_PARAM(szData); @@ -457,11 +481,13 @@ EXP_OPTION int verifySignature(const char* szData, unsigned long dataLen, int nD if(nDigestType == DIGEST_SHA1) { if((err = GetPublicKey(&pkey, cert)) == ERR_OK) { checkErrors(); - EVP_VerifyInit(&ctx, EVP_sha1()); + ctx = EVP_MD_CTX_new(); + EVP_VerifyInit(ctx, EVP_sha1()); checkErrors(); - EVP_VerifyUpdate (&ctx, szData, dataLen); + EVP_VerifyUpdate (ctx, szData, dataLen); checkErrors(); - err = EVP_VerifyFinal(&ctx, pSigBuf, nSigLen, pkey); + err = EVP_VerifyFinal(ctx, pSigBuf, nSigLen, pkey); + EVP_MD_CTX_free(ctx); if(err == ERR_LIB_NONE) err = ERR_OK; checkErrors(); @@ -536,6 +562,7 @@ EXP_OPTION int verifyEstIDSignature(const byte* digest, int digestLen, int nDige { int err = ERR_OK, nCheckSigValAsn1 = 1; EVP_PKEY* pkey = 0; + RSA *rsa = 0; byte buf2[DIGEST_LEN+2], buf3[500], buf4[200], buf5[200],buf256[DIGEST_LEN256+2]; int l2 = 0, l1; //AM 11.02.09 ecdsa-sha1 support for LI @@ -578,9 +605,11 @@ EXP_OPTION int verifyEstIDSignature(const byte* digest, int digestLen, int nDige } }else #endif - if(pkey->type==NID_rsaEncryption){ + if(EVP_PKEY_base_id(pkey)==EVP_PKEY_RSA){ //clearErrors(); - l2 = RSA_public_decrypt(nSigLen, pSigBuf, buf3, pkey->pkey.rsa, RSA_PKCS1_PADDING); //RSA_PKCS1_PADDING); //RSA_NO_PADDING); + rsa = EVP_PKEY_get1_RSA(pkey); + l2 = RSA_public_decrypt(nSigLen, pSigBuf, buf3, rsa, RSA_PKCS1_PADDING); //RSA_PKCS1_PADDING); //RSA_NO_PADDING); + RSA_free(rsa); checkErrors(); ddocDebug(3, "verifyEstIDSignature", "decryted sig-hash len: %d", l2); // debug info @@ -628,7 +657,9 @@ EXP_OPTION int verifyEstIDSignature(const byte* digest, int digestLen, int nDige memset(buf3, 0, sizeof(buf3)); ERR_clear_error(); //swapBytes(pSigBuf, nSigLen); - l2 = RSA_public_decrypt(nSigLen, pSigBuf, buf3, pkey->pkey.rsa, RSA_PKCS1_PADDING); //RSA_PKCS1_PADDING); //RSA_NO_PADDING); + rsa = EVP_PKEY_get1_RSA(pkey); + l2 = RSA_public_decrypt(nSigLen, pSigBuf, buf3, rsa, RSA_PKCS1_PADDING); //RSA_PKCS1_PADDING); //RSA_NO_PADDING); + RSA_free(rsa); checkErrors(); ddocDebug(3, "verifyEstIDSignature", "decryted sig-hash len: %d", l2); // debug info @@ -1163,10 +1194,11 @@ X509_ALGOR* setSignAlgorithm(const EVP_MD * type) /*if ((nid = EVP_MD_type(type)) != NID_undef) { alg->algorithm=OBJ_nid2obj(nid); }*/ - alg->algorithm = OBJ_nid2obj(type->pkey_type); + alg->algorithm = OBJ_nid2obj(EVP_MD_pkey_type(type)); return alg; } +#if OPENSSL_VERSION_NUMBER < 0x10010000L //-------------------------------------------------- // Helper function. Converts Notary info to an OCSP // response structure. Used in verify and file writing @@ -1268,6 +1300,7 @@ int notary2ocspBasResp(const SignedDoc* pSigDoc, const NotaryInfo* pNotInfo, X50 // checkErrors(); return ERR_OK; } +#endif //-------------------------------------------------- // Verfies NotaryInfo signature @@ -1375,20 +1408,18 @@ int verifyOcspCertId(OCSP_RESPONSE* pResp, X509* pCert, X509* pCaCert) OCSP_CERTID *cid = NULL; int err = ERR_OK; DigiDocMemBuf mbuf1, mbuf2, mbuf3; + ASN1_OCTET_STRING *issuerNameHash = NULL, *issuerKeyHash = NULL; + ASN1_INTEGER *serialNumber = NULL; RETURN_IF_NULL_PARAM(pResp); RETURN_IF_NULL_PARAM(pCert); RETURN_IF_NULL_PARAM(pCaCert); - RETURN_IF_NULL_PARAM(pResp->responseBytes); mbuf1.pMem = 0; mbuf1.nLen = 0; mbuf2.pMem = 0; mbuf2.nLen = 0; mbuf3.pMem = 0; mbuf3.nLen = 0; - rb = pResp->responseBytes; - if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE); if((br = OCSP_response_get1_basic(pResp)) == NULL) SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP); ddocCertGetSubjectDN(pCert, &mbuf2); @@ -1396,28 +1427,22 @@ int verifyOcspCertId(OCSP_RESPONSE* pResp, X509* pCert, X509* pCaCert) ddocDebug(4, "verifyOcspCertId", "for cert: %ld, cn: %s, ca: %s", X509_get_serialNumber(pCert), mbuf2.pMem, mbuf3.pMem); ddocMemBuf_free(&mbuf2); ddocMemBuf_free(&mbuf3); - rd = br->tbsResponseData; - if(ASN1_INTEGER_get(rd->version) != 0) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION); - if(sk_OCSP_SINGLERESP_num(rd->responses) != 1) - SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE); - single = sk_OCSP_SINGLERESP_value(rd->responses, 0); - RETURN_IF_NULL(single); - cid = single->certId; + cid = OCSP_cert_to_id(EVP_sha1(), pCert, pCaCert); RETURN_IF_NULL(cid); + OCSP_id_get0_info(&issuerNameHash, NULL, &issuerKeyHash, &serialNumber, cid); // check serial number - if(ASN1_INTEGER_cmp(cid->serialNumber, X509_get_serialNumber(pCert)) != 0) { + if(ASN1_INTEGER_cmp(serialNumber, X509_get_serialNumber(pCert)) != 0) { ddocDebug(4, "verifyOcspCertId", "Looking for cert-nr: %ld buf found %ld", - X509_get_serialNumber(pCert), ASN1_INTEGER_get(cid->serialNumber)); + X509_get_serialNumber(pCert), ASN1_INTEGER_get(serialNumber)); return ERR_WRONG_CERT; } // check issuer name hash err = ddocCertGetIssuerNameDigest(pCert, &mbuf1); RETURN_IF_NOT(err == ERR_OK, err); err = compareByteArrays((byte*)mbuf1.pMem, (unsigned int)mbuf1.nLen, - cid->issuerNameHash->data, cid->issuerNameHash->length); - mbuf2.pMem = cid->issuerNameHash->data; - mbuf2.nLen = cid->issuerNameHash->length; + issuerNameHash->data, issuerNameHash->length); + mbuf2.pMem = issuerNameHash->data; + mbuf2.nLen = issuerNameHash->length; ddocBin2Hex(&mbuf2, &mbuf3); mbuf2.pMem = 0; mbuf2.nLen = 0; @@ -1432,9 +1457,9 @@ int verifyOcspCertId(OCSP_RESPONSE* pResp, X509* pCert, X509* pCaCert) err = ddocCertGetPubkeyDigest(pCaCert, &mbuf1); RETURN_IF_NOT(err == ERR_OK, err); err = compareByteArrays((byte*)mbuf1.pMem, (unsigned int)mbuf1.nLen, - cid->issuerKeyHash->data, cid->issuerKeyHash->length); - mbuf2.pMem = cid->issuerKeyHash->data; - mbuf2.nLen = cid->issuerKeyHash->length; + issuerKeyHash->data, issuerKeyHash->length); + mbuf2.pMem = issuerKeyHash->data; + mbuf2.nLen = issuerKeyHash->length; ddocBin2Hex(&mbuf2, &mbuf3); mbuf2.pMem = 0; mbuf2.nLen = 0; @@ -1482,6 +1507,7 @@ EXP_OPTION int verifyNotaryInfoCERT2(const SignedDoc* pSigDoc, X509_STORE *store; OCSP_RESPONSE* pResp = NULL; OCSP_BASICRESP* bs = NULL; + ASN1_OCTET_STRING *signature = NULL; STACK_OF(X509)* ver_certs = NULL; int err = ERR_OK, l1; X509 *certNotaryDirectCA = 0, *pCert = 0, *pCaCert = 0; @@ -1516,7 +1542,7 @@ EXP_OPTION int verifyNotaryInfoCERT2(const SignedDoc* pSigDoc, //WriteOCSPResponse("test2.resp", pResp); if((setup_verifyCERT(&store, CApath, caCerts)) == ERR_OK) { ddocNotInfo_GetProducedAt_timet(pNotInfo, &tProdAt); - X509_VERIFY_PARAM_set_time(store->param, tProdAt); + X509_VERIFY_PARAM_set_time(X509_STORE_get0_param(store), tProdAt); X509_STORE_set_flags(store, X509_V_FLAG_USE_CHECK_TIME); // new basic response // create OCSP basic response @@ -1531,10 +1557,11 @@ EXP_OPTION int verifyNotaryInfoCERT2(const SignedDoc* pSigDoc, sk_X509_push(ver_certs, notCert); ddocDebug(3, "verifyNotaryInfoCERT", "OCSP verify err: %d, err1: %d format: %s", err, pSigInfo->nErr1, pSigDoc->szFormatVer); // fix invalid padding flag on ddoc 1.0 signatures + signature = (ASN1_OCTET_STRING*)OCSP_resp_get0_signature(bs); if((!strcmp(pSigDoc->szFormatVer, SK_XML_1_VER) && !strcmp(pSigDoc->szFormat, SK_XML_1_NAME)) - || (bs->signature->flags & 0x07)) { - ddocDebug(3, "verifyNotaryInfoCERT", "Reset ocsp flag %d", bs->signature->flags); - bs->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); + || (signature->flags & 0x07)) { + ddocDebug(3, "verifyNotaryInfoCERT", "Reset ocsp flag %d", signature->flags); + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); } err = OCSP_basic_verify(bs, ver_certs, store, OCSP_NOCHECKS); ddocDebug(3, "verifyNotaryInfoCERT", "OCSP verify: %d, not cet: %s cn: %s", err, buf1, mbuf1.pMem); diff --git a/libdigidoc/cdigidoc.rc b/libdigidoc/cdigidoc.rc index 3267c28..0cace7b 100644 --- a/libdigidoc/cdigidoc.rc +++ b/libdigidoc/cdigidoc.rc @@ -25,14 +25,14 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "Estonian ID Card\0" - VALUE "FileDescription", "cdigidoc\0" - VALUE "FileVersion", VERSION "\0" - VALUE "InternalName", "cdigidoc\0" - VALUE "LegalCopyright", "Copyright (C) 2009-2012 Estonian ID Card" - VALUE "OriginalFilename", "cdigidoc.exe\0" - VALUE "ProductName", "cdigidoc\0" - VALUE "ProductVersion", VERSION "\0" + VALUE "CompanyName", "RIA" + VALUE "FileDescription", "cdigidoc" + VALUE "FileVersion", VERSION + VALUE "InternalName", "cdigidoc" + VALUE "LegalCopyright", "Copyright (C) 2009-2018 Estonian Information System Authority" + VALUE "OriginalFilename", "cdigidoc.exe" + VALUE "ProductName", "cdigidoc" + VALUE "ProductVersion", VERSION END END BLOCK "VarFileInfo" diff --git a/libdigidoc/libdigidoc.rc b/libdigidoc/libdigidoc.rc index 7338b52..858778d 100644 --- a/libdigidoc/libdigidoc.rc +++ b/libdigidoc/libdigidoc.rc @@ -25,14 +25,14 @@ BEGIN BEGIN BLOCK "040904E4" BEGIN - VALUE "CompanyName", "Estonian ID Card\0" - VALUE "FileDescription", "libdigidoc\0" - VALUE "FileVersion", VERSION "\0" - VALUE "InternalName", "libdigidoc\0" - VALUE "LegalCopyright", "Copyright (C) 2009-2012 Estonian ID Card" - VALUE "OriginalFilename", "libdigidoc.dll\0" - VALUE "ProductName", "libdigidoc\0" - VALUE "ProductVersion", VERSION "\0" + VALUE "CompanyName", "RIA" + VALUE "FileDescription", "libdigidoc" + VALUE "FileVersion", VERSION + VALUE "InternalName", "libdigidoc" + VALUE "LegalCopyright", "Copyright (C) 2009-2018 Estonian Information System Authority" + VALUE "OriginalFilename", "libdigidoc.dll" + VALUE "ProductName", "libdigidoc" + VALUE "ProductVersion", VERSION END END BLOCK "VarFileInfo" -- cgit v1.2.3