Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
onlyoffice_core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boris Kocherov
onlyoffice_core
Commits
907e00a3
Commit
907e00a3
authored
Jun 09, 2017
by
Oleg Korshul
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
2470bfd3
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
743 additions
and
554 deletions
+743
-554
DesktopEditor/xmlsec/src/include/XmlCertificate.h
DesktopEditor/xmlsec/src/include/XmlCertificate.h
+36
-4
DesktopEditor/xmlsec/src/ooxmlsignature.pro
DesktopEditor/xmlsec/src/ooxmlsignature.pro
+22
-4
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.cpp
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.cpp
+663
-0
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.h
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.h
+22
-546
No files found.
DesktopEditor/xmlsec/src/include/XmlCertificate.h
View file @
907e00a3
...
...
@@ -8,6 +8,11 @@
#define OOXML_HASH_ALG_SHA1 0
#define OOXML_HASH_ALG_INVALID 1
#define OPEN_SSL_WARNING_OK 0
#define OPEN_SSL_WARNING_ERR 1
#define OPEN_SSL_WARNING_ALL_OK 2
#define OPEN_SSL_WARNING_PASS 4
class
ICertificate
;
class
Q_DECL_EXPORT
ICertificateSelectDialogOpenSsl
{
...
...
@@ -32,7 +37,7 @@ public:
class
Q_DECL_EXPORT
CCertificateInfo
{
p
ublic
:
p
rivate
:
std
::
wstring
m_name
;
std
::
string
m_date
;
std
::
string
m_id
;
...
...
@@ -44,6 +49,33 @@ public:
~
CCertificateInfo
()
{
}
std
::
wstring
GetName
()
{
return
m_name
;
}
void
SetName
(
const
std
::
wstring
&
name
)
{
m_name
=
name
;
}
std
::
string
GetDate
()
{
return
m_date
;
}
void
SetDate
(
const
std
::
string
&
date
)
{
m_date
=
date
;
}
std
::
string
GetId
()
{
return
m_id
;
}
void
SetId
(
const
std
::
string
&
id
)
{
m_id
=
id
;
}
};
class
Q_DECL_EXPORT
ICertificate
...
...
@@ -88,9 +120,9 @@ public:
virtual
CCertificateInfo
GetInfo
()
{
CCertificateInfo
info
;
info
.
m_name
=
GetSignerName
(
);
info
.
m_date
=
GetDate
(
);
info
.
m_id
=
GetId
(
);
info
.
SetName
(
GetSignerName
()
);
info
.
SetDate
(
GetDate
()
);
info
.
SetId
(
GetId
()
);
return
info
;
}
...
...
DesktopEditor/xmlsec/src/ooxmlsignature.pro
View file @
907e00a3
...
...
@@ -21,6 +21,13 @@ include($$CORE_ROOT_DIR/DesktopEditor/xml/build/qt/libxml2.pri)
DEFINES
-=
UNICODE
core_linux
{
CONFIG
+=
signature_openssl
}
core_mac
{
CONFIG
+=
signature_openssl
}
HEADERS
+=
\
include
/
XmlCertificate
.
h
\
include
/
OOXMLSigner
.
h
\
...
...
@@ -29,9 +36,7 @@ HEADERS += \
HEADERS
+=
\
src
/
XmlCanonicalizator
.
h
\
src
/
XmlRels
.
h
\
src
/
XmlTransform
.
h
\
src
/
XmlSigner_mscrypto
.
h
\
src
/
XmlSigner_openssl
.
h
src
/
XmlTransform
.
h
SOURCES
+=
\
src
/
XmlTransform
.
cpp
\
...
...
@@ -41,13 +46,26 @@ SOURCES += \
core_windows
{
HEADERS
+=
\
src
/
XmlSigner_mscrypto
.
h
LIBS
+=
-
lcrypt32
LIBS
+=
-
lcryptui
LIBS
+=
-
lAdvapi32
}
core_linux
{
signature_openssl
{
HEADERS
+=
\
src
/
XmlSigner_openssl
.
h
SOURCES
+=
\
src
/
XmlSigner_openssl
.
cpp
}
signature_openssl
{
DEFINES
+=
XMLSEC_OPENSSL_110
INCLUDEPATH
+=
$$
CORE_ROOT_DIR
/
Common
/
3
dParty
/
openssl
/
openssl
/
include
...
...
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.cpp
0 → 100644
View file @
907e00a3
#include "./XmlSigner_openssl.h"
#include "../../../common/File.h"
#include "../../../common/String.h"
#include "../../../common/BigInteger.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/pkcs12.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
class
CCertificate_openssl_private
{
protected:
ICertificateSelectDialogOpenSsl
*
m_pDialog
;
X509
*
m_cert
;
EVP_PKEY
*
m_key
;
public:
ICertificate
*
m_pBase
;
public:
CCertificate_openssl_private
()
{
m_pDialog
=
NULL
;
m_cert
=
NULL
;
m_key
=
NULL
;
m_pBase
=
NULL
;
}
virtual
~
CCertificate_openssl_private
()
{
if
(
NULL
!=
m_cert
)
X509_free
(
m_cert
);
if
(
NULL
!=
m_key
)
EVP_PKEY_free
(
m_key
);
}
public:
std
::
string
GetNumber
()
{
if
(
NULL
==
m_cert
)
return
""
;
ASN1_INTEGER
*
asn1_serial
=
X509_get_serialNumber
(
m_cert
);
if
(
asn1_serial
==
NULL
)
return
""
;
BIGNUM
*
bn
=
ASN1_INTEGER_to_BN
(
asn1_serial
,
NULL
);
if
(
!
bn
)
{
ASN1_INTEGER_free
(
asn1_serial
);
return
""
;
}
char
*
tmp
=
BN_bn2dec
(
bn
);
std
::
string
sReturn
(
tmp
);
BN_free
(
bn
);
ASN1_INTEGER_free
(
asn1_serial
);
return
sReturn
;
}
std
::
wstring
GetSignerName
()
{
if
(
NULL
==
m_cert
)
return
L""
;
X509_NAME
*
name
=
X509_get_issuer_name
(
m_cert
);
char
*
utf_8_name
=
X509_NAME_oneline
(
name
,
NULL
,
0
);
std
::
string
sName
(
utf_8_name
);
std
::
wstring
sNameW
=
UTF8_TO_U
(
sName
);
OPENSSL_free
(
utf_8_name
);
return
sNameW
;
}
std
::
string
GetCertificateBase64
()
{
if
(
NULL
==
m_cert
)
return
""
;
BIO
*
bio
=
BIO_new
(
BIO_s_mem
());
PEM_write_bio_X509_AUX
(
bio
,
m_cert
);
unsigned
char
*
data
;
unsigned
int
len
=
0
;
len
=
BIO_get_mem_data
(
bio
,
&
data
);
std
::
string
sReturn
((
char
*
)
data
,
(
size_t
)
len
);
BIO_free
(
bio
);
return
sReturn
;
}
std
::
string
GetCertificateHash
()
{
std
::
string
sBase64
=
GetCertificateBase64
();
BYTE
*
pData
=
NULL
;
int
nLen
=
0
;
if
(
NSFile
::
CBase64Converter
::
Decode
(
sBase64
.
c_str
(),
(
int
)
sBase64
.
length
(),
pData
,
nLen
))
{
std
::
string
sHash
=
GetHash
(
pData
,
(
unsigned
int
)
nLen
,
OOXML_HASH_ALG_SHA1
);
RELEASEARRAYOBJECTS
(
pData
);
return
sHash
;
}
return
""
;
}
std
::
string
GetDate
()
{
if
(
NULL
==
m_cert
)
return
""
;
ASN1_TIME
*
_time1
=
X509_get_notBefore
(
m_cert
);
struct
tm
t1
=
this
->
ASN1_GetTimeT
(
_time1
);
ASN1_TIME_free
(
_time1
);
ASN1_TIME
*
_time2
=
X509_get_notAfter
(
m_cert
);
struct
tm
t2
=
this
->
ASN1_GetTimeT
(
_time2
);
ASN1_TIME_free
(
_time2
);
std
::
string
sRet
=
std
::
to_string
(
t1
.
tm_mday
)
+
"/"
+
std
::
to_string
(
t1
.
tm_mon
+
1
)
+
"/"
+
std
::
to_string
(
t1
.
tm_year
+
1900
)
+
" - "
+
std
::
to_string
(
t1
.
tm_mday
)
+
"/"
+
std
::
to_string
(
t2
.
tm_mon
+
1
)
+
"/"
+
std
::
to_string
(
t2
.
tm_year
+
1900
);
return
sRet
;
}
std
::
string
GetId
()
{
// TODO: + public key?
return
GetNumber
();
}
public:
std
::
string
Sign
(
const
std
::
string
&
sXml
)
{
EVP_MD_CTX
*
pCtx
=
EVP_MD_CTX_create
();
const
EVP_MD
*
pDigest
=
EVP_sha1
();
int
n1
=
EVP_SignInit
(
pCtx
,
pDigest
);
n1
=
n1
;
int
n2
=
EVP_SignUpdate
(
pCtx
,
sXml
.
c_str
(),
sXml
.
length
());
n2
=
n2
;
BYTE
pSignature
[
4096
];
unsigned
int
nSignatureLen
=
0
;
int
n3
=
EVP_SignFinal
(
pCtx
,
pSignature
,
&
nSignatureLen
,
m_key
);
n3
=
n3
;
EVP_MD_CTX_destroy
(
pCtx
);
return
std
::
string
((
char
*
)
pSignature
,
(
size_t
)
nSignatureLen
);
}
std
::
string
GetHash
(
unsigned
char
*
pData
,
unsigned
int
nSize
,
int
nAlg
)
{
if
(
nAlg
==
OOXML_HASH_ALG_SHA1
)
{
unsigned
char
obuf
[
20
];
SHA1
(
pData
,
(
size_t
)
nSize
,
obuf
);
char
*
pBase64_hash
=
NULL
;
int
nBase64Len_hash
=
0
;
NSFile
::
CBase64Converter
::
Encode
(
obuf
,
20
,
pBase64_hash
,
nBase64Len_hash
,
NSBase64
::
B64_BASE64_FLAG_NOCRLF
);
std
::
string
sReturn
(
pBase64_hash
,
nBase64Len_hash
);
delete
[]
pBase64_hash
;
return
sReturn
;
}
return
""
;
}
std
::
string
GetHash
(
const
std
::
string
&
sXml
,
int
nAlg
)
{
return
GetHash
((
BYTE
*
)
sXml
.
c_str
(),
(
DWORD
)
sXml
.
length
(),
nAlg
);
}
std
::
string
GetHash
(
const
std
::
wstring
&
sXmlFile
,
int
nAlg
)
{
BYTE
*
pFileData
=
NULL
;
DWORD
dwFileDataLen
=
0
;
NSFile
::
CFileBinary
::
ReadAllBytes
(
sXmlFile
,
&
pFileData
,
dwFileDataLen
);
if
(
0
==
dwFileDataLen
)
return
""
;
std
::
string
sReturn
=
GetHash
(
pFileData
,
dwFileDataLen
,
nAlg
);
RELEASEARRAYOBJECTS
(
pFileData
);
return
sReturn
;
}
bool
Verify
(
const
std
::
string
&
sXml
,
std
::
string
&
sXmlSignature
,
int
nAlg
)
{
EVP_MD_CTX
*
pCtx
=
EVP_MD_CTX_create
();
const
EVP_MD
*
pDigest
=
EVP_sha1
();
int
n1
=
EVP_VerifyInit
(
pCtx
,
pDigest
);
n1
=
n1
;
BYTE
*
pDigestValue
=
NULL
;
int
nDigestLen
=
0
;
NSFile
::
CBase64Converter
::
Decode
(
sXmlSignature
.
c_str
(),
(
int
)
sXmlSignature
.
length
(),
pDigestValue
,
nDigestLen
);
int
n2
=
EVP_VerifyUpdate
(
pCtx
,
pDigestValue
,
(
size_t
)
nDigestLen
);
n2
=
n2
;
EVP_PKEY
*
pubkey
=
X509_get_pubkey
(
m_cert
);
int
n3
=
EVP_VerifyFinal
(
pCtx
,
(
BYTE
*
)
sXml
.
c_str
(),
(
unsigned
int
)
sXml
.
length
(),
pubkey
);
n3
=
n3
;
EVP_MD_CTX_destroy
(
pCtx
);
EVP_PKEY_free
(
pubkey
);
RELEASEARRAYOBJECTS
(
pDigestValue
);
return
(
1
==
n3
)
?
true
:
false
;
}
bool
LoadFromBase64Data
(
const
std
::
string
&
data
)
{
BYTE
*
pData
=
NULL
;
int
nLen
=
0
;
if
(
NSFile
::
CBase64Converter
::
Decode
(
data
.
c_str
(),
(
int
)
data
.
length
(),
pData
,
nLen
))
{
X509
*
pCert
=
NULL
;
int
nErr
=
LoadCert
(
pData
,
(
DWORD
)
nLen
,
""
,
&
pCert
);
if
(
nErr
==
OPEN_SSL_WARNING_OK
||
nErr
==
OPEN_SSL_WARNING_ALL_OK
)
{
m_cert
=
pCert
;
}
else
{
X509_free
(
pCert
);
m_cert
=
NULL
;
}
RELEASEARRAYOBJECTS
(
pData
);
return
(
NULL
==
m_cert
)
?
false
:
true
;
}
return
false
;
}
public:
bool
ShowSelectDialog
()
{
if
(
!
m_pDialog
)
return
false
;
bool
bResult
=
m_pDialog
->
ShowSelectDialog
();
std
::
wstring
sKeyPath
=
m_pDialog
->
GetKeyPath
();
std
::
wstring
sKeyPasswordW
=
m_pDialog
->
GetKeyPassword
();
std
::
string
sKeyPassword
=
U_TO_UTF8
(
sKeyPasswordW
);
std
::
wstring
sCertPath
=
m_pDialog
->
GetCertificatePath
();
std
::
wstring
sCertPasswordW
=
m_pDialog
->
GetCertificatePassword
();
std
::
string
sCertPassword
=
U_TO_UTF8
(
sCertPasswordW
);
if
(
sCertPath
.
empty
())
{
sCertPath
=
sKeyPath
;
sCertPassword
=
sKeyPassword
;
}
int
nErr
=
LoadKey
(
sKeyPath
,
sKeyPassword
,
&
m_key
);
if
(
nErr
!=
OPEN_SSL_WARNING_OK
&&
nErr
!=
OPEN_SSL_WARNING_ALL_OK
)
return
false
;
nErr
=
LoadCert
(
sCertPath
,
sCertPassword
,
&
m_cert
);
if
(
nErr
!=
OPEN_SSL_WARNING_OK
&&
nErr
!=
OPEN_SSL_WARNING_ALL_OK
)
return
false
;
return
true
;
}
int
ShowCertificate
()
{
if
(
m_pDialog
)
return
m_pDialog
->
ShowCertificate
(
m_pBase
);
return
1
;
}
void
SetOpenSslDialog
(
ICertificateSelectDialogOpenSsl
*
pDialog
)
{
m_pDialog
=
pDialog
;
}
protected:
tm
ASN1_GetTimeT
(
ASN1_TIME
*
time
)
{
struct
tm
t
;
const
char
*
str
=
(
const
char
*
)
time
->
data
;
size_t
i
=
0
;
memset
(
&
t
,
0
,
sizeof
(
t
));
if
(
time
->
type
==
V_ASN1_UTCTIME
)
{
/* two digit year */
t
.
tm_year
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
);
if
(
t
.
tm_year
<
70
)
t
.
tm_year
+=
100
;
}
else
if
(
time
->
type
==
V_ASN1_GENERALIZEDTIME
)
{
/* four digit year */
t
.
tm_year
=
(
str
[
i
++
]
-
'0'
)
*
1000
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
)
*
100
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_year
-=
1900
;
}
t
.
tm_mon
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_mon
+=
(
str
[
i
++
]
-
'0'
)
-
1
;
// -1 since January is 0 not 1.
t
.
tm_mday
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_mday
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_hour
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_hour
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_min
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_min
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_sec
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_sec
+=
(
str
[
i
++
]
-
'0'
);
/* Note: we did not adjust the time based on time zone information */
return
t
;
}
public:
static
std
::
string
GetOpenSslErrors
()
{
BIO
*
bio
=
BIO_new
(
BIO_s_mem
());
ERR_print_errors
(
bio
);
char
*
buf
=
NULL
;
size_t
len
=
BIO_get_mem_data
(
bio
,
&
buf
);
std
::
string
sRet
((
char
*
)
buf
,
len
);
NSStringExt
::
ToLower
(
sRet
);
BIO_free
(
bio
);
return
sRet
;
}
static
bool
IsOpenSslPasswordError
(
const
std
::
string
&
str
)
{
if
(
std
::
string
::
npos
!=
str
.
find
(
"mac verify error"
))
return
true
;
if
(
std
::
string
::
npos
!=
str
.
find
(
"mac verify failure"
))
return
true
;
if
(
std
::
string
::
npos
!=
str
.
find
(
"password"
))
return
true
;
return
false
;
}
static
int
LoadKey
(
BYTE
*
pData
,
DWORD
dwDataLen
,
std
::
string
password
,
EVP_PKEY
**
ppKey
)
{
int
nErr
=
OPEN_SSL_WARNING_ERR
;
std
::
string
sError
=
""
;
PKCS12
*
p12
=
NULL
;
EVP_PKEY
*
pKey
=
NULL
;
char
*
pPassword
=
(
password
.
empty
())
?
NULL
:
(
char
*
)
password
.
c_str
();
BIO
*
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
PEM_read_bio_PrivateKey
(
bio
,
&
pKey
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_PrivateKey_bio
(
bio
,
&
pKey
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_PKCS8PrivateKey_bio
(
bio
,
&
pKey
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
p12
=
d2i_PKCS12_bio
(
bio
,
NULL
);
if
(
p12
)
{
X509
*
pCert
=
NULL
;
STACK_OF
(
X509
)
*
pCa
=
NULL
;
if
(
PKCS12_parse
(
p12
,
pPassword
,
&
pKey
,
&
pCert
,
&
pCa
))
{
sk_X509_pop_free
(
pCa
,
X509_free
);
X509_free
(
pCert
);
PKCS12_free
(
p12
);
nErr
=
OPEN_SSL_WARNING_ALL_OK
;
goto
end
;
}
PKCS12_free
(
p12
);
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
}
end:
if
(
NULL
==
ppKey
)
EVP_PKEY_free
(
pKey
);
else
*
ppKey
=
pKey
;
BIO_free
(
bio
);
return
nErr
;
}
static
int
LoadKey
(
std
::
wstring
file
,
std
::
string
password
,
EVP_PKEY
**
ppKey
)
{
BYTE
*
pData
=
NULL
;
DWORD
dwDataLen
;
if
(
!
NSFile
::
CFileBinary
::
ReadAllBytes
(
file
,
&
pData
,
dwDataLen
))
return
OPEN_SSL_WARNING_ERR
;
int
nErr
=
LoadKey
(
pData
,
dwDataLen
,
password
,
ppKey
);
RELEASEARRAYOBJECTS
(
pData
);
return
nErr
;
}
static
int
LoadCert
(
BYTE
*
pData
,
DWORD
dwDataLen
,
std
::
string
password
,
X509
**
ppCert
)
{
int
nErr
=
OPEN_SSL_WARNING_ERR
;
std
::
string
sError
=
""
;
PKCS12
*
p12
=
NULL
;
X509
*
pCert
=
NULL
;
char
*
pPassword
=
(
password
.
empty
())
?
NULL
:
(
char
*
)
password
.
c_str
();
BIO
*
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
PEM_read_bio_X509
(
bio
,
&
pCert
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_X509_bio
(
bio
,
&
pCert
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
p12
=
d2i_PKCS12_bio
(
bio
,
NULL
);
if
(
p12
)
{
EVP_PKEY
*
pKey
=
NULL
;
STACK_OF
(
X509
)
*
pCa
=
NULL
;
if
(
PKCS12_parse
(
p12
,
pPassword
,
&
pKey
,
&
pCert
,
&
pCa
))
{
sk_X509_pop_free
(
pCa
,
X509_free
);
EVP_PKEY_free
(
pKey
);
PKCS12_free
(
p12
);
BIO_free
(
bio
);
nErr
=
OPEN_SSL_WARNING_ALL_OK
;
goto
end
;
}
PKCS12_free
(
p12
);
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
}
end:
if
(
NULL
==
ppCert
)
X509_free
(
pCert
);
else
*
ppCert
=
pCert
;
BIO_free
(
bio
);
return
nErr
;
}
static
int
LoadCert
(
std
::
wstring
file
,
std
::
string
password
,
X509
**
ppCert
)
{
BYTE
*
pData
=
NULL
;
DWORD
dwDataLen
;
if
(
!
NSFile
::
CFileBinary
::
ReadAllBytes
(
file
,
&
pData
,
dwDataLen
))
return
OPEN_SSL_WARNING_ERR
;
int
nErr
=
LoadCert
(
pData
,
dwDataLen
,
password
,
ppCert
);
RELEASEARRAYOBJECTS
(
pData
);
return
nErr
;
}
};
// REALIZE
CCertificate_openssl
::
CCertificate_openssl
()
:
ICertificate
()
{
m_internal
=
new
CCertificate_openssl_private
();
m_internal
->
m_pBase
=
this
;
}
CCertificate_openssl
::~
CCertificate_openssl
()
{
RELEASEOBJECT
(
m_internal
);
}
std
::
string
CCertificate_openssl
::
GetNumber
()
{
return
m_internal
->
GetNumber
();
}
std
::
wstring
CCertificate_openssl
::
GetSignerName
()
{
return
m_internal
->
GetSignerName
();
}
std
::
string
CCertificate_openssl
::
GetCertificateBase64
()
{
return
m_internal
->
GetCertificateBase64
();
}
std
::
string
CCertificate_openssl
::
GetCertificateHash
()
{
return
m_internal
->
GetCertificateHash
();
}
std
::
string
CCertificate_openssl
::
GetDate
()
{
return
m_internal
->
GetDate
();
}
std
::
string
CCertificate_openssl
::
GetId
()
{
return
m_internal
->
GetId
();
}
std
::
string
CCertificate_openssl
::
Sign
(
const
std
::
string
&
sXml
)
{
return
m_internal
->
Sign
(
sXml
);
}
std
::
string
CCertificate_openssl
::
GetHash
(
unsigned
char
*
pData
,
unsigned
int
nSize
,
int
nAlg
)
{
return
m_internal
->
GetHash
(
pData
,
nSize
,
nAlg
);
}
std
::
string
CCertificate_openssl
::
GetHash
(
const
std
::
string
&
sXml
,
int
nAlg
)
{
return
m_internal
->
GetHash
(
sXml
,
nAlg
);
}
std
::
string
CCertificate_openssl
::
GetHash
(
const
std
::
wstring
&
sXmlFile
,
int
nAlg
)
{
return
m_internal
->
GetHash
(
sXmlFile
,
nAlg
);
}
bool
CCertificate_openssl
::
Verify
(
const
std
::
string
&
sXml
,
std
::
string
&
sXmlSignature
,
int
nAlg
)
{
return
m_internal
->
Verify
(
sXml
,
sXmlSignature
,
nAlg
);
}
bool
CCertificate_openssl
::
LoadFromBase64Data
(
const
std
::
string
&
data
)
{
return
m_internal
->
LoadFromBase64Data
(
data
);
}
bool
CCertificate_openssl
::
ShowSelectDialog
()
{
return
m_internal
->
ShowSelectDialog
();
}
int
CCertificate_openssl
::
ShowCertificate
()
{
return
m_internal
->
ShowCertificate
();
}
void
CCertificate_openssl
::
SetOpenSslDialog
(
ICertificateSelectDialogOpenSsl
*
pDialog
)
{
return
m_internal
->
SetOpenSslDialog
(
pDialog
);
}
int
LoadKey
(
std
::
wstring
file
,
std
::
string
password
)
{
return
CCertificate_openssl_private
::
LoadKey
(
file
,
password
,
NULL
);
}
int
LoadCert
(
std
::
wstring
file
,
std
::
string
password
)
{
return
CCertificate_openssl_private
::
LoadCert
(
file
,
password
,
NULL
);
}
DesktopEditor/xmlsec/src/src/XmlSigner_openssl.h
View file @
907e00a3
#ifndef _XMLSIGNER_OPENSSL_H_
#define _XMLSIGNER_OPENSSL_H_
#include "./include/XmlCertificate.h"
#include "../../../common/File.h"
#include "../../../common/String.h"
#include "../../../common/BigInteger.h"
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/pkcs12.h>
#include <openssl/sha.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
#include <openssl/conf.h>
#define OPEN_SSL_WARNING_OK 0
#define OPEN_SSL_WARNING_ERR 1
#define OPEN_SSL_WARNING_ALL_OK 2
#define OPEN_SSL_WARNING_PASS 4
#include "./../include/XmlCertificate.h"
class
CCertificate_openssl_private
;
class
CCertificate_openssl
:
public
ICertificate
{
protected:
ICertificateSelectDialogOpenSsl
*
m_pDialog
;
BYTE
*
m_rawData
;
int
m_rawDataLen
;
X509
*
m_cert
;
EVP_PKEY
*
m_key
;
CCertificate_openssl_private
*
m_internal
;
public:
CCertificate_openssl
()
:
ICertificate
()
{
m_pDialog
=
NULL
;
m_rawData
=
NULL
;
m_rawDataLen
=
0
;
m_cert
=
NULL
;
m_key
=
NULL
;
}
virtual
~
CCertificate_openssl
()
{
if
(
NULL
!=
m_cert
)
X509_free
(
m_cert
);
if
(
NULL
!=
m_key
)
EVP_PKEY_free
(
m_key
);
}
CCertificate_openssl
();
virtual
~
CCertificate_openssl
();
public:
virtual
std
::
string
GetNumber
()
{
if
(
NULL
==
m_cert
)
return
""
;
ASN1_INTEGER
*
asn1_serial
=
X509_get_serialNumber
(
m_cert
);
if
(
asn1_serial
==
NULL
)
return
""
;
BIGNUM
*
bn
=
ASN1_INTEGER_to_BN
(
asn1_serial
,
NULL
);
if
(
!
bn
)
{
ASN1_INTEGER_free
(
asn1_serial
);
return
""
;
}
char
*
tmp
=
BN_bn2dec
(
bn
);
std
::
string
sReturn
(
tmp
);
BN_free
(
bn
);
ASN1_INTEGER_free
(
asn1_serial
);
return
sReturn
;
}
virtual
std
::
wstring
GetSignerName
()
{
if
(
NULL
==
m_cert
)
return
L""
;
X509_NAME
*
name
=
X509_get_issuer_name
(
m_cert
);
char
*
utf_8_name
=
X509_NAME_oneline
(
name
,
NULL
,
0
);
std
::
string
sName
(
utf_8_name
);
std
::
wstring
sNameW
=
UTF8_TO_U
(
sName
);
OPENSSL_free
(
utf_8_name
);
return
sNameW
;
}
virtual
std
::
string
GetCertificateBase64
()
{
if
(
NULL
==
m_cert
)
return
""
;
BIO
*
bio
=
BIO_new
(
BIO_s_mem
());
PEM_write_bio_X509_AUX
(
bio
,
m_cert
);
unsigned
char
*
data
;
unsigned
int
len
=
0
;
len
=
BIO_get_mem_data
(
bio
,
&
data
);
std
::
string
sReturn
((
char
*
)
data
,
(
size_t
)
len
);
virtual
std
::
string
GetNumber
();
BIO_free
(
bio
);
return
sReturn
;
}
virtual
std
::
wstring
GetSignerName
();
virtual
std
::
string
GetCertificateHash
()
{
std
::
string
sBase64
=
GetCertificateBase64
();
BYTE
*
pData
=
NULL
;
int
nLen
=
0
;
if
(
NSFile
::
CBase64Converter
::
Decode
(
sBase64
.
c_str
(),
(
int
)
sBase64
.
length
(),
pData
,
nLen
))
{
std
::
string
sHash
=
GetHash
(
pData
,
(
unsigned
int
)
nLen
,
OOXML_HASH_ALG_SHA1
);
RELEASEARRAYOBJECTS
(
pData
);
return
sHash
;
}
virtual
std
::
string
GetCertificateBase64
();
return
""
;
}
virtual
std
::
string
GetCertificateHash
();
virtual
std
::
string
GetDate
()
{
if
(
NULL
==
m_cert
)
return
""
;
virtual
std
::
string
GetDate
();
ASN1_TIME
*
_time1
=
X509_get_notBefore
(
m_cert
);
struct
tm
t1
=
this
->
ASN1_GetTimeT
(
_time1
);
ASN1_TIME_free
(
_time1
);
ASN1_TIME
*
_time2
=
X509_get_notAfter
(
m_cert
);
struct
tm
t2
=
this
->
ASN1_GetTimeT
(
_time2
);
ASN1_TIME_free
(
_time2
);
std
::
string
sRet
=
std
::
to_string
(
t1
.
tm_mday
)
+
"/"
+
std
::
to_string
(
t1
.
tm_mon
+
1
)
+
"/"
+
std
::
to_string
(
t1
.
tm_year
+
1900
)
+
" - "
+
std
::
to_string
(
t1
.
tm_mday
)
+
"/"
+
std
::
to_string
(
t2
.
tm_mon
+
1
)
+
"/"
+
std
::
to_string
(
t2
.
tm_year
+
1900
);
return
sRet
;
}
virtual
std
::
string
GetId
()
{
// TODO: + public key?
return
GetNumber
();
}
virtual
std
::
string
GetId
();
public:
virtual
std
::
string
Sign
(
const
std
::
string
&
sXml
)
{
EVP_MD_CTX
*
pCtx
=
EVP_MD_CTX_create
();
const
EVP_MD
*
pDigest
=
EVP_sha1
();
int
n1
=
EVP_SignInit
(
pCtx
,
pDigest
);
n1
=
n1
;
int
n2
=
EVP_SignUpdate
(
pCtx
,
sXml
.
c_str
(),
sXml
.
length
());
n2
=
n2
;
BYTE
pSignature
[
4096
];
unsigned
int
nSignatureLen
=
0
;
int
n3
=
EVP_SignFinal
(
pCtx
,
pSignature
,
&
nSignatureLen
,
m_key
);
n3
=
n3
;
EVP_MD_CTX_destroy
(
pCtx
);
return
std
::
string
((
char
*
)
pSignature
,
(
size_t
)
nSignatureLen
);
}
virtual
std
::
string
GetHash
(
unsigned
char
*
pData
,
unsigned
int
nSize
,
int
nAlg
)
{
if
(
nAlg
==
OOXML_HASH_ALG_SHA1
)
{
unsigned
char
obuf
[
20
];
SHA1
(
pData
,
(
size_t
)
nSize
,
obuf
);
char
*
pBase64_hash
=
NULL
;
int
nBase64Len_hash
=
0
;
NSFile
::
CBase64Converter
::
Encode
(
obuf
,
20
,
pBase64_hash
,
nBase64Len_hash
,
NSBase64
::
B64_BASE64_FLAG_NOCRLF
);
std
::
string
sReturn
(
pBase64_hash
,
nBase64Len_hash
);
delete
[]
pBase64_hash
;
return
sReturn
;
}
return
""
;
}
virtual
std
::
string
GetHash
(
const
std
::
string
&
sXml
,
int
nAlg
)
{
return
GetHash
((
BYTE
*
)
sXml
.
c_str
(),
(
DWORD
)
sXml
.
length
(),
nAlg
);
}
virtual
std
::
string
GetHash
(
const
std
::
wstring
&
sXmlFile
,
int
nAlg
)
{
BYTE
*
pFileData
=
NULL
;
DWORD
dwFileDataLen
=
0
;
NSFile
::
CFileBinary
::
ReadAllBytes
(
sXmlFile
,
&
pFileData
,
dwFileDataLen
);
if
(
0
==
dwFileDataLen
)
return
""
;
std
::
string
sReturn
=
GetHash
(
pFileData
,
dwFileDataLen
,
nAlg
);
RELEASEARRAYOBJECTS
(
pFileData
);
return
sReturn
;
}
virtual
bool
Verify
(
const
std
::
string
&
sXml
,
std
::
string
&
sXmlSignature
,
int
nAlg
)
{
EVP_MD_CTX
*
pCtx
=
EVP_MD_CTX_create
();
const
EVP_MD
*
pDigest
=
EVP_sha1
();
int
n1
=
EVP_VerifyInit
(
pCtx
,
pDigest
);
n1
=
n1
;
BYTE
*
pDigestValue
=
NULL
;
int
nDigestLen
=
0
;
NSFile
::
CBase64Converter
::
Decode
(
sXmlSignature
.
c_str
(),
(
int
)
sXmlSignature
.
length
(),
pDigestValue
,
nDigestLen
);
virtual
std
::
string
Sign
(
const
std
::
string
&
sXml
);
int
n2
=
EVP_VerifyUpdate
(
pCtx
,
pDigestValue
,
(
size_t
)
nDigestLen
);
n2
=
n2
;
virtual
std
::
string
GetHash
(
unsigned
char
*
pData
,
unsigned
int
nSize
,
int
nAlg
);
EVP_PKEY
*
pubkey
=
X509_get_pubkey
(
m_cert
);
virtual
std
::
string
GetHash
(
const
std
::
string
&
sXml
,
int
nAlg
);
int
n3
=
EVP_VerifyFinal
(
pCtx
,
(
BYTE
*
)
sXml
.
c_str
(),
(
unsigned
int
)
sXml
.
length
(),
pubkey
);
n3
=
n3
;
virtual
std
::
string
GetHash
(
const
std
::
wstring
&
sXmlFile
,
int
nAlg
);
EVP_MD_CTX_destroy
(
pCtx
);
EVP_PKEY_free
(
pubkey
);
virtual
bool
Verify
(
const
std
::
string
&
sXml
,
std
::
string
&
sXmlSignature
,
int
nAlg
);
RELEASEARRAYOBJECTS
(
pDigestValue
);
return
(
1
==
n3
)
?
true
:
false
;
}
virtual
bool
LoadFromBase64Data
(
const
std
::
string
&
data
)
{
BYTE
*
pData
=
NULL
;
int
nLen
=
0
;
if
(
NSFile
::
CBase64Converter
::
Decode
(
data
.
c_str
(),
(
int
)
data
.
length
(),
pData
,
nLen
))
{
X509
*
pCert
=
NULL
;
int
nErr
=
LoadCert
(
pData
,
(
DWORD
)
nLen
,
""
,
&
pCert
);
if
(
nErr
==
OPEN_SSL_WARNING_OK
||
nErr
==
OPEN_SSL_WARNING_ALL_OK
)
{
m_cert
=
pCert
;
}
else
{
X509_free
(
pCert
);
m_cert
=
NULL
;
}
RELEASEARRAYOBJECTS
(
pData
);
return
(
NULL
==
m_cert
)
?
false
:
true
;
}
return
false
;
}
virtual
bool
LoadFromBase64Data
(
const
std
::
string
&
data
);
public:
virtual
bool
ShowSelectDialog
()
{
if
(
!
m_pDialog
)
return
false
;
bool
bResult
=
m_pDialog
->
ShowSelectDialog
();
std
::
wstring
sKeyPath
=
m_pDialog
->
GetKeyPath
();
std
::
wstring
sKeyPasswordW
=
m_pDialog
->
GetKeyPassword
();
std
::
string
sKeyPassword
=
U_TO_UTF8
(
sKeyPasswordW
);
std
::
wstring
sCertPath
=
m_pDialog
->
GetCertificatePath
();
std
::
wstring
sCertPasswordW
=
m_pDialog
->
GetCertificatePassword
();
std
::
string
sCertPassword
=
U_TO_UTF8
(
sCertPasswordW
);
if
(
sCertPath
.
empty
())
{
sCertPath
=
sKeyPath
;
sCertPassword
=
sKeyPassword
;
}
int
nErr
=
LoadKey
(
sKeyPath
,
sKeyPassword
,
&
m_key
);
if
(
nErr
!=
OPEN_SSL_WARNING_OK
&&
nErr
!=
OPEN_SSL_WARNING_ALL_OK
)
return
false
;
nErr
=
LoadCert
(
sCertPath
,
sCertPassword
,
&
m_cert
);
virtual
bool
ShowSelectDialog
();
virtual
int
ShowCertificate
();
if
(
nErr
!=
OPEN_SSL_WARNING_OK
&&
nErr
!=
OPEN_SSL_WARNING_ALL_OK
)
return
false
;
return
true
;
}
virtual
int
ShowCertificate
()
{
if
(
m_pDialog
)
return
m_pDialog
->
ShowCertificate
(
this
);
return
1
;
}
virtual
void
SetOpenSslDialog
(
ICertificateSelectDialogOpenSsl
*
pDialog
)
{
m_pDialog
=
pDialog
;
}
protected:
tm
ASN1_GetTimeT
(
ASN1_TIME
*
time
)
{
struct
tm
t
;
const
char
*
str
=
(
const
char
*
)
time
->
data
;
size_t
i
=
0
;
memset
(
&
t
,
0
,
sizeof
(
t
));
if
(
time
->
type
==
V_ASN1_UTCTIME
)
{
/* two digit year */
t
.
tm_year
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
);
if
(
t
.
tm_year
<
70
)
t
.
tm_year
+=
100
;
}
else
if
(
time
->
type
==
V_ASN1_GENERALIZEDTIME
)
{
/* four digit year */
t
.
tm_year
=
(
str
[
i
++
]
-
'0'
)
*
1000
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
)
*
100
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_year
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_year
-=
1900
;
}
t
.
tm_mon
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_mon
+=
(
str
[
i
++
]
-
'0'
)
-
1
;
// -1 since January is 0 not 1.
t
.
tm_mday
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_mday
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_hour
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_hour
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_min
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_min
+=
(
str
[
i
++
]
-
'0'
);
t
.
tm_sec
=
(
str
[
i
++
]
-
'0'
)
*
10
;
t
.
tm_sec
+=
(
str
[
i
++
]
-
'0'
);
/* Note: we did not adjust the time based on time zone information */
return
t
;
}
virtual
void
SetOpenSslDialog
(
ICertificateSelectDialogOpenSsl
*
pDialog
);
public:
static
std
::
string
GetOpenSslErrors
()
{
BIO
*
bio
=
BIO_new
(
BIO_s_mem
());
ERR_print_errors
(
bio
);
char
*
buf
=
NULL
;
size_t
len
=
BIO_get_mem_data
(
bio
,
&
buf
);
std
::
string
sRet
((
char
*
)
buf
,
len
);
NSStringExt
::
ToLower
(
sRet
);
BIO_free
(
bio
);
return
sRet
;
}
static
bool
IsOpenSslPasswordError
(
const
std
::
string
&
str
)
{
if
(
std
::
string
::
npos
!=
str
.
find
(
"mac verify error"
))
return
true
;
if
(
std
::
string
::
npos
!=
str
.
find
(
"mac verify failure"
))
return
true
;
if
(
std
::
string
::
npos
!=
str
.
find
(
"password"
))
return
true
;
return
false
;
}
static
int
LoadKey
(
BYTE
*
pData
,
DWORD
dwDataLen
,
std
::
string
password
,
EVP_PKEY
**
ppKey
)
{
int
nErr
=
OPEN_SSL_WARNING_ERR
;
std
::
string
sError
=
""
;
PKCS12
*
p12
=
NULL
;
EVP_PKEY
*
pKey
=
NULL
;
char
*
pPassword
=
(
password
.
empty
())
?
NULL
:
(
char
*
)
password
.
c_str
();
BIO
*
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
PEM_read_bio_PrivateKey
(
bio
,
&
pKey
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_PrivateKey_bio
(
bio
,
&
pKey
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_PKCS8PrivateKey_bio
(
bio
,
&
pKey
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
p12
=
d2i_PKCS12_bio
(
bio
,
NULL
);
if
(
p12
)
{
X509
*
pCert
=
NULL
;
STACK_OF
(
X509
)
*
pCa
=
NULL
;
if
(
PKCS12_parse
(
p12
,
pPassword
,
&
pKey
,
&
pCert
,
&
pCa
))
{
sk_X509_pop_free
(
pCa
,
X509_free
);
X509_free
(
pCert
);
PKCS12_free
(
p12
);
nErr
=
OPEN_SSL_WARNING_ALL_OK
;
goto
end
;
}
PKCS12_free
(
p12
);
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
}
end:
if
(
NULL
==
ppKey
)
EVP_PKEY_free
(
pKey
);
else
*
ppKey
=
pKey
;
BIO_free
(
bio
);
return
nErr
;
}
static
int
LoadKey
(
std
::
wstring
file
,
std
::
string
password
,
EVP_PKEY
**
ppKey
)
{
BYTE
*
pData
=
NULL
;
DWORD
dwDataLen
;
if
(
!
NSFile
::
CFileBinary
::
ReadAllBytes
(
file
,
&
pData
,
dwDataLen
))
return
OPEN_SSL_WARNING_ERR
;
int
nErr
=
LoadKey
(
pData
,
dwDataLen
,
password
,
ppKey
);
RELEASEARRAYOBJECTS
(
pData
);
return
nErr
;
}
static
int
LoadCert
(
BYTE
*
pData
,
DWORD
dwDataLen
,
std
::
string
password
,
X509
**
ppCert
)
{
int
nErr
=
OPEN_SSL_WARNING_ERR
;
std
::
string
sError
=
""
;
PKCS12
*
p12
=
NULL
;
X509
*
pCert
=
NULL
;
char
*
pPassword
=
(
password
.
empty
())
?
NULL
:
(
char
*
)
password
.
c_str
();
BIO
*
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
PEM_read_bio_X509
(
bio
,
&
pCert
,
NULL
,
(
void
*
)
pPassword
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
if
(
d2i_X509_bio
(
bio
,
&
pCert
))
{
nErr
=
OPEN_SSL_WARNING_OK
;
goto
end
;
}
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
BIO_free
(
bio
);
bio
=
BIO_new_mem_buf
((
void
*
)
pData
,
(
int
)
dwDataLen
);
p12
=
d2i_PKCS12_bio
(
bio
,
NULL
);
if
(
p12
)
{
EVP_PKEY
*
pKey
=
NULL
;
STACK_OF
(
X509
)
*
pCa
=
NULL
;
if
(
PKCS12_parse
(
p12
,
pPassword
,
&
pKey
,
&
pCert
,
&
pCa
))
{
sk_X509_pop_free
(
pCa
,
X509_free
);
EVP_PKEY_free
(
pKey
);
PKCS12_free
(
p12
);
BIO_free
(
bio
);
nErr
=
OPEN_SSL_WARNING_ALL_OK
;
goto
end
;
}
PKCS12_free
(
p12
);
sError
=
GetOpenSslErrors
();
if
(
IsOpenSslPasswordError
(
sError
))
{
nErr
=
OPEN_SSL_WARNING_PASS
;
goto
end
;
}
}
end:
if
(
NULL
==
ppCert
)
X509_free
(
pCert
);
else
*
ppCert
=
pCert
;
BIO_free
(
bio
);
return
nErr
;
}
static
int
LoadCert
(
std
::
wstring
file
,
std
::
string
password
,
X509
**
ppCert
)
{
BYTE
*
pData
=
NULL
;
DWORD
dwDataLen
;
if
(
!
NSFile
::
CFileBinary
::
ReadAllBytes
(
file
,
&
pData
,
dwDataLen
))
return
OPEN_SSL_WARNING_ERR
;
int
nErr
=
LoadCert
(
pData
,
dwDataLen
,
password
,
ppCert
);
RELEASEARRAYOBJECTS
(
pData
);
return
nErr
;
}
static
int
LoadKey
(
std
::
wstring
file
,
std
::
string
password
);
static
int
LoadCert
(
std
::
wstring
file
,
std
::
string
password
);
};
#endif // _XMLSIGNER_OPENSSL_H_
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment