• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Licensed under the Apache License, Version 2.0 (the "License");
2 // you may not use this file except in compliance with the License.
3 // You may obtain a copy of the License at
4 //
5 //     http://www.apache.org/licenses/LICENSE-2.0
6 //
7 // Unless required by applicable law or agreed to in writing, software
8 // distributed under the License is distributed on an "AS IS" BASIS,
9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 // See the License for the specific language governing permissions and
11 // limitations under the License.
12 //
13 
14 //! Build and version information.
15 
16 use cfg_if::cfg_if;
17 use openssl_macros::corresponds;
18 use std::ffi::CStr;
19 
20 cfg_if! {
21     if #[cfg(any(ossl110, libressl271))] {
22         use ffi::{
23             OPENSSL_VERSION, OPENSSL_CFLAGS, OPENSSL_BUILT_ON, OPENSSL_PLATFORM, OPENSSL_DIR,
24             OpenSSL_version_num, OpenSSL_version,
25         };
26     } else {
27         use ffi::{
28             SSLEAY_VERSION as OPENSSL_VERSION, SSLEAY_CFLAGS as OPENSSL_CFLAGS,
29             SSLEAY_BUILT_ON as OPENSSL_BUILT_ON, SSLEAY_PLATFORM as OPENSSL_PLATFORM,
30             SSLEAY_DIR as OPENSSL_DIR, SSLeay as OpenSSL_version_num,
31             SSLeay_version as OpenSSL_version,
32         };
33     }
34 }
35 
36 /// OPENSSL_VERSION_NUMBER is a numeric release version identifier:
37 ///
38 /// `MNNFFPPS: major minor fix patch status`
39 ///
40 /// The status nibble has one of the values 0 for development, 1 to e for betas 1 to 14, and f for release.
41 ///
42 /// for example
43 ///
44 /// `0x000906000 == 0.9.6 dev`
45 /// `0x000906023 == 0.9.6b beta 3`
46 /// `0x00090605f == 0.9.6e release`
47 #[corresponds(OpenSSL_version_num)]
number() -> i6448 pub fn number() -> i64 {
49     unsafe { OpenSSL_version_num() as i64 }
50 }
51 
52 /// The text variant of the version number and the release date. For example, "OpenSSL 0.9.5a 1 Apr 2000".
53 #[corresponds(OpenSSL_version)]
version() -> &'static str54 pub fn version() -> &'static str {
55     unsafe {
56         CStr::from_ptr(OpenSSL_version(OPENSSL_VERSION))
57             .to_str()
58             .unwrap()
59     }
60 }
61 
62 /// The compiler flags set for the compilation process in the form "compiler: ..." if available or
63 /// "compiler: information not available" otherwise.
64 #[corresponds(OpenSSL_version)]
c_flags() -> &'static str65 pub fn c_flags() -> &'static str {
66     unsafe {
67         CStr::from_ptr(OpenSSL_version(OPENSSL_CFLAGS))
68             .to_str()
69             .unwrap()
70     }
71 }
72 
73 /// The date of the build process in the form "built on: ..." if available or "built on: date not available" otherwise.
74 #[corresponds(OpenSSL_version)]
built_on() -> &'static str75 pub fn built_on() -> &'static str {
76     unsafe {
77         CStr::from_ptr(OpenSSL_version(OPENSSL_BUILT_ON))
78             .to_str()
79             .unwrap()
80     }
81 }
82 
83 /// The "Configure" target of the library build in the form "platform: ..." if available or "platform: information not available" otherwise.
84 #[corresponds(OpenSSL_version)]
platform() -> &'static str85 pub fn platform() -> &'static str {
86     unsafe {
87         CStr::from_ptr(OpenSSL_version(OPENSSL_PLATFORM))
88             .to_str()
89             .unwrap()
90     }
91 }
92 
93 /// The "OPENSSLDIR" setting of the library build in the form "OPENSSLDIR: "..."" if available or "OPENSSLDIR: N/A" otherwise.
94 #[corresponds(OpenSSL_version)]
dir() -> &'static str95 pub fn dir() -> &'static str {
96     unsafe {
97         CStr::from_ptr(OpenSSL_version(OPENSSL_DIR))
98             .to_str()
99             .unwrap()
100     }
101 }
102 
103 /// This test ensures that we do not segfault when calling the functions of this module
104 /// and that the strings respect a reasonable format.
105 #[test]
test_versions()106 fn test_versions() {
107     println!("Number: '{}'", number());
108     println!("Version: '{}'", version());
109     println!("C flags: '{}'", c_flags());
110     println!("Built on: '{}'", built_on());
111     println!("Platform: '{}'", platform());
112     println!("Dir: '{}'", dir());
113 
114     #[cfg(not(any(libressl, boringssl)))]
115     fn expected_name() -> &'static str {
116         "OpenSSL"
117     }
118     #[cfg(libressl)]
119     fn expected_name() -> &'static str {
120         "LibreSSL"
121     }
122     #[cfg(boringssl)]
123     fn expected_name() -> &'static str {
124         "BoringSSL"
125     }
126 
127     assert!(number() > 0);
128     assert!(version().starts_with(expected_name()));
129     assert!(c_flags().starts_with("compiler:"));
130     // some distributions patch out dates out of openssl so that the builds are reproducible
131     if !built_on().is_empty() {
132         assert!(built_on().starts_with("built on:"));
133     }
134     assert!(dir().starts_with("OPENSSLDIR:"));
135 }
136