MCPcopy Index your code
hub / github.com/gogs/gogs / SSHNativeParsePublicKey

Function SSHNativeParsePublicKey

internal/database/ssh_key.go:217–269  ·  view source on GitHub ↗

SSHNativeParsePublicKey extracts the key type and length using the golang SSH library.

(keyLine string)

Source from the content-addressed store, hash-verified

215
216// SSHNativeParsePublicKey extracts the key type and length using the golang SSH library.
217func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
218 fields := strings.Fields(keyLine)
219 if len(fields) < 2 {
220 return "", 0, errors.Newf("not enough fields in public key line: %s", keyLine)
221 }
222
223 raw, err := base64.StdEncoding.DecodeString(fields[1])
224 if err != nil {
225 return "", 0, err
226 }
227
228 pkey, err := ssh.ParsePublicKey(raw)
229 if err != nil {
230 if strings.Contains(err.Error(), "ssh: unknown key algorithm") {
231 return "", 0, ErrKeyUnableVerify{err.Error()}
232 }
233 return "", 0, errors.Newf("ParsePublicKey: %v", err)
234 }
235
236 // The ssh library can parse the key, so next we find out what key exactly we have.
237 switch pkey.Type() {
238 case ssh.KeyAlgoDSA:
239 rawPub := struct {
240 Name string
241 P, Q, G, Y *big.Int
242 }{}
243 if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
244 return "", 0, err
245 }
246 // as per https://bugzilla.mindrot.org/show_bug.cgi?id=1647 we should never
247 // see dsa keys != 1024 bit, but as it seems to work, we will not check here
248 return "dsa", rawPub.P.BitLen(), nil // use P as per crypto/dsa/dsa.go (is L)
249 case ssh.KeyAlgoRSA:
250 rawPub := struct {
251 Name string
252 E *big.Int
253 N *big.Int
254 }{}
255 if err := ssh.Unmarshal(pkey.Marshal(), &rawPub); err != nil {
256 return "", 0, err
257 }
258 return "rsa", rawPub.N.BitLen(), nil // use N as per crypto/rsa/rsa.go (is bits)
259 case ssh.KeyAlgoECDSA256:
260 return "ecdsa", 256, nil
261 case ssh.KeyAlgoECDSA384:
262 return "ecdsa", 384, nil
263 case ssh.KeyAlgoECDSA521:
264 return "ecdsa", 521, nil
265 case ssh.KeyAlgoED25519:
266 return "ed25519", 256, nil
267 }
268 return "", 0, errors.Newf("unsupported key length detection for type: %s", pkey.Type())
269}
270
271// CheckPublicKeyString checks if the given public key string is recognized by SSH.
272// It returns the actual public key line on success.

Callers 2

TestSSHParsePublicKeyFunction · 0.85
CheckPublicKeyStringFunction · 0.85

Calls 1

ErrorMethod · 0.45

Tested by 1

TestSSHParsePublicKeyFunction · 0.68