openssl/
version.rs

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
16use cfg_if::cfg_if;
17use openssl_macros::corresponds;
18use std::ffi::CStr;
19
20cfg_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)]
48pub 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)]
54pub 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)]
65pub 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)]
75pub 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)]
85pub 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)]
95pub 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]
106fn 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, awslc)))]
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    #[cfg(awslc)]
127    fn expected_name() -> &'static str {
128        "AWS-LC"
129    }
130
131    assert!(number() > 0);
132    assert!(version().starts_with(expected_name()));
133    assert!(c_flags().starts_with("compiler:"));
134    // some distributions patch out dates out of openssl so that the builds are reproducible
135    if !built_on().is_empty() {
136        assert!(built_on().starts_with("built on:"));
137    }
138}