WIP: implement openpgp signing
This commit is contained in:
parent
9f0916b14a
commit
c8e6792622
4 changed files with 93 additions and 2 deletions
|
@ -1,11 +1,82 @@
|
|||
package openpgp_ops
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"golang.org/x/crypto/openpgp"
|
||||
"golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
type OpenPGPRoot struct {
|
||||
Name string
|
||||
SecretKeyRing string
|
||||
Identifier string
|
||||
}
|
||||
|
||||
func (r *OpenPGPRoot) SignPublicKey(pubKey []byte, algorithm *crypto.Hash, days uint16) ([]byte, error) {
|
||||
signingKey, err := r.findSigningKey(r.Identifier)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not find a signing key matching %s: %v", r.Identifier, err)
|
||||
}
|
||||
|
||||
pubKeyRing, err := openpgp.ReadKeyRing(bytes.NewReader(pubKey))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read openpgp keyring: %v", err)
|
||||
}
|
||||
|
||||
signatures := make([]*openpgp.Entity, 0)
|
||||
|
||||
for _, pe := range pubKeyRing {
|
||||
log.Tracef("found %+v", pe)
|
||||
for _, i := range pe.Identities {
|
||||
if !i.SelfSignature.KeyExpired(time.Now()) {
|
||||
signConfig := &packet.Config{
|
||||
DefaultHash: *algorithm,
|
||||
Time: func() { return calculateExpiry(i, days) },
|
||||
}
|
||||
pe.SignIdentity(i.Name, signingKey, signConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func calculateExpiry(i *openpgp.Identity, days uint16) time.Time {
|
||||
maxExpiry := i.SelfSignature.CreationTime.Add(time.Second * time.Duration(*i.SelfSignature.KeyLifetimeSecs))
|
||||
calcExpiry := time.Now().Add(time.Hour * 24 * time.Duration(days))
|
||||
|
||||
if calcExpiry.After(maxExpiry) {
|
||||
return maxExpiry
|
||||
}
|
||||
return maxExpiry
|
||||
}
|
||||
|
||||
func (r *OpenPGPRoot) findSigningKey(identifier string) (*openpgp.Entity, error) {
|
||||
keyring, err := os.Open(r.SecretKeyRing)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not open secret keyring: %v", err)
|
||||
}
|
||||
defer func() { _ = keyring.Close() }()
|
||||
|
||||
el, err := openpgp.ReadKeyRing(keyring)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read keyring: %v", err)
|
||||
}
|
||||
for _, e := range el {
|
||||
log.Tracef("found %+v", e)
|
||||
for _, i := range e.Identities {
|
||||
if i.UserId.Email == identifier && len(e.Revocations) == 0 && !i.SelfSignature.KeyExpired(time.Now()) {
|
||||
return e, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("no matching key found")
|
||||
}
|
||||
|
||||
type OpenPGPProfile struct {
|
||||
Name string
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue