golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.07k stars 17.68k forks source link

x/crypto/openpgp: handle "gnu-dummy" S2K #13605

Closed benburkert closed 3 years ago

benburkert commented 8 years ago

GPG added a "gnu-dummy" S2K type for keyrings that contain only subkey secret data (like in this guide). openpgp.ReadKeyRing returns an unsupported feature: S2K function error. Value 101 for a "gnu-dummy" S2K which x/crypto/openpgp/s2k.Parse doesn't recognize. Although RFC 4880 does not include this S2K, it does reserve 100 through 110 for extensions like this. These keys could be handled by adding Dummy bool field to encrypted keys and updating the S2K parser to recognize "gnu-dummy" type.

package main

import (
    "bytes"
    "encoding/base64"

    "golang.org/x/crypto/openpgp"
)

func main() {
    data, err := base64.StdEncoding.DecodeString(secring)
    if err != nil {
        panic(err)
    }

    if _, err = openpgp.ReadKeyRing(bytes.NewBuffer(data)); err != nil {
        panic(err)
    }
}

var secring = `lQCVBFZuSwwBBAC04VdUUq2REb7+IF/x21yOV3kIn798XRl7A7RiGcE9VpBjT5xMxtghWhH1mxyT+nrS36OJxdvtgJb3NB6hhh3qBQC6DmCGbWe61tT6TfyFbN6OvzZKMEa6RMunyd+2ErX4RLOcO+9X7a0weVASH5wRYjjqQtvPvt1/k25sloPnZQARAQAB/gNlAkdOVQG0EyA8dGVzdEBleGFtcGxlLmNvbT6IuAQTAQIAIgUCVm5LDAIbLwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQwaXYFkPfLEVROQP/RF4GXi/yGm6yQoDNXFkFiwNhJndayfZxf5Qa+JWz1ltLyal7Dm1c+U6/R/7D25gmEslI+5YrHpbExWXyfG8DbX/5Ef9Be04e9IvjoZboeRpxmyb8IflEw90tJGL8YAK2xWohvayigPnjjhycZQPMuMK9X35o89oJs+p1MxcC9EOwAgAAnQH9BFZuSwwBBADBDfq8oUK8Jr8IVkQEEEZzQ7AWh03oTVodROebMz4vAk34HkrebZuxT4U/8yFIP+kJ3Yie3T8V6F8jF3a3ZUHNj2ghgxMbPH+kRKwBphvX8Fb5GtoFVbJq1tNMDaLhVRIkDLBTqQp/20spcuU5+OMzQRUt+Z6GxMaUwt5zLHPUgwARAQAB/gMDAvozhXZdexxPYMKrp7yC2FNNpVAC61hD0VQKvFeeeXZIGOBx57F1wVBNjuPyglji0kaX0m9yYI+I1V546END4aV/hXlZve3r6qYVE9W+T1imwx1NXPSb0j/nMmdiFYFXuyz70yEO+cDwHONzmRLdBZlP1DKYBcjF7rwF0gWuIoWgDYdfECo/aANSRQtKw5Q6UowQLzpHTV+X6iL/CbjIL5f81KXPMO1AubxzAW+iatzI7jfL0MvA1FxRpMjpHc1uyT8oIfic17PklbjcnLe5GH782AEGhXwn4bY1H+ss0bxmkJV9HkcMokJUVMQxKw+a6+/IuLXdFtcA5z4CDeIbt9rv+b8s0bfq9aW4kDxG3PDcyoMTrTuJLBd6/XwJgdtrmLSCtlU4fLzZEoAd2FVyWbS6Nys3eXgIBkRRokzKANknne78LpvIiamzinb0iJk2X+AYnRKoy1pUsC+unqaXm9YHfdpxv/OXLe13zhSJAT0EGAECAAkFAlZuSwwCGy4AqAkQwaXYFkPfLEWdIAQZAQIABgUCVm5LDAAKCRBv1XiTGF5T/qsmA/9LOUNetM1QtsJ71OVdXE3dutUZULE/27DTrA/vvSfhzSFj3U3FnyI7AVsiiiwmnJnthf0zaa2HYBL844Bm7drtzGBNVvddgIJZKBE0x2vUlTVc661e2FBhtLh6xX2nhEy9owc+C7PR9OXvGiET8tTRnUDUO3PgPkyALkHfQMWMR11sA/0YQl4wf3knjk83DVVhFK5fT2lW4hmSO74tuCAA4V71C8B5rJzVq2vy1L2bGHAroe+LtX30LtZM5qWKzZzK7jjo1/eaXimOkJcnnpg6jmUP7TMkWpU7hlOQ3ZHjS2K5xJYJqBwP86TWPtDLxYD3mTlYtp2dDT8ogV/sEPPd44yWlrACAAA=`

The base64 encoded secring in the above contains a gnu-dummy S2K (notice the gnu-dummy S2K in the output):

$ gpg --list-packets secring.gpg
:secret key packet:
    version 4, algo 1, created 1450068748, expires 0
    skey[0]: [1024 bits]
    skey[1]: [17 bits]
    gnu-dummy S2K, algo: 3, SHA1 protection, hash: 2
    protect IV:
    keyid: C1A5D81643DF2C45
