Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
5e2075be
Commit
5e2075be
authored
Jan 31, 2005
by
Michael Jung
Committed by
Alexandre Julliard
Jan 31, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved PKCS1 #2 un-/padding from Import-/ExportKey to helper
functions. Support RSA en-/decryption via CPEncrypt and CPDecrypt. Added test case for RSA en-/decryption.
parent
d56ccaa7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
158 additions
and
40 deletions
+158
-40
rsaenh.c
dlls/rsaenh/rsaenh.c
+122
-39
rsaenh.c
dlls/rsaenh/tests/rsaenh.c
+36
-1
No files found.
dlls/rsaenh/rsaenh.c
View file @
5e2075be
...
...
@@ -744,6 +744,8 @@ static HCRYPTKEY new_key(HCRYPTPROV hProv, ALG_ID aiAlgid, DWORD dwFlags, CRYPTK
DWORD
dwKeyLen
=
HIWORD
(
dwFlags
);
const
PROV_ENUMALGS_EX
*
peaAlgidInfo
;
*
ppCryptKey
=
NULL
;
/*
* Retrieve the CSP's capabilities for the given ALG_ID value
*/
...
...
@@ -1275,6 +1277,84 @@ exit:
}
/******************************************************************************
* pad_data [Internal]
*
* Helper function for data padding according to PKCS1 #2
*
* PARAMS
* abData [I] The data to be padded
* dwDataLen [I] Length of the data
* abBuffer [O] Padded data will be stored here
* dwBufferLen [I] Length of the buffer (also length of padded data)
* dwFlags [I] Padding format (CRYPT_SSL2_FALLBACK)
*
* RETURN
* Success: TRUE
* Failure: FALSE (NTE_BAD_LEN, too much data to pad)
*/
static
BOOL
pad_data
(
CONST
BYTE
*
abData
,
DWORD
dwDataLen
,
BYTE
*
abBuffer
,
DWORD
dwBufferLen
,
DWORD
dwFlags
)
{
DWORD
i
;
/* Ensure there is enough space for PKCS1 #2 padding */
if
(
dwDataLen
>
dwBufferLen
-
11
)
{
SetLastError
(
NTE_BAD_LEN
);
return
FALSE
;
}
memmove
(
abBuffer
+
dwBufferLen
-
dwDataLen
,
abData
,
dwDataLen
);
abBuffer
[
0
]
=
0x00
;
abBuffer
[
1
]
=
RSAENH_PKC_BLOCKTYPE
;
for
(
i
=
2
;
i
<
dwBufferLen
-
dwDataLen
-
1
;
i
++
)
do
gen_rand_impl
(
&
abBuffer
[
i
],
1
);
while
(
!
abBuffer
[
i
]);
if
(
dwFlags
&
CRYPT_SSL2_FALLBACK
)
for
(
i
-=
8
;
i
<
dwBufferLen
-
dwDataLen
-
1
;
i
++
)
abBuffer
[
i
]
=
0x03
;
abBuffer
[
i
]
=
0x00
;
return
TRUE
;
}
/******************************************************************************
* unpad_data [Internal]
*
* Remove the PKCS1 padding from RSA decrypted data
*
* PARAMS
* abData [I] The padded data
* dwDataLen [I] Length of the padded data
* abBuffer [O] Data without padding will be stored here
* dwBufferLen [I/O] I: Length of the buffer, O: Length of unpadded data
* dwFlags [I] Currently none defined
*
* RETURNS
* Success: TRUE
* Failure: FALSE, (NTE_BAD_DATA, no valid PKCS1 padding or buffer too small)
*/
static
BOOL
unpad_data
(
CONST
BYTE
*
abData
,
DWORD
dwDataLen
,
BYTE
*
abBuffer
,
DWORD
*
dwBufferLen
,
DWORD
dwFlags
)
{
DWORD
i
;
for
(
i
=
2
;
i
<
dwDataLen
;
i
++
)
if
(
!
abData
[
i
])
break
;
if
((
i
==
dwDataLen
)
||
(
*
dwBufferLen
<
dwDataLen
-
i
-
1
)
||
(
abData
[
0
]
!=
0x00
)
||
(
abData
[
1
]
!=
RSAENH_PKC_BLOCKTYPE
))
{
SetLastError
(
NTE_BAD_DATA
);
return
FALSE
;
}
*
dwBufferLen
=
dwDataLen
-
i
-
1
;
memmove
(
abBuffer
,
abData
+
i
+
1
,
*
dwBufferLen
);
return
TRUE
;
}
/******************************************************************************
* CPAcquireContext (RSAENH.@)
*
* Acquire a handle to the key container specified by pszContainer
...
...
@@ -1719,11 +1799,6 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
return
FALSE
;
}
if
(
GET_ALG_CLASS
(
pCryptKey
->
aiAlgid
)
!=
ALG_CLASS_DATA_ENCRYPT
)
{
SetLastError
(
NTE_BAD_TYPE
);
return
FALSE
;
}
if
(
pCryptKey
->
dwState
==
RSAENH_KEYSTATE_IDLE
)
pCryptKey
->
dwState
=
RSAENH_KEYSTATE_ENCRYPTING
;
...
...
@@ -1786,6 +1861,22 @@ BOOL WINAPI RSAENH_CPEncrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
}
}
else
if
(
GET_ALG_TYPE
(
pCryptKey
->
aiAlgid
)
==
ALG_TYPE_STREAM
)
{
encrypt_stream_impl
(
pCryptKey
->
aiAlgid
,
&
pCryptKey
->
context
,
pbData
,
*
pdwDataLen
);
}
else
if
(
GET_ALG_TYPE
(
pCryptKey
->
aiAlgid
)
==
ALG_TYPE_RSA
)
{
if
(
pCryptKey
->
aiAlgid
==
CALG_RSA_SIGN
)
{
SetLastError
(
NTE_BAD_KEY
);
return
FALSE
;
}
if
(
dwBufLen
<
pCryptKey
->
dwBlockLen
)
{
SetLastError
(
ERROR_MORE_DATA
);
return
FALSE
;
}
if
(
!
pad_data
(
pbData
,
*
pdwDataLen
,
pbData
,
pCryptKey
->
dwBlockLen
,
dwFlags
))
return
FALSE
;
encrypt_block_impl
(
pCryptKey
->
aiAlgid
,
&
pCryptKey
->
context
,
pbData
,
pbData
,
RSAENH_ENCRYPT
);
*
pdwDataLen
=
pCryptKey
->
dwBlockLen
;
Final
=
TRUE
;
}
else
{
SetLastError
(
NTE_BAD_TYPE
);
return
FALSE
;
}
if
(
Final
)
setup_key
(
pCryptKey
);
...
...
@@ -1845,11 +1936,6 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
return
FALSE
;
}
if
(
GET_ALG_CLASS
(
pCryptKey
->
aiAlgid
)
!=
ALG_CLASS_DATA_ENCRYPT
)
{
SetLastError
(
NTE_BAD_TYPE
);
return
FALSE
;
}
if
(
pCryptKey
->
dwState
==
RSAENH_KEYSTATE_IDLE
)
pCryptKey
->
dwState
=
RSAENH_KEYSTATE_DECRYPTING
;
...
...
@@ -1896,8 +1982,18 @@ BOOL WINAPI RSAENH_CPDecrypt(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTHASH hHash,
}
else
if
(
GET_ALG_TYPE
(
pCryptKey
->
aiAlgid
)
==
ALG_TYPE_STREAM
)
{
encrypt_stream_impl
(
pCryptKey
->
aiAlgid
,
&
pCryptKey
->
context
,
pbData
,
*
pdwDataLen
);
}
else
if
(
GET_ALG_TYPE
(
pCryptKey
->
aiAlgid
)
==
ALG_TYPE_RSA
)
{
if
(
pCryptKey
->
aiAlgid
==
CALG_RSA_SIGN
)
{
SetLastError
(
NTE_BAD_KEY
);
return
FALSE
;
}
encrypt_block_impl
(
pCryptKey
->
aiAlgid
,
&
pCryptKey
->
context
,
pbData
,
pbData
,
RSAENH_DECRYPT
);
}
if
(
!
unpad_data
(
pbData
,
pCryptKey
->
dwBlockLen
,
pbData
,
pdwDataLen
,
dwFlags
))
return
FALSE
;
Final
=
TRUE
;
}
else
{
SetLastError
(
NTE_BAD_TYPE
);
return
FALSE
;
}
if
(
Final
)
setup_key
(
pCryptKey
);
if
(
is_valid_handle
(
&
handle_table
,
hHash
,
RSAENH_MAGIC_HASH
))
{
...
...
@@ -1932,8 +2028,7 @@ BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubK
BLOBHEADER
*
pBlobHeader
=
(
BLOBHEADER
*
)
pbData
;
RSAPUBKEY
*
pRSAPubKey
=
(
RSAPUBKEY
*
)(
pBlobHeader
+
1
);
ALG_ID
*
pAlgid
=
(
ALG_ID
*
)(
pBlobHeader
+
1
);
DWORD
dwDataLen
,
i
;
BYTE
*
pbRawData
;
DWORD
dwDataLen
;
TRACE
(
"(hProv=%08lx, hKey=%08lx, hPubKey=%08lx, dwBlobType=%08lx, dwFlags=%08lx, pbData=%p,"
"pdwDataLen=%p)
\n
"
,
hProv
,
hKey
,
hPubKey
,
dwBlobType
,
dwFlags
,
pbData
,
pdwDataLen
);
...
...
@@ -1984,22 +2079,15 @@ BOOL WINAPI RSAENH_CPExportKey(HCRYPTPROV hProv, HCRYPTKEY hKey, HCRYPTKEY hPubK
pBlobHeader
->
aiKeyAlg
=
pCryptKey
->
aiAlgid
;
*
pAlgid
=
pPubKey
->
aiAlgid
;
pbRawData
=
(
BYTE
*
)(
pAlgid
+
1
);
pbRawData
[
0
]
=
0x00
;
pbRawData
[
1
]
=
RSAENH_PKC_BLOCKTYPE
;
for
(
i
=
2
;
i
<
pPubKey
->
dwBlockLen
-
pCryptKey
->
dwKeyLen
-
1
;
i
++
)
do
gen_rand_impl
(
&
pbRawData
[
i
],
1
);
while
(
!
pbRawData
[
i
]);
if
(
dwFlags
&
CRYPT_SSL2_FALLBACK
)
for
(
i
-=
8
;
i
<
pPubKey
->
dwBlockLen
-
pCryptKey
->
dwKeyLen
-
1
;
i
++
)
pbRawData
[
i
]
=
0x03
;
pbRawData
[
i
]
=
0x00
;
for
(
i
=
0
;
i
<
pCryptKey
->
dwKeyLen
;
i
++
)
pbRawData
[
pPubKey
->
dwBlockLen
-
pCryptKey
->
dwKeyLen
+
i
]
=
pCryptKey
->
abKeyValue
[
i
];
encrypt_block_impl
(
pPubKey
->
aiAlgid
,
&
pPubKey
->
context
,
pbRawData
,
pbRawData
,
RSAENH_ENCRYPT
);
if
(
!
pad_data
(
pCryptKey
->
abKeyValue
,
pCryptKey
->
dwKeyLen
,
(
BYTE
*
)(
pAlgid
+
1
),
pPubKey
->
dwBlockLen
,
dwFlags
))
{
return
FALSE
;
}
encrypt_block_impl
(
pPubKey
->
aiAlgid
,
&
pPubKey
->
context
,
(
BYTE
*
)(
pAlgid
+
1
),
(
BYTE
*
)(
pAlgid
+
1
),
RSAENH_ENCRYPT
);
}
*
pdwDataLen
=
dwDataLen
;
return
TRUE
;
...
...
@@ -2098,7 +2186,7 @@ BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDat
CONST
ALG_ID
*
pAlgid
=
(
CONST
ALG_ID
*
)(
pBlobHeader
+
1
);
CONST
BYTE
*
pbKeyStream
=
(
CONST
BYTE
*
)(
pAlgid
+
1
);
BYTE
*
pbDecrypted
;
DWORD
dwKeyLen
,
i
;
DWORD
dwKeyLen
;
TRACE
(
"(hProv=%08lx, pbData=%p, dwDataLen=%ld, hPubKey=%08lx, dwFlags=%08lx, phKey=%p)
\n
"
,
hProv
,
pbData
,
dwDataLen
,
hPubKey
,
dwFlags
,
phKey
);
...
...
@@ -2169,24 +2257,19 @@ BOOL WINAPI RSAENH_CPImportKey(HCRYPTPROV hProv, CONST BYTE *pbData, DWORD dwDat
encrypt_block_impl
(
pPubKey
->
aiAlgid
,
&
pPubKey
->
context
,
pbKeyStream
,
pbDecrypted
,
RSAENH_DECRYPT
);
for
(
i
=
2
;
i
<
pPubKey
->
dwBlockLen
&&
pbDecrypted
[
i
];
i
++
);
if
((
i
==
pPubKey
->
dwBlockLen
)
||
(
pbDecrypted
[
0
]
!=
0x00
)
||
(
pbDecrypted
[
1
]
!=
RSAENH_PKC_BLOCKTYPE
))
{
dwKeyLen
=
RSAENH_MAX_KEY_SIZE
;
if
(
!
unpad_data
(
pbDecrypted
,
pPubKey
->
dwBlockLen
,
pbDecrypted
,
&
dwKeyLen
,
dwFlags
))
{
HeapFree
(
GetProcessHeap
(),
0
,
pbDecrypted
);
SetLastError
(
NTE_BAD_DATA
);
/* FIXME: error code */
return
FALSE
;
}
dwKeyLen
=
pPubKey
->
dwBlockLen
-
i
-
1
;
*
phKey
=
new_key
(
hProv
,
pBlobHeader
->
aiKeyAlg
,
dwKeyLen
<<
19
,
&
pCryptKey
);
if
(
*
phKey
==
(
HCRYPTKEY
)
INVALID_HANDLE_VALUE
)
{
HeapFree
(
GetProcessHeap
(),
0
,
pbDecrypted
);
return
FALSE
;
}
memcpy
(
pCryptKey
->
abKeyValue
,
pbDecrypted
+
i
+
1
,
dwKeyLen
);
memcpy
(
pCryptKey
->
abKeyValue
,
pbDecrypted
,
dwKeyLen
);
HeapFree
(
GetProcessHeap
(),
0
,
pbDecrypted
);
setup_key
(
pCryptKey
);
return
TRUE
;
...
...
dlls/rsaenh/tests/rsaenh.c
View file @
5e2075be
...
...
@@ -83,7 +83,7 @@ static void clean_up_environment(void)
result
=
CryptReleaseContext
(
hProv
,
1
);
ok
(
!
result
&&
GetLastError
()
==
NTE_BAD_FLAGS
,
"%08lx
\n
"
,
GetLastError
());
CryptAcquireContext
(
&
hProv
,
szContainer
,
szProvider
,
PROV_RSA_FULL
,
CRYPT_DELETEKEYSET
);
}
...
...
@@ -1085,6 +1085,40 @@ static void test_verify_signature() {
if
(
!
result
)
return
;
}
void
test_rsa_encrypt
()
{
HCRYPTKEY
hRSAKey
;
BYTE
abData
[
2048
]
=
"Wine rocks!"
;
BOOL
result
;
DWORD
dwLen
;
/* It is allowed to use the key exchange key for encryption/decryption */
result
=
CryptGetUserKey
(
hProv
,
AT_KEYEXCHANGE
,
&
hRSAKey
);
ok
(
result
,
"%08lx
\n
"
,
GetLastError
());
if
(
!
result
)
return
;
dwLen
=
12
;
result
=
CryptEncrypt
(
hRSAKey
,
0
,
TRUE
,
0
,
abData
,
&
dwLen
,
(
DWORD
)
sizeof
(
abData
));
ok
(
result
,
"%08lx
\n
"
,
GetLastError
());
if
(
!
result
)
return
;
result
=
CryptDecrypt
(
hRSAKey
,
0
,
TRUE
,
0
,
abData
,
&
dwLen
);
ok
(
result
&&
dwLen
==
12
&&
!
memcmp
(
abData
,
"Wine rocks!"
,
12
),
"%08lx
\n
"
,
GetLastError
());
CryptDestroyKey
(
hRSAKey
);
/* It is not allowed to use the signature key for encryption/decryption */
result
=
CryptGetUserKey
(
hProv
,
AT_SIGNATURE
,
&
hRSAKey
);
ok
(
result
,
"%08lx
\n
"
,
GetLastError
());
if
(
!
result
)
return
;
dwLen
=
12
;
result
=
CryptEncrypt
(
hRSAKey
,
0
,
TRUE
,
0
,
abData
,
&
dwLen
,
(
DWORD
)
sizeof
(
abData
));
ok
(
!
result
&&
GetLastError
()
==
NTE_BAD_KEY
,
"%08lx
\n
"
,
GetLastError
());
CryptDestroyKey
(
hRSAKey
);
}
void
test_schannel_provider
()
{
HCRYPTPROV
hProv
;
...
...
@@ -1349,6 +1383,7 @@ START_TEST(rsaenh)
test_block_cipher_modes
();
test_import_private
();
test_verify_signature
();
test_rsa_encrypt
();
clean_up_environment
();
test_schannel_provider
();
}
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