@@ -19,6 +19,7 @@ import (
1919 "context"
2020 "crypto"
2121 "crypto/ecdsa"
22+ "crypto/ed25519"
2223 "crypto/sha256"
2324 "crypto/sha512"
2425 "crypto/x509"
@@ -261,15 +262,41 @@ func verifyOCISignature(ctx context.Context, verifier signature.Verifier, sig pa
261262 if err != nil {
262263 return err
263264 }
264- signature , err := base64 .StdEncoding .DecodeString (b64sig )
265+ decodedSignature , err := base64 .StdEncoding .DecodeString (b64sig )
265266 if err != nil {
266267 return err
267268 }
268269 payload , err := sig .Payload ()
269270 if err != nil {
270271 return err
271272 }
272- return verifier .VerifySignature (bytes .NewReader (signature ), bytes .NewReader (payload ), options .WithContext (ctx ))
273+ // For compatibility reasons, if ED25519ph is used, we try both ED25519 and ED25519ph.
274+ // Refusing to verify ED25519 signatures (used e.g. by rekord entries) would break compatibility.
275+ // The signature algorithm to use should be uniquely determined before this point.
276+ verificationErr := verifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
277+ if verificationErr == nil {
278+ return nil
279+ }
280+
281+ switch verifier .(type ) {
282+ case * signature.ED25519phVerifier :
283+ publicKey , err := verifier .PublicKey ()
284+ if err != nil {
285+ return err
286+ }
287+
288+ if edPublicKey , ok := publicKey .(ed25519.PublicKey ); ok {
289+ altVerifier , err := signature .LoadED25519Verifier (edPublicKey )
290+ if err != nil {
291+ return err
292+ }
293+
294+ fmt .Fprintf (os .Stderr , "Failed to verify signature with ED25519ph, falling back to ED25519 for backward compatibility.\n " )
295+ verificationErr = altVerifier .VerifySignature (bytes .NewReader (decodedSignature ), bytes .NewReader (payload ), options .WithContext (ctx ))
296+ }
297+ }
298+
299+ return verificationErr
273300}
274301
275302// ValidateAndUnpackCert creates a Verifier from a certificate. Verifies that the
0 commit comments