Skip to content

Commit

Permalink
Merge branch 'main' into sm/SM-1083/dockerfile-as-non-root
Browse files Browse the repository at this point in the history
  • Loading branch information
tangowithfoxtrot committed Feb 1, 2024
2 parents 8618675 + 6749058 commit a2945cb
Show file tree
Hide file tree
Showing 27 changed files with 917 additions and 46 deletions.
94 changes: 90 additions & 4 deletions .github/workflows/publish-python.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,99 @@
---
name: Publish Python SDK
run-name: Publish Python SDK ${{ inputs.release_type }}

on:
workflow_dispatch:
inputs:
release_type:
description: "Release Options"
required: true
default: "Release"
type: choice
options:
- Release
- Dry Run

defaults:
run:
shell: bash

jobs:
stub:
name: Stub
setup:
name: Setup
runs-on: ubuntu-22.04
steps:
- name: Stub
run: echo "Stub"
- name: Checkout repo
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

- name: Branch check
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
run: |
if [[ "$GITHUB_REF" != "refs/heads/rc" ]] && [[ "$GITHUB_REF" != "refs/heads/hotfix-rc" ]]; then
echo "==================================="
echo "[!] Can only release from the 'rc' or 'hotfix-rc' branches"
echo "==================================="
exit 1
fi
publish:
name: Publish
runs-on: ubuntu-22.04
needs: setup
steps:
- name: Install Python
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
with:
python-version: "3.9"

- name: Install twine
run: pip install twine

- name: Download artifacts
uses: dawidd6/action-download-artifact@e7466d1a7587ed14867642c2ca74b5bcc1e19a2d # v3.0.0
with:
workflow: build-python-wheels.yml
path: ${{ github.workspace }}/target/wheels/dist
workflow_conclusion: success
branch: ${{ github.event.inputs.release_type == 'Dry Run' && 'main' || github.ref_name }}
name: bitwarden_sdk(.*)
name_is_regexp: true

- name: Move files
working-directory: ${{ github.workspace }}/target/wheels/dist
run: |
find . -maxdepth 2 -type f -print0 | xargs -0 mv -t .
rm -rf */
- name: Login to Azure
uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
with:
creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}

- name: Retrieve pypi api token
id: retrieve-secret
uses: bitwarden/gh-actions/get-keyvault-secrets@main
with:
keyvault: "bitwarden-ci"
secrets: "pypi-api-token,
pypi-test-api-token"