:user ID packet: " <test@example.com>"
:signature packet: algo 1, keyid C1A5D81643DF2C45
    version 4, created 1450068748, md5len 0, sigclass 0x13
    digest algo 2, begin of digest 51 39
    hashed subpkt 2 len 4 (sig created 2015-12-14)
    hashed subpkt 27 len 1 (key flags: 2F)
    hashed subpkt 11 len 5 (pref-sym-algos: 9 8 7 3 2)
    hashed subpkt 21 len 5 (pref-hash-algos: 8 2 9 10 11)
    hashed subpkt 22 len 3 (pref-zip-algos: 2 3 1)
    hashed subpkt 30 len 1 (features: 01)
    hashed subpkt 23 len 1 (key server preferences: 80)
    subpkt 16 len 8 (issuer key ID C1A5D81643DF2C45)
    data: [1023 bits]
:trust packet: flag=00 sigcache=00
:secret sub key packet:
    version 4, algo 1, created 1450068748, expires 0
    skey[0]: [1024 bits]
    skey[1]: [17 bits]
    iter+salt S2K, algo: 3, SHA1 protection, hash: 2, salt: fa3385765d7b1c4f
    protect count: 65536 (96)
    protect IV:  c2 ab a7 bc 82 d8 53 4d
    encrypted stuff follows
    keyid: 6FD57893185E53FE
:signature packet: algo 1, keyid C1A5D81643DF2C45
    version 4, created 1450068748, md5len 0, sigclass 0x18
    digest algo 2, begin of digest 5d 6c
    hashed subpkt 2 len 4 (sig created 2015-12-14)
    hashed subpkt 27 len 1 (key flags: 2E)
    subpkt 16 len 8 (issuer key ID C1A5D81643DF2C45)
    subpkt 32 len 156 (signature: v4, class 0x19, algo 1, digest algo 2)
    data: [1021 bits]
:trust packet: flag=00 sigcache=00
maxtaco commented 8 years ago

@rsc I've made some progress on this in my fork if you're curious. There are some cases we're not handling yet though, clearly...

maticmeznar commented 8 years ago

Is there an official answer on when this bug is going to be fixed?

bradfitz commented 8 years ago

Is there an official answer on when this bug is going to be fixed?

There is not.

This not a core part of Go. It's in an official golang.org subrepo and is subject to code review, but anybody can contribute fixes. Nobody works on the openpgp package full time.

maxtaco commented 8 years ago

We've made some more progress on our fork. Our support for Gnu S2K dummy and also YubiKeys is improved over the last few weeks.

maticmeznar commented 8 years ago

@maxtaco Would it be possible for you to make a PR (or whatever needs to be done according to https://golang.org/doc/contribute.html) with the bugfix so someone (@bradfitz ?) can review and (hopefully) accept it?

maxtaco commented 8 years ago

I previously tried that it and took a lot of effort to get ramped up on Gerrit in their PR workflow, but the PR was never reviewed, so I stopped. We've since made a lot of changes and we'd have to invest significant effort in fitting them into self-contained PRs.

Not to cast blame on the Go team, they're obviously extremely busy and doing great work. I also furthermore don't blame them that OpenPGP is low on their priority list, since with all of the upgrade churn from 2.0 to 2.1, and with smartcards / yubikeys, it's basically impossible to make a complete implementation.

bradfitz commented 8 years ago

I see one CL from you that hasn't been reviewed: https://go-review.googlesource.com/#/c/14794/

Is that the one?

Please ping that review. @agl is not a member of the Go team. He has a real job and just contributes (a ton) to Go when he has free time.

maxtaco commented 8 years ago

Sorry to be a totally noob, but how do I "ping" a review? Sorry to ask a silly question

alexbrainman commented 8 years ago

how do I "ping" a review?

There are multiple messages (2 at this moment) on the bottom of your code review screen (https://go-review.googlesource.com/#/c/14794/). These capture all messages sent to you and reviewers. You can reply to any of those messages by clicking "Reply to this message" button on the very right of expanded message. Just reply with "Ping" or any other message you want your reviewers to see (Brad set your reviewer to agl).

Alex

maxtaco commented 8 years ago

Thanks @alexbrainman, I gave it a try.

maxtaco commented 8 years ago

Thanks @bradfitz for the merge. Well, we have our work cut out for us for upstreaming the rest of the patches. I'll work on scheduling it into our backlog!

gopherbot commented 8 years ago

CL https://golang.org/cl/32797 mentions this issue.

karalabe commented 8 years ago

I wrote up a patch to fix this issue. Perhaps this round we can do a review faster than 7 months? ;)

NiklasMerz commented 6 years ago

@karalabe @agl Not quite less than 7 months ;)

FiloSottile commented 3 years ago

Per the accepted #44226 proposal and due to lack of maintenance, the golang.org/x/crypto/openpgp package is now frozen and deprecated. No new changes will be accepted except for security fixes. The package will not be removed.

If this is a security issue, please email security@golang.org and we will assess it and provide a fix.

If you're looking for alternatives, consider the crypto/ed25519 package for simple signatures, golang.org/x/mod/sumdb/note for inline signatures, or filippo.io/age for encryption. You can read a summary of OpenPGP issues and alternatives here.

If you are required to interoperate with OpenPGP systems and need a maintained package, we suggest considering one of multiple community forks of golang.org/x/crypto/openpgp. We don't endorse any specific one.