Skip to content

Commit

Permalink
add the payload version and separators to the signed payload
Browse files Browse the repository at this point in the history
  • Loading branch information
Geal committed Nov 10, 2024
1 parent d939bc9 commit 4c2b1ad
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 100 deletions.
117 changes: 45 additions & 72 deletions biscuit-auth/samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1835,7 +1835,7 @@ allow if true;

revocation ids:
- `470e4bf7aa2a01ab39c98150bd06aa15b4aa5d86509044a8809a8634cd8cf2b42269a51a774b65d10bac9369d013070b00187925196a8e680108473f11cf8f03`
- `f599b64287ccd9adbe007d5cdbd0cfa572f5f73495c95594b1bbbe938c011dc6683c52ba0354cdc4970405c6c318aef8271e6e802a7fb34eb07dd2c2d50d5707`
- `8556bc91ed8bd1e4c0b6b37bead75d91d332c4144d72e7db715e6300732dc691dbd1f444f1a7a07be8bac60358bf14330b5b8963685490cfb648df879efc9e0a`

authorizer world:
```
Expand Down Expand Up @@ -2097,9 +2097,9 @@ allow if true;

revocation ids:
- `3771cefe71beb21ead35a59c8116ee82627a5717c0295f35980662abccb159fe1b37848cb1818e548656bd4fd882d0094a2daab631c76b2b72e3a093914bfe04`
- `fbd926ee447865f2fafdc431273cce2b32005802cb8d268c2ed54cb897fb5ad25f9765aaf79188b6703cdecccc654e6906724d978da4360a36ddf3bb638c8700`
- `6e36db11093148c577c737067b5918b02e8db3fc8990755e2d2ab44d6a48f6694a31ce8fdcb6d811cc81ba3b6db2dce53abae52900d1d3984ad7875438a7f401`
- `4522a4b94bce9265c6962f9784fb971d36b400adbae30f444b7ab91d91c91eff4830e4e6d8da97dddea4399217342b0b600ecccb928678729c8d388e0285c904`
- `87ce330211e0bca95aebcbbe349c954473f49e6593b6fee34f2be93122d4f930f0fc2dedfc1721b9d2e5346befb97aef75c28a13cc2647bb99e499ceb565470d`
- `f3dc02647a3c011e87dda6050fbd67c2e037454f186eb4ba0c029c0da7b0eb309c7d24ad5f073571b11876ef9bb7955ecb462c00457a258c4e1ba4eafbae420c`
- `88c9eea7c2e17409ce542a0e8fe78c53627fc2346ffde3d8d280eb86250c6c84efa5d84ea1f644a7bcfdfc68e2efc07350132c7fc80061014fa9d678c201b20a`
- `3f675d6c364e06405d4868c904e40f3d81c32b083d91586db814d4cb4bf536b4ba209d82f11b4cb6da293b60b20d6122fc3e0e08e80c381dee83edd848211900`

authorizer world:
Expand Down Expand Up @@ -2657,97 +2657,70 @@ result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedB
### token

authority:
symbols: ["fact", "value", "fact2"]
symbols: ["abcD12", "abcD12x"]

public keys: []

```
check if fact(1, $value), 1 == $value;
check if fact2(1, $value), 1 != $value;
check if true == true;
check if false != false;
check if 1 != true;
check if 1 == 1;
check if 1 != 3;
check if 1 != true;
check if "abcD12" == "abcD12";
check if "abcD12x" != "abcD12";
check if "abcD12x" != true;
check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z;
check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z;
check if 2022-12-04T09:46:41Z != true;
check if hex:12abcd == hex:12abcd;
check if hex:12abcd != hex:12ab;
check if hex:12abcd != true;
check if {1, 2} == {1, 2};
check if {1, 4} != {1, 2};
check if {1, 4} != true;
```

### validation for "authorized same type"

authorizer code:
```
fact(1, 1);
fact2(1, 2);
allow if true;
```

revocation ids:
- `d65b3aeceb6268124190f5eb87788a5eb81c89a3fc8370c9a3ea362731c55660b2b390ca6270e68afab90862bd2bbb808aa6b5576c975ae773a992a2434c930d`

authorizer world:
```
World {
facts: [
Facts {
origin: {
None,
},
facts: [
"fact(1, 1)",
"fact2(1, 2)",
],
},
]
rules: []
checks: [
Checks {
origin: Some(
0,
),
checks: [
"check if fact(1, $value), 1 == $value",
"check if fact2(1, $value), 1 != $value",
],
},
]
policies: [
"allow if true",
]
}
```

result: `Ok(0)`
### validation for "unauthorized failed logic different type"
### validation

authorizer code:
```
fact(1, true);
fact2(1, false);
allow if true;
```

revocation ids:
- `d65b3aeceb6268124190f5eb87788a5eb81c89a3fc8370c9a3ea362731c55660b2b390ca6270e68afab90862bd2bbb808aa6b5576c975ae773a992a2434c930d`
- `4af245a2504ec00809bd0cd8d20ceaaac35f8ec5aaa8c7d3fd6652b126d2bf246d64fec8f0e65c409b196d4a60c9723dd4fbb3328988790e97fc4e08e9528208`

authorizer world:
```
World {
facts: [
Facts {
origin: {
None,
},
facts: [
"fact(1, true)",
"fact2(1, false)",
],
},
]
facts: []
rules: []
checks: [
Checks {
origin: Some(
0,
),
checks: [
"check if fact(1, $value), 1 == $value",
"check if fact2(1, $value), 1 != $value",
"check if \"abcD12\" == \"abcD12\"",
"check if \"abcD12x\" != \"abcD12\"",
"check if \"abcD12x\" != true",
"check if 1 != 3",
"check if 1 != true",
"check if 1 != true",
"check if 1 == 1",
"check if 2022-12-04T09:46:41Z != 2020-12-04T09:46:41Z",
"check if 2022-12-04T09:46:41Z != true",
"check if 2022-12-04T09:46:41Z == 2022-12-04T09:46:41Z",
"check if false != false",
"check if hex:12abcd != hex:12ab",
"check if hex:12abcd != true",
"check if hex:12abcd == hex:12abcd",
"check if true == true",
"check if {1, 2} == {1, 2}",
"check if {1, 4} != true",
"check if {1, 4} != {1, 2}",
],
},
]
Expand All @@ -2757,7 +2730,7 @@ World {
}
```

result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 0, rule: "check if fact(1, $value), 1 == $value" })] }))`
result: `Err(FailedLogic(Unauthorized { policy: Allow(0), checks: [Block(FailedBlockCheck { block_id: 0, check_id: 1, rule: "check if false != false" })] }))`


------------------------------
Expand Down
8 changes: 4 additions & 4 deletions biscuit-auth/samples/samples.json
Original file line number Diff line number Diff line change
Expand Up @@ -1795,7 +1795,7 @@
"authorizer_code": "allow if true;\n",
"revocation_ids": [
"470e4bf7aa2a01ab39c98150bd06aa15b4aa5d86509044a8809a8634cd8cf2b42269a51a774b65d10bac9369d013070b00187925196a8e680108473f11cf8f03",
"f599b64287ccd9adbe007d5cdbd0cfa572f5f73495c95594b1bbbe938c011dc6683c52ba0354cdc4970405c6c318aef8271e6e802a7fb34eb07dd2c2d50d5707"
"8556bc91ed8bd1e4c0b6b37bead75d91d332c4144d72e7db715e6300732dc691dbd1f444f1a7a07be8bac60358bf14330b5b8963685490cfb648df879efc9e0a"
]
}
}
Expand Down Expand Up @@ -2087,9 +2087,9 @@
"authorizer_code": "check if query(1, 2) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189, ed25519/a060270db7e9c9f06e8f9cc33a64e99f6596af12cb01c4b638df8afc7b642463;\n\ndeny if query(3);\ndeny if query(1, 2);\ndeny if query(0) trusting ed25519/acdd6d5b53bfee478bf689f8e012fe7988bf755e3d7c5152947abc149bc20189;\nallow if true;\n",
"revocation_ids": [
"3771cefe71beb21ead35a59c8116ee82627a5717c0295f35980662abccb159fe1b37848cb1818e548656bd4fd882d0094a2daab631c76b2b72e3a093914bfe04",
"fbd926ee447865f2fafdc431273cce2b32005802cb8d268c2ed54cb897fb5ad25f9765aaf79188b6703cdecccc654e6906724d978da4360a36ddf3bb638c8700",
"6e36db11093148c577c737067b5918b02e8db3fc8990755e2d2ab44d6a48f6694a31ce8fdcb6d811cc81ba3b6db2dce53abae52900d1d3984ad7875438a7f401",
"4522a4b94bce9265c6962f9784fb971d36b400adbae30f444b7ab91d91c91eff4830e4e6d8da97dddea4399217342b0b600ecccb928678729c8d388e0285c904",
"87ce330211e0bca95aebcbbe349c954473f49e6593b6fee34f2be93122d4f930f0fc2dedfc1721b9d2e5346befb97aef75c28a13cc2647bb99e499ceb565470d",
"f3dc02647a3c011e87dda6050fbd67c2e037454f186eb4ba0c029c0da7b0eb309c7d24ad5f073571b11876ef9bb7955ecb462c00457a258c4e1ba4eafbae420c",
"88c9eea7c2e17409ce542a0e8fe78c53627fc2346ffde3d8d280eb86250c6c84efa5d84ea1f644a7bcfdfc68e2efc07350132c7fc80061014fa9d678c201b20a",
"3f675d6c364e06405d4868c904e40f3d81c32b083d91586db814d4cb4bf536b4ba209d82f11b4cb6da293b60b20d6122fc3e0e08e80c381dee83edd848211900"
]
}
Expand Down
Binary file modified biscuit-auth/samples/test024_third_party.bc
Binary file not shown.
Binary file modified biscuit-auth/samples/test026_public_keys_interning.bc
Binary file not shown.
48 changes: 33 additions & 15 deletions biscuit-auth/src/crypto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ pub fn verify_block_signature(
public_key,
previous_signature,
external_signature,
block.version,
verification_mode,
)?;
}
Expand All @@ -292,14 +293,31 @@ pub fn verify_external_signature(
public_key: &PublicKey,
previous_signature: Option<&Signature>,
external_signature: &ExternalSignature,
version: u32,
verification_mode: ThirdPartyVerificationMode,
) -> Result<(), error::Format> {
let to_verify = match verification_mode {
ThirdPartyVerificationMode::UnsafeLegacy => {
generate_external_signature_payload_v0(payload, public_key)
}
ThirdPartyVerificationMode::PreviousSignatureHashing => {
generate_external_signature_payload_v1(payload, public_key, previous_signature)?
let previous_signature = match previous_signature {
Some(s) => s,
None => {
return Err(error::Format::Signature(
error::Signature::InvalidSignature(
"the authority block must not contain an external signature"

Check warning on line 309 in biscuit-auth/src/crypto/mod.rs

View check run for this annotation

Codecov / codecov/patch

biscuit-auth/src/crypto/mod.rs#L307-L309

Added lines #L307 - L309 were not covered by tests
.to_string(),
),
))
}
};
generate_external_signature_payload_v1(
payload,
public_key,
previous_signature.to_bytes().as_slice(),
version,
)?
}
};

Expand Down Expand Up @@ -337,26 +355,26 @@ fn generate_external_signature_payload_v0(payload: &[u8], public_key: &PublicKey
to_verify
}

fn generate_external_signature_payload_v1(
pub(crate) fn generate_external_signature_payload_v1(
payload: &[u8],
public_key: &PublicKey,
previous_signature: Option<&Signature>,
previous_signature: &[u8],
version: u32,
) -> Result<Vec<u8>, error::Format> {
let mut to_verify = payload.to_vec();
let mut to_verify = b"\0VERSION\0".to_vec();
to_verify.extend(version.to_le_bytes());

to_verify.extend(b"\0PAYLOAD\0".to_vec());
to_verify.extend(payload.to_vec());

to_verify.extend(b"\0ALGORITHM\0".to_vec());
to_verify.extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());

to_verify.extend(b"\0PUBKEY\0".to_vec());
to_verify.extend(&public_key.to_bytes());

let previous_signature = match previous_signature {
Some(s) => s,
None => {
return Err(error::Format::Signature(
error::Signature::InvalidSignature(
"the authority block must not contain an external signature".to_string(),
),
))
}
};
to_verify.extend(&previous_signature.to_bytes());
to_verify.extend(b"\0PREVSIG\0".to_vec());
to_verify.extend(previous_signature);
Ok(to_verify)
}

Expand Down
3 changes: 2 additions & 1 deletion biscuit-auth/src/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use rand_core::{CryptoRng, RngCore};
use crate::crypto::{self};
use crate::format::convert::proto_block_to_token_block;
use crate::format::schema::{self, ThirdPartyBlockContents};
use crate::format::ThirdPartyVerificationMode;
use crate::format::{ThirdPartyVerificationMode, THIRD_PARTY_SIGNATURE_VERSION};
use authorizer::Authorizer;

pub mod authorizer;
Expand Down Expand Up @@ -444,6 +444,7 @@ impl Biscuit {
.signature,
),
&external_signature,
THIRD_PARTY_SIGNATURE_VERSION,
ThirdPartyVerificationMode::PreviousSignatureHashing,
)?;

