Compare commits

..

4 Commits

Author SHA1 Message Date
Yang Luo
e5da57a005 feat: fix cert's ES options 2024-03-10 19:30:05 +08:00
Yang Luo
e4e225db32 Use "ES512" value 2024-03-10 19:25:41 +08:00
Yang Luo
a1add992ee Support legacy "RSA" value 2024-03-10 19:23:54 +08:00
Yang Luo
2aac265ed4 Improve populateContent() 2024-03-10 18:58:53 +08:00
5 changed files with 73 additions and 79 deletions

View File

@@ -16,7 +16,6 @@ package object
import (
"fmt"
"strings"
"github.com/casdoor/casdoor/util"
"github.com/xorm-io/core"
@@ -206,26 +205,41 @@ func (p *Cert) GetId() string {
}
func (p *Cert) populateContent() error {
if p.Certificate == "" || p.PrivateKey == "" {
var err error
var certificate, privateKey string
if strings.HasPrefix(p.CryptoAlgorithm, "RS") {
certificate, privateKey, err = generateRsaKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else if strings.HasPrefix(p.CryptoAlgorithm, "ES") {
certificate, privateKey, err = generateEsKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else if strings.HasPrefix(p.CryptoAlgorithm, "PS") {
certificate, privateKey, err = generateRsaPssKeys(p.BitSize, util.ParseInt(p.CryptoAlgorithm[2:]), p.ExpireInYears, p.Name, p.Owner)
} else {
err = fmt.Errorf("Crypto algorithm %s is not found", p.CryptoAlgorithm)
}
if err != nil {
return err
}
p.Certificate = certificate
p.PrivateKey = privateKey
if p.Certificate != "" && p.PrivateKey != "" {
return nil
}
if len(p.CryptoAlgorithm) < 3 {
err := fmt.Errorf("populateContent() error, unsupported crypto algorithm: %s", p.CryptoAlgorithm)
return err
}
if p.CryptoAlgorithm == "RSA" {
p.CryptoAlgorithm = "RS256"
}
sigAlgorithm := p.CryptoAlgorithm[:2]
shaSize, err := util.ParseIntWithError(p.CryptoAlgorithm[2:])
if err != nil {
return err
}
var certificate, privateKey string
if sigAlgorithm == "RS" {
certificate, privateKey, err = generateRsaKeys(p.BitSize, shaSize, p.ExpireInYears, p.Name, p.Owner)
} else if sigAlgorithm == "ES" {
certificate, privateKey, err = generateEsKeys(shaSize, p.ExpireInYears, p.Name, p.Owner)
} else if sigAlgorithm == "PS" {
certificate, privateKey, err = generateRsaPssKeys(p.BitSize, shaSize, p.ExpireInYears, p.Name, p.Owner)
} else {
err = fmt.Errorf("populateContent() error, unsupported signature algorithm: %s", sigAlgorithm)
}
if err != nil {
return err
}
p.Certificate = certificate
p.PrivateKey = privateKey
return nil
}

View File

@@ -27,7 +27,7 @@ import (
"time"
)
func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateRsaKeys(bitSize int, shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
// https://stackoverflow.com/questions/64104586/use-golang-to-get-rsa-key-the-same-way-openssl-genrsa
// https://stackoverflow.com/questions/43822945/golang-can-i-create-x509keypair-using-rsa-key
@@ -58,7 +58,7 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
BasicConstraintsValid: true,
}
switch algorithmType {
switch shaSize {
case 256:
tml.SignatureAlgorithm = x509.SHA256WithRSA
case 384:
@@ -66,7 +66,7 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
case 512:
tml.SignatureAlgorithm = x509.SHA512WithRSA
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateRsaKeys() error, unsupported SHA size: %d", shaSize)
}
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)
@@ -83,9 +83,9 @@ func generateRsaKeys(bitSize int, algorithmType int, expireInYears int, commonNa
return string(certPem), string(privateKeyPem), nil
}
func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateEsKeys(shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
var curve elliptic.Curve
switch algorithmType {
switch shaSize {
case 256:
curve = elliptic.P256()
case 384:
@@ -93,7 +93,7 @@ func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonNam
case 512:
curve = elliptic.P521() // ES512(P521,SHA512)
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateEsKeys() error, unsupported SHA size: %d", shaSize)
}
// Generate ECDSA key pair.
@@ -139,7 +139,7 @@ func generateEsKeys(bitSize int, algorithmType int, expireInYears int, commonNam
return string(certPem), string(privateKeyPem), nil
}
func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commonName string, organization string) (string, string, error) {
func generateRsaPssKeys(bitSize int, shaSize int, expireInYears int, commonName string, organization string) (string, string, error) {
// Generate RSA key.
key, err := rsa.GenerateKey(rand.Reader, bitSize)
if err != nil {
@@ -173,7 +173,7 @@ func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commo
}
// Set the signature algorithm based on the hash function
switch algorithmType {
switch shaSize {
case 256:
tml.SignatureAlgorithm = x509.SHA256WithRSAPSS
case 384:
@@ -181,7 +181,7 @@ func generateRsaPssKeys(bitSize int, algorithmType int, expireInYears int, commo
case 512:
tml.SignatureAlgorithm = x509.SHA512WithRSAPSS
default:
return "", "", fmt.Errorf("unsupported algorithm type")
return "", "", fmt.Errorf("generateRsaPssKeys() error, unsupported SHA size: %d", shaSize)
}
cert, err := x509.CreateCertificate(rand.Reader, &tml, &tml, &key.PublicKey, key)

View File

@@ -37,7 +37,7 @@ func TestGenerateRsaKeys(t *testing.T) {
func TestGenerateEsKeys(t *testing.T) {
fileId := "token_jwt_key"
certificate, privateKey, err := generateEsKeys(4096, 256, 20, "Casdoor Cert", "Casdoor Organization")
certificate, privateKey, err := generateEsKeys(256, 20, "Casdoor Cert", "Casdoor Organization")
if err != nil {
panic(err)
}

View File

@@ -171,21 +171,15 @@ class CertEditPage extends React.Component {
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.cryptoAlgorithm} onChange={(value => {
this.updateCertField("cryptoAlgorithm", value);
if (value === "RS256" || value === "PS256") {
this.updateCertField("bitSize", 2048);
} else if (value === "RS384" || value === "PS384") {
this.updateCertField("bitSize", 2048);
} else if (value === "RS512" || value === "PS512") {
this.updateCertField("bitSize", 2048);
} else if (value === "ES256") {
this.updateCertField("bitSize", 256);
} else if (value === "ES384") {
this.updateCertField("bitSize", 384);
} else if (value === "ES521") {
this.updateCertField("bitSize", 521);
} else {
if (value.startsWith("ES")) {
this.updateCertField("bitSize", 0);
} else {
if (this.state.cert.bitSize !== 1024 && this.state.cert.bitSize !== 2048 && this.state.cert.bitSize !== 4096) {
this.updateCertField("bitSize", 2048);
}
}
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
@@ -205,22 +199,26 @@ class CertEditPage extends React.Component {
</Select>
</Col>
</Row>
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Bit size"), i18next.t("cert:Bit size - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.bitSize} onChange={(value => {
this.updateCertField("bitSize", value);
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
{
Setting.getCryptoAlgorithmOptions(this.state.cert.cryptoAlgorithm).map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
</Col>
</Row>
{
this.state.cert.cryptoAlgorithm.startsWith("ES") ? null : (
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Bit size"), i18next.t("cert:Bit size - Tooltip"))} :
</Col>
<Col span={22} >
<Select virtual={false} style={{width: "100%"}} value={this.state.cert.bitSize} onChange={(value => {
this.updateCertField("bitSize", value);
this.updateCertField("certificate", "");
this.updateCertField("privateKey", "");
})}>
{
Setting.getCryptoAlgorithmOptions(this.state.cert.cryptoAlgorithm).map((item, index) => <Option key={index} value={item.id}>{item.name}</Option>)
}
</Select>
</Col>
</Row>
)
}
<Row style={{marginTop: "20px"}} >
<Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
{Setting.getLabel(i18next.t("cert:Expire in years"), i18next.t("cert:Expire in years - Tooltip"))} :

View File

@@ -1101,7 +1101,9 @@ export function getProviderTypeOptions(category) {
}
export function getCryptoAlgorithmOptions(cryptoAlgorithm) {
if (cryptoAlgorithm === "RS256") {
if (cryptoAlgorithm.startsWith("ES")) {
return [];
} else {
return (
[
{id: 1024, name: "1024"},
@@ -1109,26 +1111,6 @@ export function getCryptoAlgorithmOptions(cryptoAlgorithm) {
{id: 4096, name: "4096"},
]
);
} else if (cryptoAlgorithm === "HS256" || cryptoAlgorithm === "ES256") {
return (
[
{id: 256, name: "256"},
]
);
} else if (cryptoAlgorithm === "ES384") {
return (
[
{id: 384, name: "384"},
]
);
} else if (cryptoAlgorithm === "ES521") {
return (
[
{id: 521, name: "521"},
]
);
} else {
return [];
}
}