Skip to content

Commit

Permalink
Merge branch 'main' into tob-x509-cv-skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
woodruffw committed May 10, 2023
2 parents 42400d5 + 1ff6208 commit 212a651
Show file tree
Hide file tree
Showing 17 changed files with 208 additions and 74 deletions.
4 changes: 2 additions & 2 deletions .github/actions/cache/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ runs:
~/.cargo/registry/cache/
src/rust/target/
${{ inputs.additional-paths }}
key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock') }}-${{ steps.rust-version.version }}
key: cargo-pip-${{ runner.os }}-${{ runner.arch }}-${{ inputs.key }}-3-${{ hashFiles('**/Cargo.lock', '**/*.rs') }}-${{ steps.rust-version.version }}
- name: Size of cache items
run: |
du -sh ~/.cargo/registry/index/
du -sh ~/.cargo/registry/cache/
du -sh src/rust/target/
shell: bash
if: ${{ steps.cache.outputs.cache-hit }}
if: ${{ steps.cache.outputs.cache-hit }}
20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ jobs:
- {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "libressl", VERSION: "3.7.2"}}
- {VERSION: "3.11", NOXSESSION: "tests-randomorder"}
- {VERSION: "3.12-dev", NOXSESSION: "tests"}
# Latest commit on the BoringSSL master branch, as of May 06, 2023.
- {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "b1c6f45f1fe6d808555d04a41bb44b322e4f4c1d"}}
# Latest commit on the OpenSSL master branch, as of May 06, 2023.
- {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "6aeb42eca97227c8235af0986d1525ee4a916504"}}
# Latest commit on the BoringSSL master branch, as of May 09, 2023.
- {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "boringssl", VERSION: "2aae3f58b42e75690f28853f712a2e204857b7f6"}}
# Latest commit on the OpenSSL master branch, as of May 10, 2023.
- {VERSION: "3.11", NOXSESSION: "tests", OPENSSL: {TYPE: "openssl", VERSION: "8c63b14296f117b07781509ced529a8955d78fb9"}}
timeout-minutes: 15
steps:
- uses: actions/checkout@v3.5.2
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
# pypy3-3.8 and pypy3-3.9 -- both of them show up as 7.3.11.
key: ${{ matrix.PYTHON.VERSION }}-${{ steps.setup-python.outputs.python-version }}-${{ matrix.PYTHON.NOXSESSION }}-${{ env.OPENSSL_HASH }}

- run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml]
- run: python -m pip install -c ci-constraints-requirements.txt 'nox'
- name: Create nox environment
run: |
nox -v --install-only
Expand Down Expand Up @@ -182,7 +182,7 @@ jobs:
- run: |
echo "OPENSSL_FORCE_FIPS_MODE=1" >> $GITHUB_ENV
if: matrix.IMAGE.FIPS
- run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox' coverage
- run: /venv/bin/python -m pip install -c ci-constraints-requirements.txt 'nox'
- run: '/venv/bin/nox -v --install-only -s tests'
env:
RUSTUP_HOME: /root/.rustup
Expand Down Expand Up @@ -229,7 +229,7 @@ jobs:
- name: Clone wycheproof
timeout-minutes: 2
uses: ./.github/actions/wycheproof
- run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml]
- run: python -m pip install -c ci-constraints-requirements.txt 'nox'
- name: Create nox environment
run: nox -v --install-only -s tests
env:
Expand Down Expand Up @@ -304,7 +304,7 @@ jobs:
- name: Clone wycheproof
timeout-minutes: 2
uses: ./.github/actions/wycheproof
- run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml] cffi
- run: python -m pip install -c ci-constraints-requirements.txt 'nox' cffi
- name: Create nox environment
run: nox -v --install-only -s tests
env:
Expand Down Expand Up @@ -379,7 +379,7 @@ jobs:
python-version: ${{ matrix.PYTHON.VERSION }}
architecture: 'x64' # we force this right now so that it will install the universal2 on arm64

- run: python -m pip install -c ci-constraints-requirements.txt 'nox' coverage[toml]
- run: python -m pip install -c ci-constraints-requirements.txt 'nox'

