ChainSafe / ChainSafe/gossamer
Fuzzing result for PublicKeyFromProtobufEncoding target
- Dominant language
- Go
- Stars
- 454
- Forks
- 144
- PR merge metrics
- No merged PRs in 30d
Description
# Target
### ```Substrate```
```libp2p = { version = "0.49.0" }```
```rust
/// Decode a public key from a protobuf structure, e.g. read from storage
/// or received from another node.
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result {
use prost::Message;
let pubkey = keys_proto::PublicKey::decode(bytes)
.map_err(|e| DecodingError::new("Protobuf").source(e))?;
pubkey.try_into()
}
```
### ```Smoldot```
```rust
/// Decode a public key from a Protobuf structure, e.g. read from storage or received from
/// another node.
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result {
struct ErrorWrapper(FromProtobufEncodingError);
impl<'a> nom::error::ParseError<&'a [u8]> for ErrorWrapper {
fn from_error_kind(_: &'a [u8], _: nom::error::ErrorKind) -> Self {
ErrorWrapper(FromProtobufEncodingError::ProtobufDecodeError)
}
fn append(_: &'a [u8], _: nom::error::ErrorKind, other: Self) -> Self {
other
}
}
impl<'a> nom::error::FromExternalError<&'a [u8], FromProtobufEncodingError> for ErrorWrapper {
fn from_external_error(
_: &'a [u8],
_: nom::error::ErrorKind,
e: FromProtobufEncodingError,
) -> Self {
ErrorWrapper(e)
}
}
// As indicated in the libp2p specification, the public key must be encoded
// deterministically, and thus the fields are decoded deterministically in a precise order.
let mut parser = nom::combinator::all_consuming::<_, _, ErrorWrapper, _>(
nom::combinator::complete(nom::sequence::tuple((
nom::sequence::preceded(
nom::combinator::peek(nom::combinator::verify(
protobuf::tag_decode,
|(field_num, _)| *field_num == 1,
)),
nom::combinator::map_res(protobuf::enum_tag_decode, |val| match val {
0 | 1 | 2 | 3 => Ok(val),
_ => Err(FromProtobufEncodingError::UnknownAlgorithm),
}),
),
nom::sequence::preceded(
nom::combinator::peek(nom::combinator::verify(
protobuf::tag_decode,
|(field_num, _)| *field_num == 2,
)),
nom::combinator::map_res(protobuf::bytes_tag_decode, |d| {
<[u8; 32]>::try_from(d).map_err(|_| FromProtobufEncodingError::BadEd25519Key)
}),
),
))),
);
match nom::Finish::finish(parser(bytes)) {
Ok((_, (1, key))) => Ok(PublicKey::Ed25519(key)),
Ok((_, (_, _))) => Err(FromProtobufEncodingError::UnsupportedAlgorithm),
Err(err) => Err(err.0),
}
}
```
### ```Gossamer```
```github.com/libp2p/go-libp2p-core v0.16.1```
```go
/ UnmarshalPublicKey converts a protobuf serialized public key into its
// representative object
// Deprecated: use github.com/libp2p/go-libp2p/core/crypto.UnmarshalPublicKey instead
func UnmarshalPublicKey(data []byte) (PubKey, error) {
return crypto.UnmarshalPublicKey(data)
}
// UnmarshalPublicKey converts a protobuf serialized public key into its
// representative object
func UnmarshalPublicKey(data []byte) (PubKey, error) {
pmes := new(pb.PublicKey)
err := proto.Unmarshal(data, pmes)
if err != nil {
return nil, err
}
return PublicKeyFromProto(pmes)
}
```
# ```PublicKeyFromProtobufEncoding``` Reproducing Scripts
### ```Substrate```
```rust
pub fn substrate_publickey_from_protobuf_encoding(file_name: &String) {
println!("[+] Substrate Result:");
let buf = read_bytes(file_name).unwrap();
let ret = libp2p::identity::PublicKey::from_protobuf_encoding(&buf);
if let Err(_) = ret {
println!("[-] PublicKey from_protobuf_encoding result: {:?}", ret);
} else {
println!("[+] PublicKey from_protobuf_encoding result: {:?}", ret);
}
}
```
### ```Smoldot```
```rust
pub fn smoldot_publickey_from_protobuf_encoding(file_name: &String) {
println!("[+] Smoldot Result:");
let buf = read_bytes(file_name).unwrap();
let ret = smoldot::libp2p::peer_id::PublicKey::from_protobuf_encoding(&buf);
if let Err(_) = ret {
println!("[-] PublicKey from_protobuf_encoding result: {:?}", ret);
} else {
println!("[+] PublicKey from_protobuf_encoding result: {:?}", ret);
}
}
```
### ```Gossamer```
```go
func glib_publickey_from_protobuf_encoding(data_ptr unsafe.Pointer, data_size int) {
fmt.Println("[+] Gossamer Result:")
var data []byte
sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
sh.Data = uintptr(data_ptr)
sh.Len = data_size
sh.Cap = data_size
ret, err := crypto.UnmarshalPublicKey(data)
if err != nil {
fmt.Println("[-] PublicKey UnmarshalPublicKey result:", err)
} else {
fmt.Println("[+] PublicKey UnmarshalPublicKey result:", ret)
}
}
```
# Crash 1
The differential fuzzer catches a crash. The ```Substrate``` target give an error message but ```Smoldot``` and ```Gossamer``` targets execute the given data successfully.
### ```Reproducer```
```
./reproducer run all PublicKeyFromProtobufEncoding /crash-7e399552cfc08f22332ce2e1094981f551e45621
[+] Smoldot Result:
[+] PublicKey from_protobuf_encoding result: Ok(Ed25519([134, 134, 134, 134, 134, 134, 134, 0, 60, 140, 43, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 134, 255, 255, 255, 255, 255, 255, 39, 134, 134]))
[+] Substrate Result:
[-] PublicKey from_protobuf_encoding result: Err(DecodingError { msg: "Ed25519 public key", source: Some(signature::Error { source: Some(Cannot decompress Edwards point) }) })
[+] Gossamer Result:
[+] PublicKey UnmarshalPublicKey result: &{[134 134 134 134 134 134 134 0 60 140 43 134 134 134 134 134 134 134 134 134 134 134 134 255 255 255 255 255 255 39 134 134]}
```
### Artifacts 1
[publickeyfromprotobufencoding_crash1.zip](https://github.com/ChainSafe/gossamer/files/10724025/publickeyfromprotobufencoding_crash1.zip)
# Crash 2
The differential fuzzer catches a crash. The ```Substrate``` and ```Smoldot``` targets give an error message but the ```Gossamer``` target execute the given data successfully.
### ```Reproducer```
```
./reproducer run all PublicKeyFromProtobufEncoding /fffebdd9494b5f53
[+] Smoldot Result:
[-] PublicKey from_protobuf_encoding result: Err(BadEd25519Key)
[+] Substrate Result:
[-] PublicKey from_protobuf_encoding result: Err(DecodingError { msg: "Unsupported", source: None })
[+] Gossamer Result:
[+] PublicKey UnmarshalPublicKey result: &{{[18948385 4737096 34738706 8684676 18948385 608328 0 0 18948385 297032]} {[47972744 15090367 28120277 19620873 13848178 807834 36300299 47608540 44640710 745457]}}
```
### Artifacts 2
[publickeyfromprotobufencoding_crash2.zip](https://github.com/ChainSafe/gossamer/files/10724026/publickeyfromprotobufencoding_crash2.zip)
Contributor guide
Assessment
This issue has not been assessed yet.