();
sigList.Add(certification);
returnKey.ids.Add(id);
returnKey.idTrusts.Add(null);
returnKey.idSigs.Add(sigList);
}
return returnKey;
}
///
/// Remove any certifications associated with a user attribute subpacket on a key.
///
/// The key the certifications are to be removed from.
/// The attributes to be removed.
///
/// The re-certified key, or null if the user attribute subpacket was not found on the key.
///
public static PgpPublicKey RemoveCertification(PgpPublicKey key,
PgpUserAttributeSubpacketVector userAttributes)
{
return RemoveCert(key, userAttributes);
}
/// Remove any certifications associated with a given ID on a key.
/// The key the certifications are to be removed from.
/// The ID that is to be removed.
/// The re-certified key, or null if the ID was not found on the key.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, string id)
{
return RemoveCert(key, new UserIdPacket(id));
}
/// Remove any certifications associated with a given ID on a key.
/// The key the certifications are to be removed from.
/// The ID that is to be removed in raw byte form.
/// The re-certified key, or null if the ID was not found on the key.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, byte[] rawId)
{
return RemoveCert(key, new UserIdPacket(rawId));
}
private static PgpPublicKey RemoveCert(PgpPublicKey key, IUserDataPacket id)
{
PgpPublicKey returnKey = new PgpPublicKey(key);
bool found = false;
for (int i = 0; i < returnKey.ids.Count; i++)
{
if (id.Equals(returnKey.ids[i]))
{
found = true;
returnKey.ids.RemoveAt(i);
returnKey.idTrusts.RemoveAt(i);
returnKey.idSigs.RemoveAt(i);
}
}
return found ? returnKey : null;
}
/// Remove a certification associated with a given ID on a key.
/// The key the certifications are to be removed from.
/// The ID that the certfication is to be removed from (in its raw byte form).
/// The certfication to be removed.
/// The re-certified key, or null if the certification was not found.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, byte[] id, PgpSignature certification)
{
return RemoveCert(key, new UserIdPacket(id), certification);
}
/// Remove a certification associated with a given ID on a key.
/// The key the certifications are to be removed from.
/// The ID that the certfication is to be removed from.
/// The certfication to be removed.
/// The re-certified key, or null if the certification was not found.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, string id, PgpSignature certification)
{
return RemoveCert(key, new UserIdPacket(id), certification);
}
/// Remove a certification associated with a given user attributes on a key.
/// The key the certifications are to be removed from.
/// The user attributes that the certfication is to be removed from.
/// The certification to be removed.
/// The re-certified key, or null if the certification was not found.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpUserAttributeSubpacketVector userAttributes,
PgpSignature certification)
{
return RemoveCert(key, userAttributes, certification);
}
private static PgpPublicKey RemoveCert(PgpPublicKey key, IUserDataPacket id, PgpSignature certification)
{
PgpPublicKey returnKey = new PgpPublicKey(key);
bool found = false;
for (int i = 0; i < returnKey.ids.Count; i++)
{
if (id.Equals(returnKey.ids[i]))
{
found |= returnKey.idSigs[i].Remove(certification);
}
}
return found ? returnKey : null;
}
/// Add a revocation or some other key certification to a key.
/// The key the revocation is to be added to.
/// The key signature to be added.
/// The new changed public key object.
public static PgpPublicKey AddCertification(PgpPublicKey key, PgpSignature certification)
{
if (key.IsMasterKey)
{
if (certification.SignatureType == PgpSignature.SubkeyRevocation)
throw new ArgumentException("signature type incorrect for master key revocation.");
}
else
{
if (certification.SignatureType == PgpSignature.KeyRevocation)
throw new ArgumentException("signature type incorrect for sub-key revocation.");
}
PgpPublicKey returnKey = new PgpPublicKey(key);
var sigs = returnKey.subSigs ?? returnKey.keySigs;
sigs.Add(certification);
return returnKey;
}
/// Remove a certification from the key.
/// The key the certifications are to be removed from.
/// The certfication to be removed.
/// The modified key, null if the certification was not found.
public static PgpPublicKey RemoveCertification(PgpPublicKey key, PgpSignature certification)
{
var returnKey = new PgpPublicKey(key);
var sigs = returnKey.subSigs ?? returnKey.keySigs;
bool found = sigs.Remove(certification);
foreach (var idSigs in returnKey.idSigs)
{
found |= idSigs.Remove(certification);
}
return found ? returnKey : null;
}
/**
* Merge this the given local public key with another, potentially fresher copy.
* The resulting {@link PGPPublicKey} contains the sum of both keys user-ids and signatures.
*
* If joinTrustPackets is set to true and the copy carries a trust packet,
* the joined key will copy the trust-packet from the copy.
* Otherwise, it will carry the trust packet of the local key.
*
* @param key local public key
* @param copy copy of the public key (e.g. from a key server)
* @param joinTrustPackets if true, trust packets from the copy are copied over into the resulting key
* @param allowSubkeySigsOnNonSubkey if true, subkey signatures on the copy will be present in the merged key, even if key was not a subkey before.
* @return joined key
* @throws PGPException
*/
public static PgpPublicKey Join(PgpPublicKey key, PgpPublicKey copy, bool joinTrustPackets,
bool allowSubkeySigsOnNonSubkey)
{
if (key.KeyId != copy.keyId)
throw new ArgumentException("Key-ID mismatch.");
TrustPacket trustPk = key.trustPk;
List keySigs = new List(key.keySigs);
List ids = new List(key.ids);
List idTrusts = new List(key.idTrusts);
List> idSigs = new List>(key.idSigs);
List subSigs = key.subSigs == null ? null : new List(key.subSigs);
if (joinTrustPackets)
{
if (copy.trustPk != null)
{
trustPk = copy.trustPk;
}
}
// key signatures
foreach (PgpSignature keySig in copy.keySigs)
{
bool found = false;
for (int i = 0; i < keySigs.Count; i++)
{
PgpSignature existingKeySig = keySigs[i];
if (PgpSignature.IsSignatureEncodingEqual(existingKeySig, keySig))
{
found = true;
// join existing sig with copy to apply modifications in unhashed subpackets
existingKeySig = PgpSignature.Join(existingKeySig, keySig);
keySigs[i] = existingKeySig;
break;
}
}
if (found)
break;
keySigs.Add(keySig);
}
// user-ids and id sigs
for (int idIdx = 0; idIdx < copy.ids.Count; idIdx++)
{
IUserDataPacket copyId = copy.ids[idIdx];
List copyIdSigs = new List(copy.idSigs[idIdx]);
TrustPacket copyTrust = copy.idTrusts[idIdx];
int existingIdIndex = -1;
for (int i = 0; i < ids.Count; i++)
{
IUserDataPacket existingId = ids[i];
if (existingId.Equals(copyId))
{
existingIdIndex = i;
break;
}
}
// new user-id
if (existingIdIndex == -1)
{
ids.Add(copyId);
idSigs.Add(copyIdSigs);
idTrusts.Add(joinTrustPackets ? copyTrust : null);
continue;
}
// existing user-id
if (joinTrustPackets && copyTrust != null)
{
TrustPacket existingTrust = idTrusts[existingIdIndex];
if (existingTrust == null ||
Arrays.AreEqual(copyTrust.GetLevelAndTrustAmount(), existingTrust.GetLevelAndTrustAmount()))
{
idTrusts[existingIdIndex] = copyTrust;
}
}
var existingIdSigs = idSigs[existingIdIndex];
foreach (PgpSignature newSig in copyIdSigs)
{
bool found = false;
for (int i = 0; i < existingIdSigs.Count; i++)
{
PgpSignature existingSig = existingIdSigs[i];
if (PgpSignature.IsSignatureEncodingEqual(newSig, existingSig))
{
found = true;
// join existing sig with copy to apply modifications in unhashed subpackets
existingSig = PgpSignature.Join(existingSig, newSig);
existingIdSigs[i] = existingSig;
break;
}
}
if (!found)
{
existingIdSigs.Add(newSig);
}
}
}
// subSigs
if (copy.subSigs != null)
{
if (subSigs == null && allowSubkeySigsOnNonSubkey)
{
subSigs = new List(copy.subSigs);
}
else
{
foreach (PgpSignature copySubSig in copy.subSigs)
{
bool found = false;
for (int i = 0; subSigs != null && i < subSigs.Count; i++)
{
PgpSignature existingSubSig = subSigs[i];
if (PgpSignature.IsSignatureEncodingEqual(existingSubSig, copySubSig))
{
found = true;
// join existing sig with copy to apply modifications in unhashed subpackets
existingSubSig = PgpSignature.Join(existingSubSig, copySubSig);
subSigs[i] = existingSubSig;
break;
}
}
if (!found && subSigs != null)
{
subSigs.Add(copySubSig);
}
}
}
}
PgpPublicKey merged = new PgpPublicKey(key, trustPk, keySigs, ids, idTrusts, idSigs);
merged.subSigs = subSigs;
return merged;
}
}
}