001// SPDX-FileCopyrightText: 2021 Paul Schaub <vanitasvitae@fsfe.org> 002// 003// SPDX-License-Identifier: Apache-2.0 004 005package org.pgpainless.signature.subpackets; 006 007import java.io.IOException; 008import java.util.ArrayList; 009import java.util.Arrays; 010import java.util.Date; 011import java.util.Iterator; 012import java.util.LinkedHashSet; 013import java.util.List; 014import java.util.Set; 015import javax.annotation.Nonnull; 016import javax.annotation.Nullable; 017 018import org.bouncycastle.bcpg.SignatureSubpacket; 019import org.bouncycastle.bcpg.SignatureSubpacketTags; 020import org.bouncycastle.bcpg.sig.EmbeddedSignature; 021import org.bouncycastle.bcpg.sig.Exportable; 022import org.bouncycastle.bcpg.sig.Features; 023import org.bouncycastle.bcpg.sig.IntendedRecipientFingerprint; 024import org.bouncycastle.bcpg.sig.IssuerFingerprint; 025import org.bouncycastle.bcpg.sig.IssuerKeyID; 026import org.bouncycastle.bcpg.sig.KeyExpirationTime; 027import org.bouncycastle.bcpg.sig.KeyFlags; 028import org.bouncycastle.bcpg.sig.NotationData; 029import org.bouncycastle.bcpg.sig.PreferredAlgorithms; 030import org.bouncycastle.bcpg.sig.PrimaryUserID; 031import org.bouncycastle.bcpg.sig.Revocable; 032import org.bouncycastle.bcpg.sig.RevocationKey; 033import org.bouncycastle.bcpg.sig.RevocationReason; 034import org.bouncycastle.bcpg.sig.SignatureCreationTime; 035import org.bouncycastle.bcpg.sig.SignatureExpirationTime; 036import org.bouncycastle.bcpg.sig.SignatureTarget; 037import org.bouncycastle.bcpg.sig.SignerUserID; 038import org.bouncycastle.bcpg.sig.TrustSignature; 039import org.bouncycastle.openpgp.PGPPublicKey; 040import org.bouncycastle.openpgp.PGPSignature; 041import org.bouncycastle.openpgp.PGPSignatureSubpacketVector; 042import org.pgpainless.algorithm.CompressionAlgorithm; 043import org.pgpainless.algorithm.Feature; 044import org.pgpainless.algorithm.HashAlgorithm; 045import org.pgpainless.algorithm.KeyFlag; 046import org.pgpainless.algorithm.PublicKeyAlgorithm; 047import org.pgpainless.algorithm.SymmetricKeyAlgorithm; 048import org.pgpainless.key.util.RevocationAttributes; 049 050public class SignatureSubpackets 051 implements BaseSignatureSubpackets, SelfSignatureSubpackets, CertificationSubpackets, RevocationSignatureSubpackets { 052 053 private SignatureCreationTime signatureCreationTime; 054 private SignatureExpirationTime signatureExpirationTime; 055 private IssuerKeyID issuerKeyID; 056 private IssuerFingerprint issuerFingerprint; 057 private final List<NotationData> notationDataList = new ArrayList<>(); 058 private final List<IntendedRecipientFingerprint> intendedRecipientFingerprintList = new ArrayList<>(); 059 private final List<RevocationKey> revocationKeyList = new ArrayList<>(); 060 private Exportable exportable; 061 private SignatureTarget signatureTarget; 062 private Features features; 063 private KeyFlags keyFlags; 064 private TrustSignature trust; 065 private PreferredAlgorithms preferredCompressionAlgorithms; 066 private PreferredAlgorithms preferredSymmetricKeyAlgorithms; 067 private PreferredAlgorithms preferredHashAlgorithms; 068 private final List<EmbeddedSignature> embeddedSignatureList = new ArrayList<>(); 069 private SignerUserID signerUserId; 070 private KeyExpirationTime keyExpirationTime; 071 private PrimaryUserID primaryUserId; 072 private Revocable revocable; 073 private RevocationReason revocationReason; 074 private final List<SignatureSubpacket> residualSubpackets = new ArrayList<>(); 075 076 public SignatureSubpackets() { 077 078 } 079 080 public static SignatureSubpackets refreshHashedSubpackets(PGPPublicKey issuer, PGPSignature oldSignature) { 081 return createHashedSubpacketsFrom(issuer, oldSignature.getHashedSubPackets()); 082 } 083 084 public static SignatureSubpackets refreshUnhashedSubpackets(PGPSignature oldSignature) { 085 return createSubpacketsFrom(oldSignature.getUnhashedSubPackets()); 086 } 087 088 public static SignatureSubpackets createHashedSubpacketsFrom(PGPPublicKey issuer, PGPSignatureSubpacketVector base) { 089 SignatureSubpackets wrapper = createSubpacketsFrom(base); 090 wrapper.setIssuerFingerprintAndKeyId(issuer); 091 return wrapper; 092 } 093 094 public static SignatureSubpackets createSubpacketsFrom(PGPSignatureSubpacketVector base) { 095 SignatureSubpackets wrapper = new SignatureSubpackets(); 096 SignatureSubpacketsHelper.applyFrom(base, wrapper); 097 return wrapper; 098 } 099 100 public static SignatureSubpackets createHashedSubpackets(PGPPublicKey issuer) { 101 SignatureSubpackets wrapper = new SignatureSubpackets(); 102 wrapper.setIssuerFingerprintAndKeyId(issuer); 103 return wrapper; 104 } 105 106 public static SignatureSubpackets createEmptySubpackets() { 107 return new SignatureSubpackets(); 108 } 109 110 @Override 111 public SignatureSubpackets setIssuerFingerprintAndKeyId(PGPPublicKey key) { 112 setIssuerKeyId(key.getKeyID()); 113 setIssuerFingerprint(key); 114 return this; 115 } 116 117 @Override 118 public SignatureSubpackets setIssuerKeyId(long keyId) { 119 return setIssuerKeyId(true, keyId); 120 } 121 122 @Override 123 public SignatureSubpackets setIssuerKeyId(boolean isCritical, long keyId) { 124 return setIssuerKeyId(new IssuerKeyID(isCritical, keyId)); 125 } 126 127 @Override 128 public SignatureSubpackets setIssuerKeyId(@Nullable IssuerKeyID issuerKeyID) { 129 this.issuerKeyID = issuerKeyID; 130 return this; 131 } 132 133 public IssuerKeyID getIssuerKeyIdSubpacket() { 134 return issuerKeyID; 135 } 136 137 @Override 138 public SignatureSubpackets setIssuerFingerprint(@Nonnull PGPPublicKey key) { 139 return setIssuerFingerprint(true, key); 140 } 141 142 @Override 143 public SignatureSubpackets setIssuerFingerprint(boolean isCritical, @Nonnull PGPPublicKey key) { 144 return setIssuerFingerprint(new IssuerFingerprint(isCritical, key.getVersion(), key.getFingerprint())); 145 } 146 147 @Override 148 public SignatureSubpackets setIssuerFingerprint(@Nullable IssuerFingerprint fingerprint) { 149 this.issuerFingerprint = fingerprint; 150 return this; 151 } 152 153 public IssuerFingerprint getIssuerFingerprintSubpacket() { 154 return issuerFingerprint; 155 } 156 157 @Override 158 public SignatureSubpackets setKeyFlags(KeyFlag... keyFlags) { 159 return setKeyFlags(true, keyFlags); 160 } 161 162 @Override 163 public SignatureSubpackets setKeyFlags(boolean isCritical, KeyFlag... keyFlags) { 164 int bitmask = KeyFlag.toBitmask(keyFlags); 165 return setKeyFlags(new KeyFlags(isCritical, bitmask)); 166 } 167 168 @Override 169 public SignatureSubpackets setKeyFlags(@Nullable KeyFlags keyFlags) { 170 this.keyFlags = keyFlags; 171 return this; 172 } 173 174 public KeyFlags getKeyFlagsSubpacket() { 175 return keyFlags; 176 } 177 178 @Override 179 public SignatureSubpackets setSignatureCreationTime(@Nonnull Date creationTime) { 180 return setSignatureCreationTime(true, creationTime); 181 } 182 183 @Override 184 public SignatureSubpackets setSignatureCreationTime(boolean isCritical, @Nonnull Date creationTime) { 185 return setSignatureCreationTime(new SignatureCreationTime(isCritical, creationTime)); 186 } 187 188 @Override 189 public SignatureSubpackets setSignatureCreationTime(@Nullable SignatureCreationTime signatureCreationTime) { 190 this.signatureCreationTime = signatureCreationTime; 191 return this; 192 } 193 194 public SignatureCreationTime getSignatureCreationTimeSubpacket() { 195 return signatureCreationTime; 196 } 197 198 @Override 199 public SignatureSubpackets setSignatureExpirationTime(@Nonnull Date creationTime, @Nonnull Date expirationTime) { 200 return setSignatureExpirationTime(true, creationTime, expirationTime); 201 } 202 203 @Override 204 public SignatureSubpackets setSignatureExpirationTime(boolean isCritical, @Nonnull Date creationTime, @Nonnull Date expirationTime) { 205 return setSignatureExpirationTime(isCritical, (expirationTime.getTime() / 1000) - (creationTime.getTime() / 1000)); 206 } 207 208 @Override 209 public SignatureSubpackets setSignatureExpirationTime(boolean isCritical, long seconds) { 210 if (seconds < 0) { 211 throw new IllegalArgumentException("Expiration time cannot be negative."); 212 } 213 return setSignatureExpirationTime(new SignatureExpirationTime(isCritical, seconds)); 214 } 215 216 @Override 217 public SignatureSubpackets setSignatureExpirationTime(@Nullable SignatureExpirationTime expirationTime) { 218 this.signatureExpirationTime = expirationTime; 219 return this; 220 } 221 222 public SignatureExpirationTime getSignatureExpirationTimeSubpacket() { 223 return signatureExpirationTime; 224 } 225 226 @Override 227 public SignatureSubpackets setSignerUserId(@Nonnull String userId) { 228 return setSignerUserId(false, userId); 229 } 230 231 @Override 232 public SignatureSubpackets setSignerUserId(boolean isCritical, @Nonnull String userId) { 233 return setSignerUserId(new SignerUserID(isCritical, userId)); 234 } 235 236 @Override 237 public SignatureSubpackets setSignerUserId(@Nullable SignerUserID signerUserId) { 238 this.signerUserId = signerUserId; 239 return this; 240 } 241 242 public SignerUserID getSignerUserIdSubpacket() { 243 return signerUserId; 244 } 245 246 @Override 247 public SignatureSubpackets setPrimaryUserId() { 248 return setPrimaryUserId(true); 249 } 250 251 @Override 252 public SignatureSubpackets setPrimaryUserId(boolean isCritical) { 253 return setPrimaryUserId(new PrimaryUserID(isCritical, true)); 254 } 255 256 @Override 257 public SignatureSubpackets setPrimaryUserId(@Nullable PrimaryUserID primaryUserId) { 258 this.primaryUserId = primaryUserId; 259 return this; 260 } 261 262 public PrimaryUserID getPrimaryUserIdSubpacket() { 263 return primaryUserId; 264 } 265 266 @Override 267 public SignatureSubpackets setKeyExpirationTime(@Nonnull PGPPublicKey key, @Nonnull Date keyExpirationTime) { 268 return setKeyExpirationTime(key.getCreationTime(), keyExpirationTime); 269 } 270 271 @Override 272 public SignatureSubpackets setKeyExpirationTime(@Nonnull Date keyCreationTime, @Nonnull Date keyExpirationTime) { 273 return setKeyExpirationTime(true, keyCreationTime, keyExpirationTime); 274 } 275 276 @Override 277 public SignatureSubpackets setKeyExpirationTime(boolean isCritical, @Nonnull Date keyCreationTime, @Nonnull Date keyExpirationTime) { 278 return setKeyExpirationTime(isCritical, (keyExpirationTime.getTime() / 1000) - (keyCreationTime.getTime() / 1000)); 279 } 280 281 @Override 282 public SignatureSubpackets setKeyExpirationTime(boolean isCritical, long secondsFromCreationToExpiration) { 283 if (secondsFromCreationToExpiration < 0) { 284 throw new IllegalArgumentException("Seconds from key creation to expiration cannot be less than 0."); 285 } 286 return setKeyExpirationTime(new KeyExpirationTime(isCritical, secondsFromCreationToExpiration)); 287 } 288 289 @Override 290 public SignatureSubpackets setKeyExpirationTime(@Nullable KeyExpirationTime keyExpirationTime) { 291 this.keyExpirationTime = keyExpirationTime; 292 return this; 293 } 294 295 public KeyExpirationTime getKeyExpirationTimeSubpacket() { 296 return keyExpirationTime; 297 } 298 299 @Override 300 public SignatureSubpackets setPreferredCompressionAlgorithms(CompressionAlgorithm... algorithms) { 301 return setPreferredCompressionAlgorithms(new LinkedHashSet<>(Arrays.asList(algorithms))); 302 } 303 304 @Override 305 public SignatureSubpackets setPreferredCompressionAlgorithms(Set<CompressionAlgorithm> algorithms) { 306 return setPreferredCompressionAlgorithms(true, algorithms); 307 } 308 309 @Override 310 public SignatureSubpackets setPreferredCompressionAlgorithms(boolean isCritical, Set<CompressionAlgorithm> algorithms) { 311 int[] ids = new int[algorithms.size()]; 312 Iterator<CompressionAlgorithm> iterator = algorithms.iterator(); 313 for (int i = 0; i < algorithms.size(); i++) { 314 ids[i] = iterator.next().getAlgorithmId(); 315 } 316 return setPreferredCompressionAlgorithms(new PreferredAlgorithms( 317 SignatureSubpacketTags.PREFERRED_COMP_ALGS, isCritical, ids)); 318 } 319 320 @Override 321 public SignatureSubpackets setPreferredCompressionAlgorithms(@Nullable PreferredAlgorithms algorithms) { 322 if (algorithms == null) { 323 this.preferredCompressionAlgorithms = null; 324 return this; 325 } 326 327 if (algorithms.getType() != SignatureSubpacketTags.PREFERRED_COMP_ALGS) { 328 throw new IllegalArgumentException("Invalid preferred compression algorithms type."); 329 } 330 this.preferredCompressionAlgorithms = algorithms; 331 return this; 332 } 333 334 public PreferredAlgorithms getPreferredCompressionAlgorithmsSubpacket() { 335 return preferredCompressionAlgorithms; 336 } 337 338 @Override 339 public SignatureSubpackets setPreferredSymmetricKeyAlgorithms(SymmetricKeyAlgorithm... algorithms) { 340 return setPreferredSymmetricKeyAlgorithms(new LinkedHashSet<>(Arrays.asList(algorithms))); 341 } 342 343 @Override 344 public SignatureSubpackets setPreferredSymmetricKeyAlgorithms(Set<SymmetricKeyAlgorithm> algorithms) { 345 return setPreferredSymmetricKeyAlgorithms(true, algorithms); 346 } 347 348 @Override 349 public SignatureSubpackets setPreferredSymmetricKeyAlgorithms(boolean isCritical, Set<SymmetricKeyAlgorithm> algorithms) { 350 int[] ids = new int[algorithms.size()]; 351 Iterator<SymmetricKeyAlgorithm> iterator = algorithms.iterator(); 352 for (int i = 0; i < algorithms.size(); i++) { 353 ids[i] = iterator.next().getAlgorithmId(); 354 } 355 return setPreferredSymmetricKeyAlgorithms(new PreferredAlgorithms( 356 SignatureSubpacketTags.PREFERRED_SYM_ALGS, isCritical, ids)); 357 } 358 359 @Override 360 public SignatureSubpackets setPreferredSymmetricKeyAlgorithms(@Nullable PreferredAlgorithms algorithms) { 361 if (algorithms == null) { 362 this.preferredSymmetricKeyAlgorithms = null; 363 return this; 364 } 365 366 if (algorithms.getType() != SignatureSubpacketTags.PREFERRED_SYM_ALGS) { 367 throw new IllegalArgumentException("Invalid preferred symmetric key algorithms type."); 368 } 369 this.preferredSymmetricKeyAlgorithms = algorithms; 370 return this; 371 } 372 373 public PreferredAlgorithms getPreferredSymmetricKeyAlgorithmsSubpacket() { 374 return preferredSymmetricKeyAlgorithms; 375 } 376 377 @Override 378 public SignatureSubpackets setPreferredHashAlgorithms(HashAlgorithm... algorithms) { 379 return setPreferredHashAlgorithms(new LinkedHashSet<>(Arrays.asList(algorithms))); 380 } 381 382 @Override 383 public SignatureSubpackets setPreferredHashAlgorithms(Set<HashAlgorithm> algorithms) { 384 return setPreferredHashAlgorithms(true, algorithms); 385 } 386 387 @Override 388 public SignatureSubpackets setPreferredHashAlgorithms(boolean isCritical, Set<HashAlgorithm> algorithms) { 389 int[] ids = new int[algorithms.size()]; 390 Iterator<HashAlgorithm> iterator = algorithms.iterator(); 391 for (int i = 0; i < ids.length; i++) { 392 ids[i] = iterator.next().getAlgorithmId(); 393 } 394 return setPreferredHashAlgorithms(new PreferredAlgorithms( 395 SignatureSubpacketTags.PREFERRED_HASH_ALGS, isCritical, ids)); 396 } 397 398 @Override 399 public SignatureSubpackets setPreferredHashAlgorithms(@Nullable PreferredAlgorithms algorithms) { 400 if (algorithms == null) { 401 preferredHashAlgorithms = null; 402 return this; 403 } 404 405 if (algorithms.getType() != SignatureSubpacketTags.PREFERRED_HASH_ALGS) { 406 throw new IllegalArgumentException("Invalid preferred hash algorithms type."); 407 } 408 this.preferredHashAlgorithms = algorithms; 409 return this; 410 } 411 412 public PreferredAlgorithms getPreferredHashAlgorithmsSubpacket() { 413 return preferredHashAlgorithms; 414 } 415 416 @Override 417 public SignatureSubpackets addNotationData(boolean isCritical, @Nonnull String notationName, @Nonnull String notationValue) { 418 return addNotationData(isCritical, true, notationName, notationValue); 419 } 420 421 @Override 422 public SignatureSubpackets addNotationData(boolean isCritical, boolean isHumanReadable, @Nonnull String notationName, @Nonnull String notationValue) { 423 return addNotationData(new NotationData(isCritical, isHumanReadable, notationName, notationValue)); 424 } 425 426 @Override 427 public SignatureSubpackets addNotationData(@Nonnull NotationData notationData) { 428 notationDataList.add(notationData); 429 return this; 430 } 431 432 @Override 433 public SignatureSubpackets clearNotationData() { 434 notationDataList.clear(); 435 return this; 436 } 437 438 public List<NotationData> getNotationDataSubpackets() { 439 return new ArrayList<>(notationDataList); 440 } 441 442 @Override 443 public SignatureSubpackets addIntendedRecipientFingerprint(@Nonnull PGPPublicKey recipient) { 444 return addIntendedRecipientFingerprint(false, recipient); 445 } 446 447 @Override 448 public SignatureSubpackets addIntendedRecipientFingerprint(boolean isCritical, @Nonnull PGPPublicKey recipient) { 449 return addIntendedRecipientFingerprint(new IntendedRecipientFingerprint(isCritical, recipient.getVersion(), recipient.getFingerprint())); 450 } 451 452 @Override 453 public SignatureSubpackets addIntendedRecipientFingerprint(IntendedRecipientFingerprint intendedRecipientFingerprint) { 454 this.intendedRecipientFingerprintList.add(intendedRecipientFingerprint); 455 return this; 456 } 457 458 @Override 459 public SignatureSubpackets clearIntendedRecipientFingerprints() { 460 intendedRecipientFingerprintList.clear(); 461 return this; 462 } 463 464 public List<IntendedRecipientFingerprint> getIntendedRecipientFingerprintSubpackets() { 465 return new ArrayList<>(intendedRecipientFingerprintList); 466 } 467 468 @Override 469 public SignatureSubpackets setExportable(boolean isCritical, boolean isExportable) { 470 return setExportable(new Exportable(isCritical, isExportable)); 471 } 472 473 @Override 474 public SignatureSubpackets setExportable(@Nullable Exportable exportable) { 475 this.exportable = exportable; 476 return this; 477 } 478 479 public Exportable getExportableSubpacket() { 480 return exportable; 481 } 482 483 @Override 484 public SignatureSubpackets setRevocable(boolean isCritical, boolean isRevocable) { 485 return setRevocable(new Revocable(isCritical, isRevocable)); 486 } 487 488 @Override 489 public SignatureSubpackets setRevocable(@Nullable Revocable revocable) { 490 this.revocable = revocable; 491 return this; 492 } 493 494 public Revocable getRevocableSubpacket() { 495 return revocable; 496 } 497 498 @Override 499 public SignatureSubpackets addRevocationKey(@Nonnull PGPPublicKey revocationKey) { 500 return addRevocationKey(true, revocationKey); 501 } 502 503 @Override 504 public SignatureSubpackets addRevocationKey(boolean isCritical, @Nonnull PGPPublicKey revocationKey) { 505 return addRevocationKey(isCritical, false, revocationKey); 506 } 507 508 @Override 509 public SignatureSubpackets addRevocationKey(boolean isCritical, boolean isSensitive, @Nonnull PGPPublicKey revocationKey) { 510 byte clazz = (byte) 0x80; 511 clazz |= (isSensitive ? 0x40 : 0x00); 512 return addRevocationKey(new RevocationKey(isCritical, clazz, revocationKey.getAlgorithm(), revocationKey.getFingerprint())); 513 } 514 515 @Override 516 public SignatureSubpackets addRevocationKey(@Nonnull RevocationKey revocationKey) { 517 this.revocationKeyList.add(revocationKey); 518 return this; 519 } 520 521 @Override 522 public SignatureSubpackets clearRevocationKeys() { 523 revocationKeyList.clear(); 524 return this; 525 } 526 527 public List<RevocationKey> getRevocationKeySubpackets() { 528 return new ArrayList<>(revocationKeyList); 529 } 530 531 @Override 532 public SignatureSubpackets setRevocationReason(RevocationAttributes revocationAttributes) { 533 return setRevocationReason(true, revocationAttributes); 534 } 535 536 @Override 537 public SignatureSubpackets setRevocationReason(boolean isCritical, RevocationAttributes revocationAttributes) { 538 return setRevocationReason(isCritical, revocationAttributes.getReason(), revocationAttributes.getDescription()); 539 } 540 541 @Override 542 public SignatureSubpackets setRevocationReason(boolean isCritical, RevocationAttributes.Reason reason, @Nonnull String description) { 543 return setRevocationReason(new RevocationReason(isCritical, reason.code(), description)); 544 } 545 546 @Override 547 public SignatureSubpackets setRevocationReason(@Nullable RevocationReason reason) { 548 this.revocationReason = reason; 549 return this; 550 } 551 552 public RevocationReason getRevocationReasonSubpacket() { 553 return revocationReason; 554 } 555 556 @Override 557 public SignatureSubpackets setSignatureTarget(@Nonnull PublicKeyAlgorithm keyAlgorithm, @Nonnull HashAlgorithm hashAlgorithm, @Nonnull byte[] hashData) { 558 return setSignatureTarget(true, keyAlgorithm, hashAlgorithm, hashData); 559 } 560 561 @Override 562 public SignatureSubpackets setSignatureTarget(boolean isCritical, @Nonnull PublicKeyAlgorithm keyAlgorithm, @Nonnull HashAlgorithm hashAlgorithm, @Nonnull byte[] hashData) { 563 return setSignatureTarget(new SignatureTarget(isCritical, keyAlgorithm.getAlgorithmId(), hashAlgorithm.getAlgorithmId(), hashData)); 564 } 565 566 @Override 567 public SignatureSubpackets setSignatureTarget(@Nullable SignatureTarget signatureTarget) { 568 this.signatureTarget = signatureTarget; 569 return this; 570 } 571 572 public SignatureTarget getSignatureTargetSubpacket() { 573 return signatureTarget; 574 } 575 576 @Override 577 public SignatureSubpackets setFeatures(Feature... features) { 578 return setFeatures(true, features); 579 } 580 581 @Override 582 public SignatureSubpackets setFeatures(boolean isCritical, Feature... features) { 583 byte bitmask = Feature.toBitmask(features); 584 return setFeatures(new Features(isCritical, bitmask)); 585 } 586 587 @Override 588 public SignatureSubpackets setFeatures(@Nullable Features features) { 589 this.features = features; 590 return this; 591 } 592 593 public Features getFeaturesSubpacket() { 594 return features; 595 } 596 597 @Override 598 public SignatureSubpackets setTrust(int depth, int amount) { 599 return setTrust(true, depth, amount); 600 } 601 602 @Override 603 public SignatureSubpackets setTrust(boolean isCritical, int depth, int amount) { 604 return setTrust(new TrustSignature(isCritical, depth, amount)); 605 } 606 607 @Override 608 public SignatureSubpackets setTrust(@Nullable TrustSignature trust) { 609 this.trust = trust; 610 return this; 611 } 612 613 public TrustSignature getTrustSubpacket() { 614 return trust; 615 } 616 617 @Override 618 public SignatureSubpackets addEmbeddedSignature(@Nonnull PGPSignature signature) throws IOException { 619 return addEmbeddedSignature(true, signature); 620 } 621 622 @Override 623 public SignatureSubpackets addEmbeddedSignature(boolean isCritical, @Nonnull PGPSignature signature) throws IOException { 624 byte[] sig = signature.getEncoded(); 625 byte[] data; 626 627 if (sig.length - 1 > 256) { 628 data = new byte[sig.length - 3]; 629 } 630 else { 631 data = new byte[sig.length - 2]; 632 } 633 634 System.arraycopy(sig, sig.length - data.length, data, 0, data.length); 635 636 return addEmbeddedSignature(new EmbeddedSignature(isCritical, false, data)); 637 } 638 639 @Override 640 public SignatureSubpackets addEmbeddedSignature(@Nonnull EmbeddedSignature embeddedSignature) { 641 this.embeddedSignatureList.add(embeddedSignature); 642 return this; 643 } 644 645 @Override 646 public SignatureSubpackets clearEmbeddedSignatures() { 647 this.embeddedSignatureList.clear(); 648 return this; 649 } 650 651 public List<EmbeddedSignature> getEmbeddedSignatureSubpackets() { 652 return new ArrayList<>(embeddedSignatureList); 653 } 654 655 public SignatureSubpackets addResidualSubpacket(SignatureSubpacket subpacket) { 656 this.residualSubpackets.add(subpacket); 657 return this; 658 } 659 660 public List<SignatureSubpacket> getResidualSubpackets() { 661 return new ArrayList<>(residualSubpackets); 662 } 663 664}