golang / golang/go

x/crypto/ssh: ParseDSAPrivateKey lacks validation for DSA parameters

Open
#80,418 8 comments 0 reactions 0 assignees View on GitHub
NeedsDecision
Dominant language
Go
Stars
139k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

ParseDSAPrivateKey parses PEM/DER-encoded DSA private keys without validating the DSA parameters (P , Q , G , Y ). This allows structurally valid ASN.1 encoded keys with malformed or out-of-range parameters (such as an extremely large Q ) to be parsed successfully. Subsequent operations on these keys, such as dsa.Sign or dsa.Verify , can consume excessive CPU.

This is inconsistent with parseDSA and parseDSAKey , which validate parameters via checkDSAParams and range checks on Y.

### Expected Behavior

ParseDSAPrivateKey should validate that:

• Q and P bit lengths are correct.
• G and Y are within the valid group range.

### Actual Behavior

ParseDSAPrivateKey passes the parsed ASN.1 values directly to the dsa.PrivateKey structure without validation.

### Minimal Example

package main

import (
"crypto/dsa"
"encoding/asn1"
"encoding/pem"
"fmt"
"math/big"
"time"
"golang.org/x/crypto/ssh"
)

func main() {
hugeQ := new(big.Int).Lsh(big.NewInt(1), 20000)
p := new(big.Int).Lsh(big.NewInt(1), 1023)
g := big.NewInt(2)
y := big.NewInt(5)
x := big.NewInt(7)

type dsaKeyASN1 struct {
Version int
P, Q, G, Pub, Priv *big.Int
}
der, _ := asn1.Marshal(dsaKeyASN1{0, p, hugeQ, g, y, x})
pemBlock := pem.EncodeToMemory(&pem.Block{
Type: "DSA PRIVATE KEY",
Bytes: der,
})

key, err := ssh.ParseRawPrivateKey(pemBlock)
if err != nil {
fmt.Printf("Parse error: %v\n", err)
return
}

if priv, ok := key.(*dsa.PrivateKey); ok {
start := time.Now()
_, _ = dsa.Sign(nil, priv, make([]byte, 20))
fmt.Printf("Sign took: %v\n", time.Since(start))
}
}

Output:

Parse error:
Sign took: [very long]

This was originally reported by Prasanna Dabi (@prasanna8585).

cc @drakkan

Contributor guide

Open the contributing guide

Research direction

Start at ParseDSAPrivateKey and compare its handling with parseDSA and parseDSAKey, especially checkDSAParams and the Y range checks. Use the minimal example to reproduce acceptance of an extremely large Q, then verify malformed P, Q, G, and Y values are rejected and valid DSA private keys still parse successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cryptography, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.