- name: Check
working-directory: ${{ github.workspace }}/target/wheels
run: twine check dist/*

- name: Publish
if: ${{ github.event.inputs.release_type != 'Dry Run' }}
working-directory: ${{ github.workspace }}/target/wheels
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ steps.retrieve-secret.outputs.pypi-api-token }}
run: twine upload --repository pypi dist/*

- name: Dry Run - Publish
if: ${{ github.event.inputs.release_type == 'Dry Run' }}
working-directory: ${{ github.workspace }}/target/wheels
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ steps.retrieve-secret.outputs.pypi-test-api-token }}
run: twine upload --repository testpypi dist/*
8 changes: 8 additions & 0 deletions .github/workflows/version-bump.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ on:
- bitwarden-json
- cli
- napi
- python-sdk
version_number:
description: "New version (example: '2024.1.0')"
required: true
Expand Down Expand Up @@ -142,6 +143,13 @@ jobs:
if: ${{ inputs.project == 'bitwarden-json' }}
run: cargo-set-version set-version -p bitwarden-json ${{ inputs.version_number }}

### python
- name: Bump python-sdk Version
if: ${{ inputs.project == 'python-sdk' }}
run: |
sed -i 's/version = "[0-9]\.[0-9]\.[0-9]"/version = "${{ inputs.version_number }}"/' ./languages/python/pyproject.toml
sed -i 's/__version__ = "[0-9]\.[0-9]\.[0-9]"/__version__ = "${{ inputs.version_number }}"/' ./languages/python/bitwarden_sdk/__init__.py
############################
# VERSION BUMP SECTION END #
############################
Expand Down
12 changes: 12 additions & 0 deletions .github/workflows/workflow-linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
name: Workflow linter

on:
pull_request:
paths:
- .github/workflows/**

jobs:
call-workflow:
name: Lint
uses: bitwarden/gh-actions/.github/workflows/workflow-linter.yml@main
1 change: 1 addition & 0 deletions Cargo.lock

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

33 changes: 33 additions & 0 deletions crates/bitwarden-crypto/src/enc_string/asymmetric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ impl schemars::JsonSchema for AsymmetricEncString {

#[cfg(test)]
mod tests {
use schemars::schema_for;

use super::{AsymmetricCryptoKey, AsymmetricEncString, KeyDecryptable};

const RSA_PRIVATE_KEY: &str = "-----BEGIN PRIVATE KEY-----
Expand Down Expand Up @@ -288,4 +290,35 @@ XKZBokBGnjFnTnKcs7nv/O8=
assert_eq!(t.key.to_string(), cipher);
assert_eq!(serde_json::to_string(&t).unwrap(), serialized);
}

#[test]
fn test_from_str_invalid() {
let enc_str = "7.ABC";
let enc_string: Result<AsymmetricEncString, _> = enc_str.parse();

let err = enc_string.unwrap_err();
assert_eq!(
err.to_string(),
"EncString error, Invalid asymmetric type, got type 7 with 1 parts"
);
}

#[test]
fn test_debug_format() {
let enc_str: &str = "4.ZheRb3PCfAunyFdQYPfyrFqpuvmln9H9w5nDjt88i5A7ug1XE0LJdQHCIYJl0YOZ1gCOGkhFu/CRY2StiLmT3iRKrrVBbC1+qRMjNNyDvRcFi91LWsmRXhONVSPjywzrJJXglsztDqGkLO93dKXNhuKpcmtBLsvgkphk/aFvxbaOvJ/FHdK/iV0dMGNhc/9tbys8laTdwBlI5xIChpRcrfH+XpSFM88+Bu03uK67N9G6eU1UmET+pISJwJvMuIDMqH+qkT7OOzgL3t6I0H2LDj+CnsumnQmDsvQzDiNfTR0IgjpoE9YH2LvPXVP2wVUkiTwXD9cG/E7XeoiduHyHjw==";
let enc_string: AsymmetricEncString = enc_str.parse().unwrap();

let debug_string = format!("{:?}", enc_string);
assert_eq!(debug_string, "AsymmetricEncString");
}

#[test]
fn test_json_schema() {
let schema = schema_for!(AsymmetricEncString);

assert_eq!(
serde_json::to_string(&schema).unwrap(),
r#"{"$schema":"http://json-schema.org/draft-07/schema#","title":"AsymmetricEncString","type":"string"}"#
);
}
}
53 changes: 53 additions & 0 deletions crates/bitwarden-crypto/src/enc_string/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,56 @@ where
T::from_str(v).map_err(|e| E::custom(format!("{:?}", e)))
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_check_length_less_than_expected() {
let buf = [1, 2, 3];
let expected = 5;
let result = check_length(&buf, expected);
assert!(result.is_err());
}

#[test]
fn test_check_length_equal_to_expected() {
let buf = [1, 2, 3, 4, 5];
let expected = 5;
let result = check_length(&buf, expected);
assert!(result.is_ok());
}

#[test]
fn test_check_length_greater_than_expected() {
let buf = [1, 2, 3, 4, 5, 6];
let expected = 5;
let result = check_length(&buf, expected);
assert!(result.is_ok());
}

#[test]
fn test_split_enc_string_new_format() {
let s = "2.abc|def|ghi";
let (header, parts) = split_enc_string(s);
assert_eq!(header, "2");
assert_eq!(parts, vec!["abc", "def", "ghi"]);
}

#[test]
fn test_split_enc_string_old_format_three_parts() {
let s = "abc|def|ghi";
let (header, parts) = split_enc_string(s);
assert_eq!(header, "1");
assert_eq!(parts, vec!["abc", "def", "ghi"]);
}

#[test]
fn test_split_enc_string_old_format_fewer_parts() {
let s = "abc|def";
let (header, parts) = split_enc_string(s);
assert_eq!(header, "0");
assert_eq!(parts, vec!["abc", "def"]);
}
}
76 changes: 76 additions & 0 deletions crates/bitwarden-crypto/src/enc_string/symmetric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ impl schemars::JsonSchema for EncString {

#[cfg(test)]
mod tests {
use schemars::schema_for;

use super::EncString;
use crate::{derive_symmetric_key, KeyDecryptable, KeyEncryptable};

Expand Down Expand Up @@ -325,4 +327,78 @@ mod tests {

assert_eq!(enc_string_new.to_string(), enc_str)
}

#[test]
fn test_from_str_cbc256() {
let enc_str = "0.pMS6/icTQABtulw52pq2lg==|XXbxKxDTh+mWiN1HjH2N1w==";
let enc_string: EncString = enc_str.parse().unwrap();

assert_eq!(enc_string.enc_type(), 0);
if let EncString::AesCbc256_B64 { iv, data } = &enc_string {
assert_eq!(
iv,
&[164, 196, 186, 254, 39, 19, 64, 0, 109, 186, 92, 57, 218, 154, 182, 150]
);
assert_eq!(
data,
&[93, 118, 241, 43, 16, 211, 135, 233, 150, 136, 221, 71, 140, 125, 141, 215]
);
}
}

#[test]
fn test_from_str_cbc128_hmac() {
let enc_str = "1.Hh8gISIjJCUmJygpKissLQ==|MjM0NTY3ODk6Ozw9Pj9AQUJDREU=|KCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkc=";
let enc_string: EncString = enc_str.parse().unwrap();

assert_eq!(enc_string.enc_type(), 1);
if let EncString::AesCbc128_HmacSha256_B64 { iv, mac, data } = &enc_string {
assert_eq!(
iv,
&[30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45]
);
assert_eq!(
mac,
&[
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71
]
);
assert_eq!(
data,
&[50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69]
);
}
}

#[test]
fn test_from_str_invalid() {
let enc_str = "7.ABC";
let enc_string: Result<EncString, _> = enc_str.parse();

let err = enc_string.unwrap_err();
assert_eq!(
err.to_string(),
"EncString error, Invalid symmetric type, got type 7 with 1 parts"
);
}

#[test]
fn test_debug_format() {
let enc_str = "2.pMS6/icTQABtulw52pq2lg==|XXbxKxDTh+mWiN1HjH2N1w==|Q6PkuT+KX/axrgN9ubD5Ajk2YNwxQkgs3WJM0S0wtG8=";
let enc_string: EncString = enc_str.parse().unwrap();

let debug_string = format!("{:?}", enc_string);
assert_eq!(debug_string, "EncString");
}

#[test]
fn test_json_schema() {
let schema = schema_for!(EncString);

assert_eq!(
serde_json::to_string(&schema).unwrap(),
r#"{"$schema":"http://json-schema.org/draft-07/schema#","title":"EncString","type":"string"}"#
);
}
}
4 changes: 4 additions & 0 deletions crates/bitwarden-crypto/src/keys/master_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ pub enum HashPurpose {
pub struct MasterKey(SymmetricCryptoKey);

impl MasterKey {
pub fn new(key: SymmetricCryptoKey) -> MasterKey {
Self(key)
}

/// Derives a users master key from their password, email and KDF.
pub fn derive(password: &[u8], email: &[u8], kdf: &Kdf) -> Result<Self> {
derive_key(password, email, kdf).map(Self)
Expand Down
15 changes: 14 additions & 1 deletion crates/bitwarden-uniffi/src/crypto.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::sync::Arc;

use bitwarden::mobile::crypto::{
DerivePinKeyResponse, InitOrgCryptoRequest, InitUserCryptoRequest,
DerivePinKeyResponse, InitOrgCryptoRequest, InitUserCryptoRequest, UpdatePasswordResponse,
};
use bitwarden_crypto::EncString;

Expand Down Expand Up @@ -51,6 +51,19 @@ impl ClientCrypto {
.await?)
}

/// Update the user's password, which will re-encrypt the user's encryption key with the new
/// password. This returns the new encrypted user key and the new password hash.
pub async fn update_password(&self, new_password: String) -> Result<UpdatePasswordResponse> {
Ok(self
.0
.0
.write()
.await
.crypto()
.update_password(new_password)
.await?)
}

/// Generates a PIN protected user key from the provided PIN. The result can be stored and later
/// used to initialize another client instance by using the PIN and the PIN key with
/// `initialize_user_crypto`.
Expand Down
1 change: 1 addition & 0 deletions crates/bitwarden/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,4 @@ reqwest = { version = "*", features = [
rand_chacha = "0.3.1"
tokio = { version = "1.35.1", features = ["rt", "macros"] }
wiremock = "0.5.22"
zeroize = { version = ">=1.7.0, <2.0", features = ["derive", "aarch64"] }
Loading

0 comments on commit a2945cb

Please sign in to comment.