| 115 | } |
| 116 | |
| 117 | func (service *OIDCService) Init() error { |
| 118 | // If not configured, skip init |
| 119 | if len(service.config.Clients) == 0 { |
| 120 | service.isConfigured = false |
| 121 | return nil |
| 122 | } |
| 123 | |
| 124 | service.isConfigured = true |
| 125 | |
| 126 | // Ensure issuer is https |
| 127 | uissuer, err := url.Parse(service.config.Issuer) |
| 128 | |
| 129 | if err != nil { |
| 130 | return err |
| 131 | } |
| 132 | |
| 133 | if uissuer.Scheme != "https" { |
| 134 | return errors.New("issuer must be https") |
| 135 | } |
| 136 | |
| 137 | service.issuer = fmt.Sprintf("%s://%s", uissuer.Scheme, uissuer.Host) |
| 138 | |
| 139 | // Create/load private and public keys |
| 140 | if strings.TrimSpace(service.config.PrivateKeyPath) == "" || |
| 141 | strings.TrimSpace(service.config.PublicKeyPath) == "" { |
| 142 | return errors.New("private key path and public key path are required") |
| 143 | } |
| 144 | |
| 145 | var privateKey *rsa.PrivateKey |
| 146 | |
| 147 | fprivateKey, err := os.ReadFile(service.config.PrivateKeyPath) |
| 148 | |
| 149 | if err != nil && !errors.Is(err, os.ErrNotExist) { |
| 150 | return err |
| 151 | } |
| 152 | |
| 153 | if errors.Is(err, os.ErrNotExist) { |
| 154 | privateKey, err = rsa.GenerateKey(rand.Reader, 2048) |
| 155 | if err != nil { |
| 156 | return err |
| 157 | } |
| 158 | der := x509.MarshalPKCS1PrivateKey(privateKey) |
| 159 | if der == nil { |
| 160 | return errors.New("failed to marshal private key") |
| 161 | } |
| 162 | encoded := pem.EncodeToMemory(&pem.Block{ |
| 163 | Type: "RSA PRIVATE KEY", |
| 164 | Bytes: der, |
| 165 | }) |
| 166 | tlog.App.Trace().Str("type", "RSA PRIVATE KEY").Msg("Generated private RSA key") |
| 167 | err = os.WriteFile(service.config.PrivateKeyPath, encoded, 0600) |
| 168 | if err != nil { |
| 169 | return err |
| 170 | } |
| 171 | service.privateKey = privateKey |
| 172 | } else { |
| 173 | block, _ := pem.Decode(fprivateKey) |
| 174 | if block == nil { |