|
9 | 9 | "net/http" |
10 | 10 | "strings" |
11 | 11 |
|
| 12 | + "github.com/lestrrat-go/dsig" |
12 | 13 | "github.com/lestrrat-go/htmsig/component" |
13 | 14 | "github.com/lestrrat-go/htmsig/input" |
14 | | - "github.com/lestrrat-go/jwx/v3/jws/jwsbb" |
15 | 15 | "github.com/lestrrat-go/sfv" |
16 | 16 | ) |
17 | 17 |
|
@@ -198,104 +198,104 @@ func buildSignatureBase(ctx context.Context, def *input.Definition) ([]byte, err |
198 | 198 |
|
199 | 199 | // generateSignature creates a signature over the signature base using the provided key material |
200 | 200 | // This implements the HTTP_SIGN primitive function from RFC 9421 Section 3.3 |
201 | | -// Uses JWX's jwsbb (JWS Bare Bones) for cryptographic signing operations |
| 201 | +// Uses DSIG for cryptographic signing operations |
202 | 202 | func generateSignature(ctx context.Context, sigbase []byte, def *input.Definition, key any) ([]byte, error) { |
203 | | - // Determine the appropriate JWS algorithm, preferring explicit algorithm from Definition |
204 | | - algorithm, err := determineJWSAlgorithm(def, key) |
| 203 | + // Determine the appropriate algorithm, preferring explicit algorithm from Definition |
| 204 | + algorithm, err := determineAlgorithm(def, key) |
205 | 205 | if err != nil { |
206 | | - return nil, fmt.Errorf("failed to determine JWS algorithm: %w", err) |
| 206 | + return nil, fmt.Errorf("failed to determine algorithm: %w", err) |
207 | 207 | } |
208 | 208 |
|
209 | | - // Use JWX's jwsbb to sign the signature base directly |
| 209 | + // Use DSIG to sign the signature base directly |
210 | 210 | // RFC 9421 Section 3.3.7: "the HTTP message's signature base is used as the entire JWS Signing Input" |
211 | 211 | // "The JOSE Header is not used, and the signature base is not first encoded in Base64" |
212 | | - signature, err := jwsbb.Sign(key, algorithm, sigbase, nil) |
| 212 | + signature, err := dsig.Sign(key, algorithm, sigbase, nil) |
213 | 213 | if err != nil { |
214 | 214 | return nil, fmt.Errorf("failed to sign with algorithm %s: %w", algorithm, err) |
215 | 215 | } |
216 | 216 |
|
217 | 217 | return signature, nil |
218 | 218 | } |
219 | 219 |
|
220 | | -// determineJWSAlgorithm determines the appropriate JWS algorithm from Definition and key material |
| 220 | +// determineAlgorithm determines the appropriate algorithm from Definition and key material |
221 | 221 | // First checks the explicit algorithm parameter in Definition, then falls back to key type detection |
222 | | -func determineJWSAlgorithm(def *input.Definition, key any) (string, error) { |
| 222 | +func determineAlgorithm(def *input.Definition, key any) (string, error) { |
223 | 223 | // First, check if algorithm is explicitly specified in the Definition |
224 | 224 | if algorithm := def.Algorithm(); algorithm != "" { |
225 | | - // Convert RFC 9421 algorithm names to JWS algorithm names |
226 | | - return convertRFC9421ToJWS(algorithm) |
| 225 | + // Convert RFC 9421 algorithm names to DSIG algorithm names |
| 226 | + return convertRFC9421ToDSIG(algorithm) |
227 | 227 | } |
228 | 228 |
|
229 | 229 | // Fallback to determining algorithm from key material |
230 | | - return determineJWSAlgorithmFromKey(key) |
| 230 | + return determineAlgorithmFromKey(key) |
231 | 231 | } |
232 | 232 |
|
233 | | -// convertRFC9421ToJWS converts RFC 9421 algorithm names to JWS algorithm identifiers |
234 | | -// Maps the official RFC 9421 algorithm registry entries to their corresponding JWS algorithm names |
235 | | -func convertRFC9421ToJWS(rfc9421Alg string) (string, error) { |
| 233 | +// convertRFC9421ToDSIG converts RFC 9421 algorithm names to DSIG algorithm identifiers |
| 234 | +// Maps the official RFC 9421 algorithm registry entries to their corresponding DSIG algorithm names |
| 235 | +func convertRFC9421ToDSIG(rfc9421Alg string) (string, error) { |
236 | 236 | switch rfc9421Alg { |
237 | 237 | // Official RFC 9421 algorithms from Section 6.2.2 Initial Contents |
238 | 238 | case "rsa-pss-sha512": // Section 3.3.1 |
239 | | - return "PS512", nil |
| 239 | + return dsig.RSAPSSWithSHA512, nil |
240 | 240 | case "rsa-v1_5-sha256": // Section 3.3.2 |
241 | | - return "RS256", nil |
| 241 | + return dsig.RSAPKCS1v15WithSHA256, nil |
242 | 242 | case "hmac-sha256": // Section 3.3.3 |
243 | | - return "HS256", nil |
| 243 | + return dsig.HMACWithSHA256, nil |
244 | 244 | case "ecdsa-p256-sha256": // Section 3.3.4 |
245 | | - return "ES256", nil |
| 245 | + return dsig.ECDSAWithP256AndSHA256, nil |
246 | 246 | case "ecdsa-p384-sha384": // Section 3.3.5 |
247 | | - return "ES384", nil |
| 247 | + return dsig.ECDSAWithP384AndSHA384, nil |
248 | 248 | case "ed25519": // Section 3.3.6 |
249 | | - return "EdDSA", nil |
| 249 | + return dsig.EdDSA, nil |
250 | 250 | default: |
251 | 251 | return "", fmt.Errorf("unsupported RFC 9421 algorithm: %s", rfc9421Alg) |
252 | 252 | } |
253 | 253 | } |
254 | 254 |
|
255 | | -// determineJWSAlgorithmFromKey determines the appropriate JWS algorithm from key material |
256 | | -// Maps key types to JWS algorithm identifiers for use with jwsbb |
257 | | -func determineJWSAlgorithmFromKey(key any) (string, error) { |
| 255 | +// determineAlgorithmFromKey determines the appropriate DSIG algorithm from key material |
| 256 | +// Maps key types to DSIG algorithm identifiers |
| 257 | +func determineAlgorithmFromKey(key any) (string, error) { |
258 | 258 | switch k := key.(type) { |
259 | 259 | case *rsa.PrivateKey: |
260 | | - // Use PS512 (RSA-PSS with SHA-512) as per RFC 9421 Section 3.3.1 |
261 | | - return "PS512", nil |
| 260 | + // Use RSA-PSS with SHA-512 as per RFC 9421 Section 3.3.1 |
| 261 | + return dsig.RSAPSSWithSHA512, nil |
262 | 262 | case *rsa.PublicKey: |
263 | | - // Use PS512 (RSA-PSS with SHA-512) for public key verification |
264 | | - return "PS512", nil |
| 263 | + // Use RSA-PSS with SHA-512 for public key verification |
| 264 | + return dsig.RSAPSSWithSHA512, nil |
265 | 265 | case *ecdsa.PrivateKey: |
266 | 266 | // Determine curve and select appropriate ECDSA algorithm |
267 | 267 | switch k.Curve.Params().Name { |
268 | 268 | case "P-256": |
269 | | - // ES256 (ECDSA using P-256 and SHA-256) as per RFC 9421 Section 3.3.4 |
270 | | - return "ES256", nil |
| 269 | + // ECDSA using P-256 and SHA-256 as per RFC 9421 Section 3.3.4 |
| 270 | + return dsig.ECDSAWithP256AndSHA256, nil |
271 | 271 | case "P-384": |
272 | | - // ES384 (ECDSA using P-384 and SHA-384) as per RFC 9421 Section 3.3.5 |
273 | | - return "ES384", nil |
| 272 | + // ECDSA using P-384 and SHA-384 as per RFC 9421 Section 3.3.5 |
| 273 | + return dsig.ECDSAWithP384AndSHA384, nil |
274 | 274 | default: |
275 | 275 | return "", fmt.Errorf("unsupported ECDSA curve: %s", k.Curve.Params().Name) |
276 | 276 | } |
277 | 277 | case *ecdsa.PublicKey: |
278 | 278 | // Determine curve and select appropriate ECDSA algorithm for public key |
279 | 279 | switch k.Curve.Params().Name { |
280 | 280 | case "P-256": |
281 | | - return "ES256", nil |
| 281 | + return dsig.ECDSAWithP256AndSHA256, nil |
282 | 282 | case "P-384": |
283 | | - return "ES384", nil |
| 283 | + return dsig.ECDSAWithP384AndSHA384, nil |
284 | 284 | default: |
285 | 285 | return "", fmt.Errorf("unsupported ECDSA curve: %s", k.Curve.Params().Name) |
286 | 286 | } |
287 | 287 | case ed25519.PrivateKey: |
288 | 288 | // EdDSA using Ed25519 as per RFC 9421 Section 3.3.6 |
289 | | - return "EdDSA", nil |
| 289 | + return dsig.EdDSA, nil |
290 | 290 | case ed25519.PublicKey: |
291 | 291 | // EdDSA using Ed25519 for public key verification |
292 | | - return "EdDSA", nil |
| 292 | + return dsig.EdDSA, nil |
293 | 293 | case []byte: |
294 | | - // HS256 (HMAC using SHA-256) for raw byte keys as per RFC 9421 Section 3.3.3 |
295 | | - return "HS256", nil |
| 294 | + // HMAC using SHA-256 for raw byte keys as per RFC 9421 Section 3.3.3 |
| 295 | + return dsig.HMACWithSHA256, nil |
296 | 296 | case string: |
297 | | - // HS256 (HMAC using SHA-256) for string keys as per RFC 9421 Section 3.3.3 |
298 | | - return "HS256", nil |
| 297 | + // HMAC using SHA-256 for string keys as per RFC 9421 Section 3.3.3 |
| 298 | + return dsig.HMACWithSHA256, nil |
299 | 299 | default: |
300 | 300 | return "", fmt.Errorf("unsupported key type: %T", key) |
301 | 301 | } |
@@ -410,18 +410,18 @@ func resolveKey(keyOrResolver any, def *input.Definition) (any, error) { |
410 | 410 | } |
411 | 411 |
|
412 | 412 | // verifySignature verifies a single signature using the HTTP_VERIFY primitive from RFC 9421 Section 3.3 |
413 | | -// Uses JWX's jwsbb for cryptographic verification operations |
| 413 | +// Uses DSIG for cryptographic verification operations |
414 | 414 | func verifySignature(_ context.Context, signatureBase []byte, signatureBytes []byte, def *input.Definition, key any) error { |
415 | | - // Determine the appropriate JWS algorithm, preferring explicit algorithm from Definition |
416 | | - algorithm, err := determineJWSAlgorithm(def, key) |
| 415 | + // Determine the appropriate algorithm, preferring explicit algorithm from Definition |
| 416 | + algorithm, err := determineAlgorithm(def, key) |
417 | 417 | if err != nil { |
418 | | - return fmt.Errorf("failed to determine JWS algorithm: %w", err) |
| 418 | + return fmt.Errorf("failed to determine algorithm: %w", err) |
419 | 419 | } |
420 | 420 |
|
421 | | - // Use JWX's jwsbb to verify the signature directly |
| 421 | + // Use DSIG to verify the signature directly |
422 | 422 | // RFC 9421 Section 3.3.7: "the HTTP message's signature base is used as the entire JWS Signing Input" |
423 | 423 | // "The JOSE Header is not used, and the signature base is not first encoded in Base64" |
424 | | - err = jwsbb.Verify(key, algorithm, signatureBase, signatureBytes) |
| 424 | + err = dsig.Verify(key, algorithm, signatureBase, signatureBytes) |
425 | 425 | if err != nil { |
426 | 426 | return fmt.Errorf("cryptographic verification failed with algorithm %s: %w", algorithm, err) |
427 | 427 | } |
|
0 commit comments