1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
|
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package clearsign
import (
"bufio"
"bytes"
"crypto"
"fmt"
"io"
"strings"
"testing"
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/packet"
)
var allowAllAlgorithmsConfig = &packet.Config{
RejectPublicKeyAlgorithms: map[packet.PublicKeyAlgorithm]bool{},
RejectMessageHashAlgorithms: map[crypto.Hash]bool{},
RejectCurves: map[packet.Curve]bool{},
MinRSABits: 512,
}
func testParse(t *testing.T, input []byte, expected, expectedPlaintext string) {
b, rest := Decode(input)
if b == nil {
t.Fatal("failed to decode clearsign message")
}
if !bytes.Equal(rest, []byte("trailing")) {
t.Errorf("unexpected remaining bytes returned: %s", string(rest))
}
if b.ArmoredSignature.Type != "PGP SIGNATURE" {
t.Errorf("bad armor type, got:%s, want:PGP SIGNATURE", b.ArmoredSignature.Type)
}
if !bytes.Equal(b.Bytes, []byte(expected)) {
t.Errorf("bad body, got:%x want:%x", b.Bytes, expected)
}
if !bytes.Equal(b.Plaintext, []byte(expectedPlaintext)) {
t.Errorf("bad plaintext, got:%x want:%x", b.Plaintext, expectedPlaintext)
}
keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
if err != nil {
t.Errorf("failed to parse public key: %s", err)
}
if _, _, err := openpgp.VerifyDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body, allowAllAlgorithmsConfig); err != nil {
t.Errorf("failed to check signature: %s", err)
}
b, _ = Decode(input)
if _, err := b.VerifySignature(keyring, allowAllAlgorithmsConfig); err != nil {
t.Errorf("failed to check signature: %s", err)
}
}
func TestParse(t *testing.T) {
testParse(t, clearsignInput, "Hello world\r\nline 2", "Hello world\nline 2")
testParse(t, clearsignInput2, "\r\n\r\n(This message has a couple of blank lines at the start and end.)\r\n\r\n", "\n\n(This message has a couple of blank lines at the start and end.)\n\n")
}
func TestParseWithNoNewlineAtEnd(t *testing.T) {
input := clearsignInput
input = input[:len(input)-len("trailing")-1]
b, rest := Decode(input)
if b == nil {
t.Fatal("failed to decode clearsign message")
}
if len(rest) > 0 {
t.Errorf("unexpected remaining bytes returned: %s", string(rest))
}
}
var signingTests = []struct {
in, signed, plaintext string
}{
{"", "", ""},
{"a", "a", "a"},
{"a\n", "a\r\n", "a\n"},
{"-a\n", "-a\r\n", "-a\n"},
{"--a\nb", "--a\r\nb", "--a\nb"},
// leading whitespace
{" a\n", " a\r\n", " a\n"},
{" a\n", " a\r\n", " a\n"},
// trailing whitespace (should be stripped)
{"a \n", "a\r\n", "a\n"},
{"a ", "a", "a"},
{" \n", "\r\n", "\n"},
{" ", "", ""},
{"a\n \n \nb\n", "a\r\n\r\n\r\nb\r\n", "a\n\n\nb\n"},
{"a\n \n \nb\n", "a\r\n\r\n\r\nb\r\n", "a\n\n\nb\n"},
}
func TestVerifyV6(t *testing.T) {
keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(clearSignV6PublicKey))
if err != nil {
t.Errorf("failed to parse public key: %s", err)
}
b, _ := Decode([]byte(clearSignV6))
_, err = b.VerifySignature(keyring, nil)
if err != nil {
t.Errorf("failed to verify signature: %s", err)
}
}
func TestSigning(t *testing.T) {
keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
if err != nil {
t.Errorf("failed to parse public key: %s", err)
}
for i, test := range signingTests {
var buf bytes.Buffer
plaintext, err := Encode(&buf, keyring[0].PrivateKey, allowAllAlgorithmsConfig)
if err != nil {
t.Errorf("#%d: error from Encode: %s", i, err)
continue
}
if _, err := plaintext.Write([]byte(test.in)); err != nil {
t.Errorf("#%d: error from Write: %s", i, err)
continue
}
if err := plaintext.Close(); err != nil {
t.Fatalf("#%d: error from Close: %s", i, err)
continue
}
b, _ := Decode(buf.Bytes())
if b == nil {
t.Errorf("#%d: failed to decode clearsign message", i)
continue
}
if !bytes.Equal(b.Bytes, []byte(test.signed)) {
t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Bytes, test.signed)
continue
}
if !bytes.Equal(b.Plaintext, []byte(test.plaintext)) {
t.Errorf("#%d: bad result, got:%x, want:%x", i, b.Plaintext, test.plaintext)
continue
}
if _, _, err := openpgp.VerifyDetachedSignature(keyring, bytes.NewBuffer(b.Bytes), b.ArmoredSignature.Body, allowAllAlgorithmsConfig); err != nil {
t.Errorf("#%d: failed to check signature: %s", i, err)
}
}
}
func TestSigningInterop(t *testing.T) {
keyring, err := openpgp.ReadArmoredKeyRing(bytes.NewBufferString(signingKey))
if err != nil {
t.Errorf("failed to parse public key: %s", err)
}
var buf bytes.Buffer
plaintext, err := Encode(&buf, keyring[0].PrivateKey, nil)
if err != nil {
t.Errorf("error from Encode")
}
if _, err := plaintext.Write([]byte(trickyGrocery)); err != nil {
t.Errorf("error from Write")
}
if err := plaintext.Close(); err != nil {
t.Fatalf("error from Close")
}
expected := "- - tofu\n- - vegetables\n- - noodles\n\n\n"
if !strings.Contains(buf.String(), expected) {
t.Fatalf("expected output to contain %s but got: %s", expected, buf.String())
}
}
func TestHashHeader(t *testing.T) {
tests := []struct {
name string
hashTypes []crypto.Hash
expected string
}{
{
name: "unique hashes",
hashTypes: []crypto.Hash{
crypto.SHA256,
crypto.SHA512,
crypto.SHA3_512,
},
expected: "Hash: SHA256,SHA512,SHA3-512\n",
},
{
name: "with duplicates",
hashTypes: []crypto.Hash{
crypto.SHA256,
crypto.SHA512,
crypto.SHA512,
crypto.SHA3_512,
},
expected: "Hash: SHA256,SHA512,SHA3-512\n",
},
{
name: "with duplicates",
hashTypes: []crypto.Hash{
crypto.SHA256,
crypto.SHA256,
crypto.SHA256,
crypto.SHA256,
},
expected: "Hash: SHA256\n",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
var buf bytes.Buffer
writer := bufio.NewWriter(&buf)
if err := writeHashHeader(writer, tc.hashTypes); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := writer.Flush(); err != nil {
t.Fatalf("flush failed: %v", err)
}
actual := buf.String()
if actual != tc.expected {
t.Errorf("output mismatch:\nExpected: %q\nActual: %q", tc.expected, actual)
}
})
}
}
func testMultiSign(t *testing.T, v6 bool) {
if testing.Short() {
t.Skip("skipping long test in -short mode")
}
config := packet.Config{V6Keys: v6}
for nKeys := 1; nKeys < 4; nKeys++ {
nextTest:
for nExtra := 2; nExtra < 4; nExtra++ {
var signKeys []*packet.PrivateKey
var verifyKeys openpgp.EntityList
desc := fmt.Sprintf("%d keys; %d of which will be used to verify", nKeys+nExtra, nKeys)
for i := 0; i < nKeys+nExtra; i++ {
e, err := openpgp.NewEntity("name", "comment", "email", &config)
if err != nil {
t.Errorf("cannot create key: %v", err)
continue nextTest
}
if i < nKeys {
verifyKeys = append(verifyKeys, e)
}
signKeys = append(signKeys, e.PrivateKey)
}
input := []byte("this is random text\r\n4 17")
var output bytes.Buffer
w, err := EncodeMultiWithHeader(&output, signKeys, nil, nil)
if err != nil {
t.Errorf("EncodeMulti (%s) failed: %v", desc, err)
}
if _, err := w.Write(input); err != nil {
t.Errorf("Write(%q) to signer (%s) failed: %v", string(input), desc, err)
}
if err := w.Close(); err != nil {
t.Errorf("Close() of signer (%s) failed: %v", desc, err)
}
block, _ := Decode(output.Bytes())
if string(block.Bytes) != string(input) {
t.Errorf("Inline data didn't match original; got %q want %q", string(block.Bytes), string(input))
}
config := &packet.Config{}
_, _, err = openpgp.VerifyDetachedSignature(verifyKeys, bytes.NewReader(block.Bytes), block.ArmoredSignature.Body, config)
if nKeys == 0 {
if err == nil {
t.Errorf("verifying inline (%s) succeeded; want failure", desc)
}
} else {
if err != nil {
t.Errorf("verifying inline (%s) failed (%v); want success", desc, err)
}
}
}
}
}
func TestMultiSignV4(t *testing.T) {
testMultiSign(t, false)
}
func TestMultiSignV6(t *testing.T) {
testMultiSign(t, true)
}
func TestDecodeMissingCRC(t *testing.T) {
block, rest := Decode(clearsignInput3)
if block == nil {
t.Fatal("failed to decode PGP signature missing a CRC")
}
if len(rest) > 0 {
t.Fatalf("Decode should not have any remaining data left: %s", rest)
}
if _, err := packet.Read(block.ArmoredSignature.Body); err != nil {
t.Error(err)
}
if _, err := packet.Read(block.ArmoredSignature.Body); err != io.EOF {
t.Error(err)
}
}
const signatureBlock = `
-----BEGIN PGP SIGNATURE-----
Version: OpenPrivacy 0.99
yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS
vBSFjNSiVHsuAA==
=njUN
-----END PGP SIGNATURE-----
`
var invalidInputs = []string{
`
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
(This message was truncated.)
`,
`
-----BEGIN PGP SIGNED MESSAGE-----garbage
Hash: SHA256
_o/
` + signatureBlock,
`
garbage-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
_o/
` + signatureBlock,
`
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA` + "\x0b\x0b" + `256
_o/
` + signatureBlock,
`
-----BEGIN PGP SIGNED MESSAGE-----
NotHash: SHA256
_o/
` + signatureBlock,
}
func TestParseInvalid(t *testing.T) {
for i, input := range invalidInputs {
if b, rest := Decode([]byte(input)); b != nil {
t.Errorf("#%d: decoded a bad clearsigned message without any error", i)
} else if string(rest) != input {
t.Errorf("#%d: did not return all data with a bad message", i)
}
}
}
var clearsignInput = []byte(`
;lasjlkfdsa
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello world
line 2
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
iJwEAQECAAYFAk8kMuEACgkQO9o98PRieSpMsAQAhmY/vwmNpflrPgmfWsYhk5O8
pjnBUzZwqTDoDeINjZEoPDSpQAHGhjFjgaDx/Gj4fAl0dM4D0wuUEBb6QOrwflog
2A2k9kfSOMOtk0IH/H5VuFN1Mie9L/erYXjTQIptv9t9J7NoRBMU0QOOaFU0JaO9
MyTpno24AjIAGb+mH1U=
=hIJ6
-----END PGP SIGNATURE-----
trailing`)
var clearsignInput2 = []byte(`
asdlfkjasdlkfjsadf
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
(This message has a couple of blank lines at the start and end.)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
iJwEAQEIAAYFAlPpSREACgkQO9o98PRieSpZTAP+M8QUoCt/7Rf3YbXPcdzIL32v
pt1I+cMNeopzfLy0u4ioEFi8s5VkwpL1AFmirvgViCwlf82inoRxzZRiW05JQ5LI
ESEzeCoy2LIdRCQ2hcrG8pIUPzUO4TqO5D/dMbdHwNH4h5nNmGJUAEG6FpURlPm+
qZg6BaTvOxepqOxnhVU=
=e+C6
-----END PGP SIGNATURE-----
trailing`)
var clearsignInput3 = []byte(`-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
Origin: vscode stable
Label: vscode stable
Suite: stable
Codename: stable
Date: Mon, 13 Jan 2020 08:41:45 UTC
Architectures: amd64
Components: main
Description: Generated by aptly
MD5Sum:
66437152b3082616d8053e52c4bafafb 5821166 Contents-amd64
8024662ed51109946a517754bbafdd33 286298 Contents-amd64.gz
66437152b3082616d8053e52c4bafafb 5821166 main/Contents-amd64
8024662ed51109946a517754bbafdd33 286298 main/Contents-amd64.gz
3062a08b3eca94a65d6d17ba1dafcf3e 1088265 main/binary-amd64/Packages
b8ee22200fba8fa3be56c1ff946cdd24 159344 main/binary-amd64/Packages.bz2
f89c47c81ebd25caf287c8e6dda16c1a 169456 main/binary-amd64/Packages.gz
4c9ca25b556f111a5536c78df885ad82 95 main/binary-amd64/Release
SHA1:
2b62d0e322746b7d094878278f49993ca4314bf7 5821166 Contents-amd64
aafe35cce12e03d8b1939e403ddf5c0958c6e9bd 286298 Contents-amd64.gz
2b62d0e322746b7d094878278f49993ca4314bf7 5821166 main/Contents-amd64
aafe35cce12e03d8b1939e403ddf5c0958c6e9bd 286298 main/Contents-amd64.gz
30316ac5d4ce3b472a96a797eeb0a2a82d43ed3e 1088265 main/binary-amd64/Packages
6507e0b4da8194fd1048fcbb74c6e7433edaf3d6 159344 main/binary-amd64/Packages.bz2
ec9d39c39567c74001221e4900fb5d11ec11b833 169456 main/binary-amd64/Packages.gz
58bf20987a91d35936f18efce75ea233d43dbf8b 95 main/binary-amd64/Release
SHA256:
deff9ebfc44bf482e10a6ea10f608c6bb0fdc8373bf86b88cad9d99879ae3c39 5821166 Contents-amd64
f163bc65c7666ef58e0be3336e8c846ae2b7b388fbb2d7db0bcdc3fd1abae462 286298 Contents-amd64.gz
deff9ebfc44bf482e10a6ea10f608c6bb0fdc8373bf86b88cad9d99879ae3c39 5821166 main/Contents-amd64
f163bc65c7666ef58e0be3336e8c846ae2b7b388fbb2d7db0bcdc3fd1abae462 286298 main/Contents-amd64.gz
0fba50799ef72d0c2b354d0bcbbc8c623f6dae5a7fd7c218a54ea44dd8a49d5e 1088265 main/binary-amd64/Packages
69382470a88b67acde80fe45ab223016adebc445713ff0aa3272902581d21f13 159344 main/binary-amd64/Packages.bz2
1724b8ace5bd8882943e9463d8525006f33ca704480da0186fd47937451dc216 169456 main/binary-amd64/Packages.gz
0f509a0cb07e0ab433176fa47a21dccccc6b519f25f640cc58561104c11de6c2 95 main/binary-amd64/Release
SHA512:
f69f09c6180ceb6625a84b5f7123ad27972983146979dcfd9c38b2990459b52b4975716f85374511486bb5ad5852ebb1ef8265176df7134fc15b17ada3ba596c 5821166 Contents-amd64
46031bf89166188989368957d20cdcaac6eec72bab3f9839c9704bb08cbee3174ca6da11e290b0eab0e6b5754c1e7feb06d18ec9c5a0c955029cef53235e0a3a 286298 Contents-amd64.gz
f69f09c6180ceb6625a84b5f7123ad27972983146979dcfd9c38b2990459b52b4975716f85374511486bb5ad5852ebb1ef8265176df7134fc15b17ada3ba596c 5821166 main/Contents-amd64
46031bf89166188989368957d20cdcaac6eec72bab3f9839c9704bb08cbee3174ca6da11e290b0eab0e6b5754c1e7feb06d18ec9c5a0c955029cef53235e0a3a 286298 main/Contents-amd64.gz
3f78baf5adbaf0100996555b154807c794622fd0b5879b568ae0b6560e988fbfabed8d97db5a703d1a58514b9690fc6b60f9ad2eeece473d86ab257becd0ae41 1088265 main/binary-amd64/Packages
18f26df90beff29192662ca40525367c3c04f4581d59d2e9ab1cd0700a145b6a292a1609ca33ebe1c211f13718a8eee751f41fd8189cf93d52aa3e0851542dfc 159344 main/binary-amd64/Packages.bz2
6a6d917229e0cf06c493e174a87d76e815717676f2c70bcbd3bc689a80bd3c5489ea97db83b8f74cba8e70f374f9d9974f22b1ed2687a4ba1dacd22fdef7e14d 169456 main/binary-amd64/Packages.gz
e1a4378ad266c13c2edf8a0e590fa4d11973ab99ce79f15af005cb838f1600f66f3dc6da8976fa8b474da9073c118039c27623ab3360c6df115071497fe4f50c 95 main/binary-amd64/Release
-----BEGIN PGP SIGNATURE-----
Version: BSN Pgp v1.0.0.0
iQEcBAEBCAAGBQJeHC1bAAoJEOs+lK2+EinPAg8H/1rrhcgfm1HYL+Vmr9Ns6ton
LWQ8r13ADN66UTRa3XsO9V+q1fYowTqpXq6EZt2Gmlby/cpDf7mFPM5IteOXWLl7
QcWxPKHcdPIUi+h5F7BkFW65imP9GyX+V5Pxx5X544op7hYKaI0gAQ1oYtWDb3HE
4D27fju6icbj8w6E8TePcrDn82UvWAcaI5WSLboyhXCt2DxS3PNGFlyaP58zKJ8F
9cbBzksuMgMaTPAAMrU0zrFGfGeQz0Yo6nV/gRGiQaL9pSeIJWSKLNCMG/nIGmv2
xHVNFqTEetREY6UcQmuhwOn4HezyigH6XCBVp/Uez1izXiNdwBOet34SSvnkuJ4=
-----END PGP SIGNATURE-----`)
var signingKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1.4.10 (GNU/Linux)
lQHYBE2rFNoBBADFwqWQIW/DSqcB4yCQqnAFTJ27qS5AnB46ccAdw3u4Greeu3Bp
idpoHdjULy7zSKlwR1EA873dO/k/e11Ml3dlAFUinWeejWaK2ugFP6JjiieSsrKn
vWNicdCS4HTWn0X4sjl0ZiAygw6GNhqEQ3cpLeL0g8E9hnYzJKQ0LWJa0QARAQAB
AAP/TB81EIo2VYNmTq0pK1ZXwUpxCrvAAIG3hwKjEzHcbQznsjNvPUihZ+NZQ6+X
0HCfPAdPkGDCLCb6NavcSW+iNnLTrdDnSI6+3BbIONqWWdRDYJhqZCkqmG6zqSfL
IdkJgCw94taUg5BWP/AAeQrhzjChvpMQTVKQL5mnuZbUCeMCAN5qrYMP2S9iKdnk
VANIFj7656ARKt/nf4CBzxcpHTyB8+d2CtPDKCmlJP6vL8t58Jmih+kHJMvC0dzn
gr5f5+sCAOOe5gt9e0am7AvQWhdbHVfJU0TQJx+m2OiCJAqGTB1nvtBLHdJnfdC9
TnXXQ6ZXibqLyBies/xeY2sCKL5qtTMCAKnX9+9d/5yQxRyrQUHt1NYhaXZnJbHx
q4ytu0eWz+5i68IYUSK69jJ1NWPM0T6SkqpB3KCAIv68VFm9PxqG1KmhSrQIVGVz
dCBLZXmIuAQTAQIAIgUCTasU2gIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AA
CgkQO9o98PRieSoLhgQAkLEZex02Qt7vGhZzMwuN0R22w3VwyYyjBx+fM3JFETy1
ut4xcLJoJfIaF5ZS38UplgakHG0FQ+b49i8dMij0aZmDqGxrew1m4kBfjXw9B/v+
eIqpODryb6cOSwyQFH0lQkXC040pjq9YqDsO5w0WYNXYKDnzRV0p4H1pweo2VDid
AdgETasU2gEEAN46UPeWRqKHvA99arOxee38fBt2CI08iiWyI8T3J6ivtFGixSqV
bRcPxYO/qLpVe5l84Nb3X71GfVXlc9hyv7CD6tcowL59hg1E/DC5ydI8K8iEpUmK
/UnHdIY5h8/kqgGxkY/T/hgp5fRQgW1ZoZxLajVlMRZ8W4tFtT0DeA+JABEBAAEA
A/0bE1jaaZKj6ndqcw86jd+QtD1SF+Cf21CWRNeLKnUds4FRRvclzTyUMuWPkUeX
TaNNsUOFqBsf6QQ2oHUBBK4VCHffHCW4ZEX2cd6umz7mpHW6XzN4DECEzOVksXtc
lUC1j4UB91DC/RNQqwX1IV2QLSwssVotPMPqhOi0ZLNY7wIA3n7DWKInxYZZ4K+6
rQ+POsz6brEoRHwr8x6XlHenq1Oki855pSa1yXIARoTrSJkBtn5oI+f8AzrnN0BN
oyeQAwIA/7E++3HDi5aweWrViiul9cd3rcsS0dEnksPhvS0ozCJiHsq/6GFmy7J8
QSHZPteedBnZyNp5jR+H7cIfVN3KgwH/Skq4PsuPhDq5TKK6i8Pc1WW8MA6DXTdU
nLkX7RGmMwjC0DBf7KWAlPjFaONAX3a8ndnz//fy1q7u2l9AZwrj1qa1iJ8EGAEC
AAkFAk2rFNoCGwwACgkQO9o98PRieSo2/QP/WTzr4ioINVsvN1akKuekmEMI3LAp
BfHwatufxxP1U+3Si/6YIk7kuPB9Hs+pRqCXzbvPRrI8NHZBmc8qIGthishdCYad
AHcVnXjtxrULkQFGbGvhKURLvS9WnzD/m1K2zzwxzkPTzT9/Yf06O6Mal5AdugPL
VrM0m72/jnpKo04=
=zNCn
-----END PGP PRIVATE KEY BLOCK-----
`
// https://www.ietf.org/archive/id/draft-ietf-openpgp-crypto-refresh-08.html#name-sample-v6-certificate-trans
const clearSignV6PublicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
xioGY4d/4xsAAAAg+U2nu0jWCmHlZ3BqZYfQMxmZu52JGggkLq2EVD34laPCsQYf
GwoAAABCBYJjh3/jAwsJBwUVCg4IDAIWAAKbAwIeCSIhBssYbE8GCaaX5NUt+mxy
KwwfHifBilZwj2Ul7Ce62azJBScJAgcCAAAAAK0oIBA+LX0ifsDm185Ecds2v8lw
gyU2kCcUmKfvBXbAf6rhRYWzuQOwEn7E/aLwIwRaLsdry0+VcallHhSu4RN6HWaE
QsiPlR4zxP/TP7mhfVEe7XWPxtnMUMtf15OyA51YBM4qBmOHf+MZAAAAIIaTJINn
+eUBXbki+PSAld2nhJh/LVmFsS+60WyvXkQ1wpsGGBsKAAAALAWCY4d/4wKbDCIh
BssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce62azJAAAAAAQBIKbpGG2dWTX8
j+VjFM21J0hqWlEg+bdiojWnKfA5AQpWUWtnNwDEM0g12vYxoWM8Y81W+bHBw805
I8kWVkXU6vFOi+HWvv/ira7ofJu16NnoUkhclkUrk0mXubZvyl4GBg==
-----END PGP PUBLIC KEY BLOCK-----`
// https://gitlab.com/openpgp-wg/rfc4880bis/-/merge_requests/275
const clearSignV6 = `-----BEGIN PGP SIGNED MESSAGE-----
What we need from the grocery store:
- - tofu
- - vegetables
- - noodles
-----BEGIN PGP SIGNATURE-----
wpgGARsKAAAAKQWCY5ijYyIhBssYbE8GCaaX5NUt+mxyKwwfHifBilZwj2Ul7Ce6
2azJAAAAAGk2IHZJX1AhiJD39eLuPBgiUU9wUA9VHYblySHkBONKU/usJ9BvuAqo
/FvLFuGWMbKAdA+epq7V4HOtAPlBWmU8QOd6aud+aSunHQaaEJ+iTFjP2OMW0KBr
NK2ay45cX1IVAQ==
-----END PGP SIGNATURE-----`
const trickyGrocery = `From the grocery store we need:
- tofu
- vegetables
- noodles
`
|