Expand Down
20 changes: 12 additions & 8 deletions biscuit-auth/src/token/third_party.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ use prost::Message;

use crate::{
builder::BlockBuilder,
crypto::PublicKey,
crypto::{generate_external_signature_payload_v1, PublicKey},
datalog::SymbolTable,
error,
format::{convert::token_block_to_proto_block, schema, SerializedBiscuit},
KeyPair, PrivateKey,
};

use super::THIRD_PARTY_SIGNATURE_VERSION;

/// Third party block request
#[derive(Debug)]
pub struct ThirdPartyRequest {
Expand Down Expand Up @@ -108,22 +110,24 @@ impl ThirdPartyRequest {
let mut block = block_builder.build(symbols);
block.version = max(super::DATALOG_3_2, block.version);

let mut v = Vec::new();
let mut payload = Vec::new();
token_block_to_proto_block(&block)
.encode(&mut v)
.encode(&mut payload)
.map_err(|e| {
error::Format::SerializationError(format!("serialization error: {:?}", e))
})?;
let payload = v.clone();

v.extend(&(crate::format::schema::public_key::Algorithm::Ed25519 as i32).to_le_bytes());
v.extend(self.previous_key.to_bytes());
v.extend(&self.previous_signature);
let signed_payload = generate_external_signature_payload_v1(
&payload,
&self.previous_key,
&self.previous_signature,
THIRD_PARTY_SIGNATURE_VERSION,
)?;

let keypair = KeyPair::from(private_key);
let signature = keypair
.kp
.try_sign(&v)
.try_sign(&signed_payload)
.map_err(|s| s.to_string())
.map_err(error::Signature::InvalidSignatureGeneration)
.map_err(error::Format::Signature)?;
Expand Down

0 comments on commit 4c2b1ad

Please sign in to comment.