minio / minio-go

MinIO Go client SDK for S3 compatible object storage
https://docs.min.io/docs/golang-client-quickstart-guide.html
Apache License 2.0
2.52k stars 649 forks source link

MinIO SDK GO with FIPS compatibility #2024

Open LeonidWeinberg opened 3 days ago

LeonidWeinberg commented 3 days ago

Hello,

I am using GO FIPS compliant image with MinioSDK v7.0.80 My program fails while using the following APIs

Code

`package main

import ( "bytes" "context" "fmt" "log"

"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"

)

func main() { minioClient, err := minio.New("minio:9000", &minio.Options{ Creds: credentials.NewStaticV4("admin", "secretpassword", ""), Secure: false, })

if err != nil {
    log.Fatalf("Failed to initialize MinIO client: %v", err)
}

minioClient.TraceOn(log.Writer())
bucketName := "test-s3-fips"

// Ensure the bucket exists
err = minioClient.MakeBucket(context.Background(), bucketName, minio.MakeBucketOptions{Region: "us-east-1"})
if err != nil {
    exists, errBucketExists := minioClient.BucketExists(context.Background(), bucketName)
    if errBucketExists == nil && exists {
        log.Printf("Bucket %s already exists\n", bucketName)
    } else {
        log.Fatalf("Failed to create bucket: %v", err)
    }
}

// Upload objects programmatically
objectsToUpload := []string{"object1.txt", "object2.txt", "object3.txt"}
for _, obj := range objectsToUpload {
    uploadObject(minioClient, bucketName, obj)
}

// Test RemoveObjectsWithResult
log.Println("Testing RemoveObjectsWithResult...")
//testRemoveObjectsWithResult(minioClient, bucketName, objectsToUpload)

// Re-upload objects for next test
for _, obj := range objectsToUpload {
    uploadObject(minioClient, bucketName, obj)
}

// Test RemoveObjects
log.Println("Testing RemoveObjects...")
testRemoveObjects(minioClient, bucketName, objectsToUpload)

}

func uploadObject(minioClient *minio.Client, bucketName, objectName string) { content := fmt.Sprintf("This is the content of %s", objectName) _, err := minioClient.PutObject( context.Background(), bucketName, objectName, bytes.NewReader([]byte(content)), int64(len(content)), minio.PutObjectOptions{ContentType: "text/plain"}, ) if err != nil { log.Fatalf("Failed to upload object %s: %v", objectName, err) } log.Printf("Successfully uploaded object: %s to bucket: %s", objectName, bucketName) }

func testRemoveObjectsWithResult(minioClient *minio.Client, bucketName string, objectsToDelete []string) { objectCh := make(chan minio.ObjectInfo) go func() { for _, obj := range objectsToDelete { objectCh <- minio.ObjectInfo{Key: obj} } close(objectCh) }()

// Call RemoveObjectsWithResult
errorCh := minioClient.RemoveObjectsWithResult(context.Background(), bucketName, objectCh, minio.RemoveObjectsOptions{})

log.Println("Starting RemoveObjectsWithResult...")
for err := range errorCh {
    if err.Err != nil {
        log.Printf("Failed to delete object %s: %v", err.ObjectName, err.Err)
    } else {
        log.Printf("Successfully deleted object: %s", err.ObjectName)
    }
}
log.Println("Completed RemoveObjectsWithResult.")

}

func testRemoveObjects(minioClient *minio.Client, bucketName string, objectsToDelete []string) { objectCh := make(chan minio.ObjectInfo) go func() { for _, obj := range objectsToDelete { objectCh <- minio.ObjectInfo{Key: obj} } close(objectCh) }()

// Call RemoveObjects
errorCh := minioClient.RemoveObjects(context.Background(), bucketName, objectCh, minio.RemoveObjectsOptions{})

log.Println("Starting RemoveObjects...")
for err := range errorCh {
    if err.Err != nil {
        log.Printf("Failed to delete object %s: %v", err.ObjectName, err.Err)
    } else {
        log.Printf("Successfully deleted object: %s", err.ObjectName)
    }
}
log.Println("Completed RemoveObjects.")

} `

Here is error (similar error for both APIs)

`2024/11/26 17:56:37 Successfully uploaded object: object3.txt to bucket: test-s3-fips 2024/11/26 17:56:37 Testing RemoveObjects... 2024/11/26 17:56:37 Starting RemoveObjects... panic: openssl: unsupported hash function: 2

goroutine 59 [running]: vendor/github.com/golang-fips/openssl/v2.newEvpHash(0x2, 0x10, 0x40) /usr/lib/go/src/vendor/github.com/golang-fips/openssl/v2/hash.go:127 +0x16a vendor/github.com/golang-fips/openssl/v2.NewMD5(...) /usr/lib/go/src/vendor/github.com/golang-fips/openssl/v2/hash.go:248 crypto/internal/backend.NewMD5(...) /usr/lib/go/src/crypto/internal/backend/openssl_linux.go:135 crypto/md5.New(...) /usr/lib/go/src/crypto/md5/md5.go:104 github.com/minio/minio-go/v7.init.func3() /home/nonroot/go/pkg/mod/github.com/minio/minio-go/v7@v7.0.80/utils.go:545 +0x25 sync.(Pool).Get(0xb39040) /usr/lib/go/src/sync/pool.go:155 +0xb1 github.com/minio/minio-go/v7.newMd5Hasher(...) /home/nonroot/go/pkg/mod/github.com/minio/minio-go/v7@v7.0.80/utils.go:550 github.com/minio/minio-go/v7.sumMD5Base64({0xc00007a1e0, 0x9a, 0xa0}) /home/nonroot/go/pkg/mod/github.com/minio/minio-go/v7@v7.0.80/utils.go:100 +0x49 github.com/minio/minio-go/v7.(Client).removeObjects(0xc00007cea0, {0x8cee60, 0xb684a0}, {0x80eb3d, 0xc}, 0xc00011c770, 0xc00026c2a0, {0x0?}) /home/nonroot/go/pkg/mod/github.com/minio/minio-go/v7@v7.0.80/api-remove.go:444 +0x385 created by github.com/minio/minio-go/v7.(*Client).RemoveObjects in goroutine 1 /home/nonroot/go/pkg/mod/github.com/minio/minio-go/v7@v7.0.80/api-remove.go:309 +0x186`

klauspost commented 3 days ago

MD5 should be redundant here: https://github.com/minio/minio-go/blob/v7.0.81/api-remove.go#L444 (there is SHA256)

Feel free to send a PR to remove it.