- name: Clone wycheproof
timeout-minutes: 2
Expand Down Expand Up @@ -442,7 +442,7 @@ jobs:
timeout-minutes: 2
with:
key: ${{ matrix.PYTHON.NOXSESSION }}-${{ matrix.WINDOWS.ARCH }}-${{ steps.setup-python.outputs.python-version }}
- run: python -m pip install -c ci-constraints-requirements.txt "nox" coverage[toml]
- run: python -m pip install -c ci-constraints-requirements.txt "nox"

- uses: dawidd6/action-download-artifact@246dbf436b23d7c49e21a7ab8204ca9ecd1fe615
with:
Expand Down
4 changes: 2 additions & 2 deletions src/rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/rust/cryptography-cffi/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
// FIXME: maybe pyo3-build-config should provide a way to do this?
let python = env::var("PYO3_PYTHON").unwrap_or_else(|_| "python3".to_string());
println!("cargo:rerun-if-env-changed=PYO3_PYTHON");
println!("cargo:rerun-if-changed=../../_cffi_src/");
let output = Command::new(&python)
.env("OUT_DIR", &out_dir)
Expand Down
9 changes: 8 additions & 1 deletion src/rust/cryptography-x509/src/certificate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use crate::common;
use crate::extensions;
use crate::extensions::Extensions;
use crate::name;

#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)]
Expand Down Expand Up @@ -31,7 +32,13 @@ pub struct TbsCertificate<'a> {
#[implicit(2)]
pub subject_unique_id: Option<asn1::BitString<'a>>,
#[explicit(3)]
pub extensions: Option<extensions::Extensions<'a>>,
pub raw_extensions: Option<extensions::RawExtensions<'a>>,
}

impl<'a> TbsCertificate<'a> {
pub fn extensions(&'a self) -> Result<Option<Extensions<'a>>, asn1::ObjectIdentifier> {
Extensions::from_raw_extensions(self.raw_extensions.as_ref())
}
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, Hash, PartialEq, Clone)]
Expand Down
10 changes: 7 additions & 3 deletions src/rust/cryptography-x509/src/crl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::{common, extensions, name};
use crate::{
common,
extensions::{self},
name,
};

pub type ReasonFlags<'a> =
Option<common::Asn1ReadableOrWritable<'a, asn1::BitString<'a>, asn1::OwnedBitString>>;
Expand Down Expand Up @@ -31,14 +35,14 @@ pub struct TBSCertList<'a> {
pub next_update: Option<common::Time>,
pub revoked_certificates: RevokedCertificates<'a>,
#[explicit(0)]
pub crl_extensions: Option<extensions::Extensions<'a>>,
pub raw_crl_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Hash, Clone)]
pub struct RevokedCertificate<'a> {
pub user_certificate: asn1::BigUint<'a>,
pub revocation_date: common::Time,
pub crl_entry_extensions: Option<extensions::Extensions<'a>>,
pub raw_crl_entry_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
Expand Down
2 changes: 1 addition & 1 deletion src/rust/cryptography-x509/src/csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct CertificationRequestInfo<'a> {
impl CertificationRequestInfo<'_> {
pub fn get_extension_attribute(
&self,
) -> Result<Option<extensions::Extensions<'_>>, asn1::ParseError> {
) -> Result<Option<extensions::RawExtensions<'_>>, asn1::ParseError> {
for attribute in self.attributes.unwrap_read().clone() {
if attribute.type_id == oid::EXTENSION_REQUEST
|| attribute.type_id == oid::MS_EXTENSION_REQUEST
Expand Down
83 changes: 82 additions & 1 deletion src/rust/cryptography-x509/src/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,62 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use std::collections::HashSet;

use crate::common;
use crate::crl;
use crate::name;

pub type Extensions<'a> = common::Asn1ReadableOrWritable<
pub type RawExtensions<'a> = common::Asn1ReadableOrWritable<
'a,
asn1::SequenceOf<'a, Extension<'a>>,
asn1::SequenceOfWriter<'a, Extension<'a>, Vec<Extension<'a>>>,
>;

/// An invariant-enforcing wrapper for `RawExtensions`.
///
/// In particular, an `Extensions` cannot be constructed from a `RawExtensions`
/// that contains duplicated extensions (by OID).
pub struct Extensions<'a>(RawExtensions<'a>);

