gopenpgp icon indicating copy to clipboard operation
gopenpgp copied to clipboard

Adding notation with a different name

Open Mihara opened this issue 2 years ago • 1 comments

I happen to require to add a notation when signing a key. Which crypto.NewSigningContext theoretically permits me to do, only, the name the notation will acquire appears to be hardcoded in constants/context.SignatureContextName. With my admittedly limited knowledge of golang, this becomes extremely problematic to fix.

Why?... Is this deliberate or a historical holdover of some sort?

Mihara avatar Jan 25 '24 10:01 Mihara

@Mihara

I don't know if it helps, but I wanted to embed custom notations to the public key. Then I figured it out to use the config. Here's my two cents.

I think it takes the same manner when signing too.

package main

import (
	"fmt"
	"time"

	"github.com/ProtonMail/go-crypto/openpgp/packet"
	v2 "github.com/ProtonMail/go-crypto/openpgp/v2"
	"github.com/ProtonMail/gopenpgp/v3/crypto"
)

func main() {
	// ------------------------------------------
	//  Generate a new key with custom notations
	// ------------------------------------------

	// Add custom notations to the configuration.
	conf := &packet.Config{
		Time: time.Now,
		SignatureNotations: []*packet.Notation{
			{
				Name:            "custom:mail",
				Value:           []byte("[email protected]"),
				IsHumanReadable: true,
			},
			{
				Name:            "custom:url",
				Value:           []byte("https://alice.example.com"),
				IsHumanReadable: true,
			},
		},
	}

	// Generate a new entity with the custom notations.
	entity, err := v2.NewEntity("Alice", "Test Key", "[email protected]", conf)
	panicOnError(err)

	key, err := crypto.NewKeyFromEntity(entity)
	panicOnError(err)

	pubKeyPEM, err := key.GetArmoredPublicKey()
	panicOnError(err)

	// ------------------------------------------
	//  List up the notations in the public key
	// ------------------------------------------

	pubKey, err := crypto.NewKeyFromArmored(pubKeyPEM)
	panicOnError(err)

	ent := pubKey.GetEntity()

	sig, err := ent.PrimarySelfSignature(time.Now().Add(300*time.Second), nil)
	panicOnError(err)

	fmt.Println("* Notations:")
	for _, notation := range sig.Notations {
		// As per the design specification, this notation is always present with random value.
		if notation.Name == "[email protected]" {
			// Random salt value for EdDSA signatures to avoid mitigating fault attacks.
			// - https://github.com/ProtonMail/go-crypto/pull/209
			// - https://github.com/openpgpjs/openpgpjs/pull/1737
			// - https://github.com/ProtonMail/go-crypto/releases/tag/v1.1.0-alpha.4
			fmt.Printf("- Key(Name): %s, Value: [random value]\n", notation.Name)

			continue
		}

		// List up the Name and Value of the notations.
		if notation.IsHumanReadable {
			fmt.Printf("- Key(Name): %s, Value: %s\n", notation.Name, notation.Value)

			continue
		}

		// Print the non-human-readable notation value in HEX.
		fmt.Printf("- Key(Name): %s, Value: %X\n", notation.Name, notation.Value)
	}

	// Output:
	// * Notations:
	// - Key(Name): custom:mail, Value: [email protected]
	// - Key(Name): custom:url, Value: https://alice.example.com
	// - Key(Name): [email protected], Value: [random value]
}

func panicOnError(err error) {
	if err != nil {
		panic(err)
	}
}

KEINOS avatar Feb 11 '25 01:02 KEINOS