mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-21 16:40:52 +00:00
add .gpg url (match github behaviour) (#6610)
* add .gpg url (match github behaviour) * wildcard * test to export maximum data * working POC * add comment for old imported keys * cleaning * Update routers/user/profile.go Co-Authored-By: sapk <sapk@users.noreply.github.com> * add migration script * add integration tests
This commit is contained in:
parent
38889f09cb
commit
d699de32f2
10 changed files with 259 additions and 20 deletions
|
@ -43,6 +43,12 @@ type GPGKey struct {
|
|||
CanCertify bool
|
||||
}
|
||||
|
||||
//GPGKeyImport the original import of key
|
||||
type GPGKeyImport struct {
|
||||
KeyID string `xorm:"pk CHAR(16) NOT NULL"`
|
||||
Content string `xorm:"TEXT NOT NULL"`
|
||||
}
|
||||
|
||||
// BeforeInsert will be invoked by XORM before inserting a record
|
||||
func (key *GPGKey) BeforeInsert() {
|
||||
key.AddedUnix = util.TimeStampNow()
|
||||
|
@ -74,6 +80,18 @@ func GetGPGKeyByID(keyID int64) (*GPGKey, error) {
|
|||
return key, nil
|
||||
}
|
||||
|
||||
// GetGPGImportByKeyID returns the import public armored key by given KeyID.
|
||||
func GetGPGImportByKeyID(keyID string) (*GPGKeyImport, error) {
|
||||
key := new(GPGKeyImport)
|
||||
has, err := x.ID(keyID).Get(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if !has {
|
||||
return nil, ErrGPGKeyImportNotExist{keyID}
|
||||
}
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// checkArmoredGPGKeyString checks if the given key string is a valid GPG armored key.
|
||||
// The function returns the actual public key on success
|
||||
func checkArmoredGPGKeyString(content string) (*openpgp.Entity, error) {
|
||||
|
@ -84,15 +102,37 @@ func checkArmoredGPGKeyString(content string) (*openpgp.Entity, error) {
|
|||
return list[0], nil
|
||||
}
|
||||
|
||||
//addGPGKey add key and subkeys to database
|
||||
func addGPGKey(e Engine, key *GPGKey) (err error) {
|
||||
//addGPGKey add key, import and subkeys to database
|
||||
func addGPGKey(e Engine, key *GPGKey, content string) (err error) {
|
||||
//Add GPGKeyImport
|
||||
if _, err = e.Insert(GPGKeyImport{
|
||||
KeyID: key.KeyID,
|
||||
Content: content,
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
// Save GPG primary key.
|
||||
if _, err = e.Insert(key); err != nil {
|
||||
return err
|
||||
}
|
||||
// Save GPG subs key.
|
||||
for _, subkey := range key.SubsKey {
|
||||
if err := addGPGKey(e, subkey); err != nil {
|
||||
if err := addGPGSubKey(e, subkey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//addGPGSubKey add subkeys to database
|
||||
func addGPGSubKey(e Engine, key *GPGKey) (err error) {
|
||||
// Save GPG primary key.
|
||||
if _, err = e.Insert(key); err != nil {
|
||||
return err
|
||||
}
|
||||
// Save GPG subs key.
|
||||
for _, subkey := range key.SubsKey {
|
||||
if err := addGPGSubKey(e, subkey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -127,14 +167,14 @@ func AddGPGKey(ownerID int64, content string) (*GPGKey, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err = addGPGKey(sess, key); err != nil {
|
||||
if err = addGPGKey(sess, key, content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return key, sess.Commit()
|
||||
}
|
||||
|
||||
//base64EncPubKey encode public kay content to base 64
|
||||
//base64EncPubKey encode public key content to base 64
|
||||
func base64EncPubKey(pubkey *packet.PublicKey) (string, error) {
|
||||
var w bytes.Buffer
|
||||
err := pubkey.Serialize(&w)
|
||||
|
@ -144,6 +184,34 @@ func base64EncPubKey(pubkey *packet.PublicKey) (string, error) {
|
|||
return base64.StdEncoding.EncodeToString(w.Bytes()), nil
|
||||
}
|
||||
|
||||
//base64DecPubKey decode public key content from base 64
|
||||
func base64DecPubKey(content string) (*packet.PublicKey, error) {
|
||||
b, err := readerFromBase64(content)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//Read key
|
||||
p, err := packet.Read(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//Check type
|
||||
pkey, ok := p.(*packet.PublicKey)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("key is not a public key")
|
||||
}
|
||||
return pkey, nil
|
||||
}
|
||||
|
||||
//GPGKeyToEntity retrieve the imported key and the traducted entity
|
||||
func GPGKeyToEntity(k *GPGKey) (*openpgp.Entity, error) {
|
||||
impKey, err := GetGPGImportByKeyID(k.KeyID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return checkArmoredGPGKeyString(impKey.Content)
|
||||
}
|
||||
|
||||
//parseSubGPGKey parse a sub Key
|
||||
func parseSubGPGKey(ownerID int64, primaryID string, pubkey *packet.PublicKey, expiry time.Time) (*GPGKey, error) {
|
||||
content, err := base64EncPubKey(pubkey)
|
||||
|
@ -244,6 +312,11 @@ func deleteGPGKey(e *xorm.Session, keyID string) (int64, error) {
|
|||
if keyID == "" {
|
||||
return 0, fmt.Errorf("empty KeyId forbidden") //Should never happen but just to be sure
|
||||
}
|
||||
//Delete imported key
|
||||
n, err := e.Where("key_id=?", keyID).Delete(new(GPGKeyImport))
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
return e.Where("key_id=?", keyID).Or("primary_key_id=?", keyID).Delete(new(GPGKey))
|
||||
}
|
||||
|
||||
|
@ -339,22 +412,10 @@ func verifySign(s *packet.Signature, h hash.Hash, k *GPGKey) error {
|
|||
return fmt.Errorf("key can not sign")
|
||||
}
|
||||
//Decode key
|
||||
b, err := readerFromBase64(k.Content)
|
||||
pkey, err := base64DecPubKey(k.Content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//Read key
|
||||
p, err := packet.Read(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//Check type
|
||||
pkey, ok := p.(*packet.PublicKey)
|
||||
if !ok {
|
||||
return fmt.Errorf("key is not a public key")
|
||||
}
|
||||
|
||||
return pkey.VerifySignature(h, s)
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue