Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
R
Rust Openssl
Manage
Activity
Members
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Model registry
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Public Repositories
Rust Openssl
Commits
6018fed2
Unverified
Commit
6018fed2
authored
Feb 19, 2023
by
Jack Rickard
Committed by
GitHub
Feb 19, 2023
Browse files
Options
Downloads
Plain Diff
Merge pull request #1589 from sladecek/CMS_verify
Add CMS_verify() method.
parents
ba8cee49
bfb7518c
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
openssl-sys/src/handwritten/cms.rs
+10
-0
10 additions, 0 deletions
openssl-sys/src/handwritten/cms.rs
openssl/CHANGELOG.md
+2
-0
2 additions, 0 deletions
openssl/CHANGELOG.md
openssl/src/cms.rs
+168
-2
168 additions, 2 deletions
openssl/src/cms.rs
with
180 additions
and
2 deletions
openssl-sys/src/handwritten/cms.rs
+
10
−
0
View file @
6018fed2
...
...
@@ -35,6 +35,16 @@ extern "C" {
flags
:
c_uint
,
)
->
*
mut
CMS_ContentInfo
;
#[cfg(ossl101)]
pub
fn
CMS_verify
(
cms
:
*
mut
CMS_ContentInfo
,
certs
:
*
mut
stack_st_X509
,
store
:
*
mut
X509_STORE
,
detached_data
:
*
mut
BIO
,
out
:
*
mut
BIO
,
flags
:
c_uint
,
)
->
c_int
;
#[cfg(ossl101)]
pub
fn
CMS_encrypt
(
certs
:
*
mut
stack_st_X509
,
...
...
This diff is collapsed.
Click to expand it.
openssl/CHANGELOG.md
+
2
−
0
View file @
6018fed2
...
...
@@ -2,6 +2,8 @@
## [Unreleased]
*
Added
`CMS_verify`
.
## [v0.10.45] - 2022-12-20
### Fixed
...
...
This diff is collapsed.
Click to expand it.
openssl/src/cms.rs
+
168
−
2
View file @
6018fed2
...
...
@@ -15,7 +15,7 @@ use crate::error::ErrorStack;
use
crate
::
pkey
::{
HasPrivate
,
PKeyRef
};
use
crate
::
stack
::
StackRef
;
use
crate
::
symm
::
Cipher
;
use
crate
::
x509
::{
X509Ref
,
X509
};
use
crate
::
x509
::{
store
::
X509StoreRef
,
X509Ref
,
X509
};
use
crate
::{
cvt
,
cvt_p
};
use
openssl_macros
::
corresponds
;
...
...
@@ -227,14 +227,65 @@ impl CmsContentInfo {
Ok
(
CmsContentInfo
::
from_ptr
(
cms
))
}
}
/// Verify this CmsContentInfo's signature,
/// This will search the 'certs' list for the signing certificate.
/// Additional certificates, needed for building the certificate chain, may be
/// given in 'store' as well as additional CRLs.
/// A detached signature may be passed in `detached_data`. The signed content
/// without signature, will be copied into output_data if it is present.
///
#[corresponds(CMS_verify)]
pub
fn
verify
(
&
mut
self
,
certs
:
Option
<&
StackRef
<
X509
>>
,
store
:
Option
<&
X509StoreRef
>
,
detached_data
:
Option
<&
[
u8
]
>
,
output_data
:
Option
<&
mut
Vec
<
u8
>>
,
flags
:
CMSOptions
,
)
->
Result
<
(),
ErrorStack
>
{
unsafe
{
let
certs_ptr
=
certs
.map_or
(
ptr
::
null_mut
(),
|
p
|
p
.as_ptr
());
let
store_ptr
=
store
.map_or
(
ptr
::
null_mut
(),
|
p
|
p
.as_ptr
());
let
detached_data_bio
=
match
detached_data
{
Some
(
data
)
=>
Some
(
MemBioSlice
::
new
(
data
)
?
),
None
=>
None
,
};
let
detached_data_bio_ptr
=
detached_data_bio
.as_ref
()
.map_or
(
ptr
::
null_mut
(),
|
p
|
p
.as_ptr
());
let
out_bio
=
MemBio
::
new
()
?
;
cvt
(
ffi
::
CMS_verify
(
self
.as_ptr
(),
certs_ptr
,
store_ptr
,
detached_data_bio_ptr
,
out_bio
.as_ptr
(),
flags
.bits
(),
))
?
;
if
let
Some
(
data
)
=
output_data
{
data
.clear
();
data
.extend_from_slice
(
out_bio
.get_buf
());
};
Ok
(())
}
}
}
#[cfg(test)]
mod
test
{
use
super
::
*
;
use
crate
::
pkcs12
::
Pkcs12
;
use
crate
::
pkey
::
PKey
;
use
crate
::
stack
::
Stack
;
use
crate
::
x509
::
X509
;
use
crate
::
x509
::{
store
::{
X509Store
,
X509StoreBuilder
},
X509
,
};
#[test]
fn
cms_encrypt_decrypt
()
{
...
...
@@ -317,4 +368,119 @@ mod test {
assert_eq!
(
input
,
decrypt_without_cert_check
);
}
}
fn
cms_sign_verify_generic_helper
(
is_detached
:
bool
)
{
// load cert with private key
let
cert_bytes
=
include_bytes!
(
"../test/cert.pem"
);
let
cert
=
X509
::
from_pem
(
cert_bytes
)
.expect
(
"failed to load cert.pem"
);
let
key_bytes
=
include_bytes!
(
"../test/key.pem"
);
let
key
=
PKey
::
private_key_from_pem
(
key_bytes
)
.expect
(
"failed to load key.pem"
);
let
root_bytes
=
include_bytes!
(
"../test/root-ca.pem"
);
let
root
=
X509
::
from_pem
(
root_bytes
)
.expect
(
"failed to load root-ca.pem"
);
// sign cms message using public key cert
let
data
=
b"Hello world!"
;
let
(
opt
,
ext_data
):
(
CMSOptions
,
Option
<&
[
u8
]
>
)
=
if
is_detached
{
(
CMSOptions
::
DETACHED
|
CMSOptions
::
BINARY
,
Some
(
data
))
}
else
{
(
CMSOptions
::
empty
(),
None
)
};
let
mut
cms
=
CmsContentInfo
::
sign
(
Some
(
&
cert
),
Some
(
&
key
),
None
,
Some
(
data
),
opt
)
.expect
(
"failed to CMS sign a message"
);
// check CMS signature length
let
pem_cms
=
cms
.to_pem
()
.expect
(
"failed to pack CmsContentInfo into PEM"
);
assert!
(
!
pem_cms
.is_empty
());
// verify CMS signature
let
mut
builder
=
X509StoreBuilder
::
new
()
.expect
(
"failed to create X509StoreBuilder"
);
builder
.add_cert
(
root
)
.expect
(
"failed to add root-ca into X509StoreBuilder"
);
let
store
:
X509Store
=
builder
.build
();
let
mut
out_data
:
Vec
<
u8
>
=
Vec
::
new
();
let
res
=
cms
.verify
(
None
,
Some
(
&
store
),
ext_data
,
Some
(
&
mut
out_data
),
CMSOptions
::
empty
(),
);
// check verification result - valid signature
res
.unwrap
();
assert_eq!
(
data
.to_vec
(),
out_data
);
}
#[test]
fn
cms_sign_verify_ok
()
{
cms_sign_verify_generic_helper
(
false
);
}
#[test]
fn
cms_sign_verify_detached_ok
()
{
cms_sign_verify_generic_helper
(
true
);
}
#[test]
fn
cms_sign_verify_error
()
{
#[cfg(ossl300)]
let
_provider
=
crate
::
provider
::
Provider
::
try_load
(
None
,
"legacy"
,
true
)
.unwrap
();
// load cert with private key
let
priv_cert_bytes
=
include_bytes!
(
"../test/cms.p12"
);
let
priv_cert
=
Pkcs12
::
from_der
(
priv_cert_bytes
)
.expect
(
"failed to load priv cert"
);
let
priv_cert
=
priv_cert
.parse2
(
"mypass"
)
.expect
(
"failed to parse priv cert"
);
// sign cms message using public key cert
let
data
=
b"Hello world!"
;
let
mut
cms
=
CmsContentInfo
::
sign
(
Some
(
&
priv_cert
.cert
.unwrap
()),
Some
(
&
priv_cert
.pkey
.unwrap
()),
None
,
Some
(
data
),
CMSOptions
::
empty
(),
)
.expect
(
"failed to CMS sign a message"
);
// check CMS signature length
let
pem_cms
=
cms
.to_pem
()
.expect
(
"failed to pack CmsContentInfo into PEM"
);
assert!
(
!
pem_cms
.is_empty
());
let
empty_store
=
X509StoreBuilder
::
new
()
.expect
(
"failed to create X509StoreBuilder"
)
.build
();
// verify CMS signature
let
res
=
cms
.verify
(
None
,
Some
(
&
empty_store
),
Some
(
data
),
None
,
CMSOptions
::
empty
(),
);
// check verification result - this is an invalid signature
// defined in openssl crypto/cms/cms.h
const
CMS_R_CERTIFICATE_VERIFY_ERROR
:
i32
=
100
;
match
res
{
Err
(
es
)
=>
{
let
error_array
=
es
.errors
();
assert_eq!
(
1
,
error_array
.len
());
let
code
=
error_array
[
0
]
.code
();
assert_eq!
(
ffi
::
ERR_GET_REASON
(
code
),
CMS_R_CERTIFICATE_VERIFY_ERROR
);
}
_
=>
panic!
(
"expected CMS verification error, got Ok()"
),
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
sign in
to comment