impl<'a> Extensions<'a> {
/// Create an `Extensions` from the given `RawExtensions`.
///
/// Returns an `Err` variant containing the first duplicated extension's
/// OID, if there are any duplicates.
pub fn from_raw_extensions(
raw: Option<&RawExtensions<'a>>,
) -> Result<Option<Self>, asn1::ObjectIdentifier> {
match raw {
Some(raw_exts) => {
let mut seen_oids = HashSet::new();

for ext in raw_exts.unwrap_read().clone() {
if !seen_oids.insert(ext.extn_id.clone()) {
return Err(ext.extn_id);
}
}

Ok(Some(Self(raw_exts.clone())))
}
None => Ok(None),
}
}

/// Retrieves the extension identified by the given OID,
/// or None if the extension is not present (or no extensions are present).
pub fn get_extension(&self, oid: &asn1::ObjectIdentifier) -> Option<Extension> {
let mut extensions = self.0.unwrap_read().clone();

extensions.find(|ext| &ext.extn_id == oid)
}

/// Returns a reference to the underlying extensions.
pub fn as_raw(&self) -> &RawExtensions<'_> {
&self.0
}
}

#[derive(asn1::Asn1Read, asn1::Asn1Write, PartialEq, Eq, Hash, Clone)]
pub struct Extension<'a> {
pub extn_id: asn1::ObjectIdentifier,
Expand Down Expand Up @@ -174,3 +220,38 @@ pub struct BasicConstraints {
pub ca: bool,
pub path_length: Option<u64>,
}

#[cfg(test)]
mod tests {
use asn1::SequenceOfWriter;

use crate::oid::{AUTHORITY_KEY_IDENTIFIER_OID, BASIC_CONSTRAINTS_OID};

use super::{BasicConstraints, Extension, Extensions};

#[test]
fn test_get_extension() {
let extension_value = BasicConstraints {
ca: true,
path_length: Some(3),
};
let extension = Extension {
extn_id: BASIC_CONSTRAINTS_OID,
critical: true,
extn_value: &asn1::write_single(&extension_value).unwrap(),
};
let extensions = SequenceOfWriter::new(vec![extension]);

let der = asn1::write_single(&extensions).unwrap();

let extensions: Extensions =
Extensions::from_raw_extensions(Some(&asn1::parse_single(&der).unwrap()))
.unwrap()
.unwrap();

assert!(&extensions.get_extension(&BASIC_CONSTRAINTS_OID).is_some());
assert!(&extensions
.get_extension(&AUTHORITY_KEY_IDENTIFIER_OID)
.is_none());
}
}
10 changes: 7 additions & 3 deletions src/rust/cryptography-x509/src/ocsp_req.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::{common, extensions, name};
use crate::{
common,
extensions::{self},
name,
};

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct TBSRequest<'a> {
Expand All @@ -17,14 +21,14 @@ pub struct TBSRequest<'a> {
asn1::SequenceOfWriter<'a, Request<'a>>,
>,
#[explicit(2)]
pub request_extensions: Option<extensions::Extensions<'a>>,
pub raw_request_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct Request<'a> {
pub req_cert: CertID<'a>,
#[explicit(0)]
pub single_request_extensions: Option<extensions::Extensions<'a>>,
pub single_request_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
Expand Down
10 changes: 7 additions & 3 deletions src/rust/cryptography-x509/src/ocsp_resp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
// 2.0, and the BSD License. See the LICENSE file in the root of this repository
// for complete details.

use crate::{certificate, common, crl, extensions, name, ocsp_req};
use crate::{
certificate, common, crl,
extensions::{self},
name, ocsp_req,
};

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
pub struct OCSPResponse<'a> {
Expand Down Expand Up @@ -47,7 +51,7 @@ pub struct ResponseData<'a> {
asn1::SequenceOfWriter<'a, SingleResponse<'a>, Vec<SingleResponse<'a>>>,
>,
#[explicit(1)]
pub response_extensions: Option<extensions::Extensions<'a>>,
pub raw_response_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
Expand All @@ -66,7 +70,7 @@ pub struct SingleResponse<'a> {
#[explicit(0)]
pub next_update: Option<asn1::GeneralizedTime>,
#[explicit(1)]
pub single_extensions: Option<extensions::Extensions<'a>>,
pub raw_single_extensions: Option<extensions::RawExtensions<'a>>,
}

#[derive(asn1::Asn1Read, asn1::Asn1Write)]
Expand Down
Loading

0 comments on commit 212a651

Please sign in to comment.