feat(saml): implementation of saml for ZITADEL v2 (#3618)

This commit is contained in:
Stefan Benz
2022-09-12 17:18:08 +01:00
committed by GitHub
parent 01a92ba5d9
commit 7a5f7f82cf
134 changed files with 5570 additions and 1293 deletions

View File

@@ -2,6 +2,10 @@ package command
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"math/big"
"time"
"github.com/zitadel/zitadel/internal/api/authz"
@@ -34,3 +38,138 @@ func (c *Commands) GenerateSigningKeyPair(ctx context.Context, algorithm string)
privateKeyExp, publicKeyExp))
return err
}
func (c *Commands) GenerateSAMLCACertificate(ctx context.Context, algorithm string) error {
now := time.Now().UTC()
after := now.Add(c.certificateLifetime)
randInt, err := rand.Int(rand.Reader, big.NewInt(1000))
if err != nil {
return err
}
privateCrypto, publicCrypto, certificateCrypto, err := crypto.GenerateEncryptedKeyPairWithCACertificate(c.certKeySize, c.keyAlgorithm, c.certificateAlgorithm, &crypto.CertificateInformations{
SerialNumber: randInt,
Organisation: []string{"ZITADEL"},
CommonName: "ZITADEL SAML CA",
NotBefore: now,
NotAfter: after,
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign,
})
if err != nil {
return err
}
keyID, err := c.idGenerator.Next()
if err != nil {
return err
}
keyPairWriteModel := NewKeyPairWriteModel(keyID, authz.GetInstance(ctx).InstanceID())
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
_, err = c.eventstore.Push(ctx,
keypair.NewAddedEvent(
ctx,
keyAgg,
domain.KeyUsageSAMLCA,
algorithm,
privateCrypto, publicCrypto,
after, after,
),
keypair.NewAddedCertificateEvent(
ctx,
keyAgg,
certificateCrypto,
after,
),
)
return err
}
func (c *Commands) GenerateSAMLResponseCertificate(ctx context.Context, algorithm string, caPrivateKey *rsa.PrivateKey, caCertificate []byte) error {
now := time.Now().UTC()
after := now.Add(c.certificateLifetime)
randInt, err := rand.Int(rand.Reader, big.NewInt(1000))
if err != nil {
return err
}
privateCrypto, publicCrypto, certificateCrypto, err := crypto.GenerateEncryptedKeyPairWithCertificate(c.certKeySize, c.keyAlgorithm, c.certificateAlgorithm, caPrivateKey, caCertificate, &crypto.CertificateInformations{
SerialNumber: randInt,
Organisation: []string{"ZITADEL"},
CommonName: "ZITADEL SAML response",
NotBefore: now,
NotAfter: after,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
})
if err != nil {
return err
}
keyID, err := c.idGenerator.Next()
if err != nil {
return err
}
keyPairWriteModel := NewKeyPairWriteModel(keyID, authz.GetInstance(ctx).InstanceID())
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
_, err = c.eventstore.Push(ctx,
keypair.NewAddedEvent(
ctx,
keyAgg,
domain.KeyUsageSAMLResponseSinging,
algorithm,
privateCrypto, publicCrypto,
after, after,
),
keypair.NewAddedCertificateEvent(
ctx,
keyAgg,
certificateCrypto,
after,
),
)
return err
}
func (c *Commands) GenerateSAMLMetadataCertificate(ctx context.Context, algorithm string, caPrivateKey *rsa.PrivateKey, caCertificate []byte) error {
now := time.Now().UTC()
after := now.Add(c.certificateLifetime)
randInt, err := rand.Int(rand.Reader, big.NewInt(1000))
if err != nil {
return err
}
privateCrypto, publicCrypto, certificateCrypto, err := crypto.GenerateEncryptedKeyPairWithCertificate(c.certKeySize, c.keyAlgorithm, c.certificateAlgorithm, caPrivateKey, caCertificate, &crypto.CertificateInformations{
SerialNumber: randInt,
Organisation: []string{"ZITADEL"},
CommonName: "ZITADEL SAML metadata",
NotBefore: now,
NotAfter: after,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageKeyEncipherment,
})
if err != nil {
return err
}
keyID, err := c.idGenerator.Next()
if err != nil {
return err
}
keyPairWriteModel := NewKeyPairWriteModel(keyID, authz.GetInstance(ctx).InstanceID())
keyAgg := KeyPairAggregateFromWriteModel(&keyPairWriteModel.WriteModel)
_, err = c.eventstore.Push(ctx,
keypair.NewAddedEvent(
ctx,
keyAgg,
domain.KeyUsageSAMLMetadataSigning,
algorithm,
privateCrypto, publicCrypto,
after, after),
keypair.NewAddedCertificateEvent(
ctx,
keyAgg,
certificateCrypto,
after,
),
)
return err
}