Sorgente pubblicata
Scarica sorgente ZIP
CH-J Tools
Sfoglia directory e file per una specifica release di applicazioni.
CH-J / Server Manager
1704 file
0.1.2-beta
Aggiunto: · Costruito:
1
use super::wire::*;2
use crate::core::error::CoreResult;3
use pgp::{4
composed::KeyType,5
crypto::ecc_curve::ECCCurve,6
ser::Serialize,7
types::{KeyVersion, SecretParams},8
};9
use zeroize::Zeroizing;11
#[derive(Clone)]12
pub struct Key {13
pub version: u8,14
pub created: u32,15
pub days: u16,16
pub algorithm: u8,17
pub public: Vec<u8>,18
pub material: Vec<u8>,19
pub secret: Option<Zeroizing<Vec<u8>>>,20
pub tag: u8,21
}22
impl Key {23
pub fn parse(packet: &Packet) -> CoreResult<Self> {24
if ![5, 6, 7, 14].contains(&packet.tag) {25
return Err(invalid());26
}27
let mut r = Reader::new(&packet.body);28
let version = r.u8()?;29
if ![2, 3, 5].contains(&version) {30
return Err(invalid());31
}32
let created = r.u32()?;33
let days = if version <= 3 { r.u16()? } else { 0 };34
let algorithm = r.u8()?;35
let start = r.pos;36
let material = if version == 5 {37
let len = r.u32()? as usize;38
r.take(len)?.to_vec()39
} else {40
if algorithm != 1 {41
return Err(invalid());42
}43
r.mpi()?;44
r.mpi()?;45
packet.body[start..r.pos].to_vec()46
};47
Parameters::public(algorithm, created, &material)?;48
let public = packet.body[..r.pos].to_vec();49
let secret = if [5, 7].contains(&packet.tag) {50
{51
if r.rest().is_empty() {52
return Err(invalid());53
}54
Some(Zeroizing::new(r.rest().to_vec()))55
}56
} else {57
r.done()?;58
None59
};60
Ok(Self {61
version,62
created,63
days,64
algorithm,65
public,66
material,67
secret,68
tag: packet.tag,69
})70
}71
pub fn prefix(&self) -> CoreResult<Vec<u8>> {72
let mut out = vec![if self.version == 5 { 0x9a } else { 0x99 }];73
if self.version == 5 {74
out.extend((self.public.len() as u32).to_be_bytes())75
} else {76
out.extend(77
u16::try_from(self.public.len())78
.map_err(|_| invalid())?79
.to_be_bytes(),80
)81
}82
out.extend(&self.public);83
Ok(out)84
}85
pub fn fingerprint(&self) -> CoreResult<Vec<u8>> {86
if self.version == 5 {87
hash(8, &[&self.prefix()?])88
} else {89
let mut r = Reader::new(&self.material);90
let n = r.mpi()?;91
let e = r.mpi()?;92
r.done()?;93
hash(1, &[n, e])94
}95
}96
pub fn key_id(&self) -> CoreResult<Vec<u8>> {97
if self.version == 5 {98
Ok(self.fingerprint()?[..8].to_vec())99
} else {100
let n = Reader::new(&self.material).mpi()?;101
if n.len() < 8 {102
return Err(invalid());103
}104
Ok(n[n.len() - 8..].to_vec())105
}106
}107
pub fn parameters(&self) -> CoreResult<Parameters> {108
Parameters::public(self.algorithm, self.created, &self.material)109
}110
}111
pub struct Generated {112
pub key: Key,113
pub parameters: Parameters,114
pub plain: Zeroizing<Vec<u8>>,115
}116
pub fn generate(version: u8, created: u32, days: u16, algorithm: &str) -> CoreResult<Generated> {117
crate::core::openpgp_algorithms::validate(118
version,119
algorithm,120
if algorithm == "curve25519" { "E" } else { "S" },121
)?;122
let typ = match algorithm {123
"rsa1024" if version <= 3 => KeyType::Rsa(1024),124
"rsa2048" if version <= 3 => KeyType::Rsa(2048),125
"rsa3072" if version == 5 => KeyType::Rsa(3072),126
"rsa4096" if version == 5 => KeyType::Rsa(4096),127
"ed25519" if version == 5 => KeyType::Ed25519Legacy,128
"curve25519" if version == 5 => KeyType::ECDH(ECCCurve::Curve25519Legacy),129
_ if crate::core::openpgp_algorithms::is_dsa(algorithm) => {130
pgp::composed::KeyType::Dsa(pgp::composed::DsaKeySize::B2048)131
}132
_ => return Err(invalid()),133
};134
let (public, secret) = if crate::core::openpgp_algorithms::is_dsa(algorithm) {135
crate::core::openpgp_algorithms::generate_dsa(version, algorithm)?136
} else {137
crypto(typ.generate(&mut rand::thread_rng()))?138
};139
let material = crypto(public.to_bytes())?;140
let alg: u8 = typ.to_alg().into();141
let mut body = vec![version];142
body.extend(created.to_be_bytes());143
if version <= 3 {144
body.extend(days.to_be_bytes())145
}146
body.push(alg);147
if version == 5 {148
body.extend((material.len() as u32).to_be_bytes())149
}150
body.extend(&material);151
let mut plain = Zeroizing::new(Vec::new());152
let SecretParams::Plain(ref private) = secret else {153
return Err(invalid());154
};155
// V6 here selects parameter bytes without a checksum, not a serialized key format.156
crypto(private.to_writer(&mut *plain, KeyVersion::V6))?;157
let parameters = Parameters::public(alg, created, &material)?.with_secret(alg, &plain)?;158
let key = Key {159
version,160
created,161
days,162
algorithm: alg,163
public: body,164
material,165
secret: None,166
tag: 6,167
};168
Ok(Generated {169
key,170
parameters,171
plain,172
})173
}SHA-256
595d5454d691dcdc12e5d648c1c0cc9eb35bc378c30612bfd7749287258eede2CH-J Proprietary Software License 1.14 · La sorgente è fornita sotto CH-J Proprietary Software License 1.14. La sua disponibilità non modifica i termini di licenza o concede diritti aggiuntivi.
Archivio SHA-256
ac8fe790f4ba60fc098f8c985fc2656cfcc6cdc21fb34b30e308a2b54e62258f