@@ -19,6 +19,7 @@ import (
1919 "context"
2020 "crypto"
2121 "crypto/ecdsa"
22+ "crypto/ed25519"
2223 "crypto/sha256"
2324 "crypto/sha512"
2425 "crypto/x509"
@@ -233,15 +234,41 @@ func verifyOCISignature(ctx context.Context, verifier signature.Verifier, sig pa
233234 if err != nil {
234235 return err
235236 }
236- signature , err := base64 .StdEncoding .DecodeString (b64sig )
237+ decodedSignature , err := base64 .StdEncoding .DecodeString (b64sig )
237238 if err != nil {
238239 return err
239240 }
240241 payload , err := sig .Payload ()
241242 if err != nil {
242243 return err
243244 }
244- return verifier .VerifySignature (bytes .NewReader (signature ), bytes .NewReader (payload ), options .WithContext (ctx ))
245+ // For compatibility reasons, if ED25519ph is used, we try both ED25519 and ED25519ph.
246+ // Refusing to verify ED25519 signatures (used e.g. by rekord entries) would break compatibility.
247+ // The signature algorithm to use should be uniquely determined before this point.
248+ verificationErr := verifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
249+ if verificationErr == nil {
250+ return nil
251+ }
252+
253+ switch verifier .(type ) {
254+ case * signature.ED25519phVerifier :
255+ publicKey , err := verifier .PublicKey ()
256+ if err != nil {
257+ return err
258+ }
259+
260+ if edPublicKey , ok := publicKey .(ed25519.PublicKey ); ok {
261+ altVerifier , err := signature .LoadED25519Verifier (edPublicKey )
262+ if err != nil {
263+ return err
264+ }
265+
266+ fmt .Fprintf (os .Stderr , "Failed to verify signature with ED25519ph, falling back to ED25519 for backward compatibility.\n " )
267+ verificationErr = altVerifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
268+ }
269+ }
270+
271+ return verificationErr
245272}
246273
247274// ValidateAndUnpackCert creates a Verifier from a certificate. Veries that the certificate
0 commit comments