// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). You may not // use this file except in compliance with the License. A copy of the // License is located at // // http://aws.amazon.com/apache2.0/ // // or in the "license" file accompanying this file. This file is distributed // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, // either express or implied. See the License for the specific language governing // permissions and limitations under the License. //go:build freebsd || linux || netbsd || openbsd // +build freebsd linux netbsd openbsd package certreader import ( "fmt" "io/ioutil" "os" "path/filepath" "syscall" ) var getSys = func(info os.FileInfo) interface{} { return info.Sys() } var getIsRegular = func(info os.FileInfo) bool { return info.Mode().IsRegular() } var getPerm = func(info os.FileInfo) os.FileMode { return info.Mode().Perm() } var getStat = os.Stat var readFile = ioutil.ReadFile // ReadCertificates returns a certificate from a given path // If certificate or its containing folder is not owned by root, or does not have read only permissions, it returns an error func ReadCertificate(certificatePath string) ([]byte, error) { if certificatePath == "" { return nil, fmt.Errorf("Certificate path not set") } // Get folder stat folderStat, err := getStat(filepath.Dir(certificatePath)) if err != nil { return nil, fmt.Errorf("Certificate folder does not exist") } // Get folder resource information folderSys := getSys(folderStat) if folderSys.(*syscall.Stat_t).Uid != 0 || folderSys.(*syscall.Stat_t).Gid != 0 { return nil, fmt.Errorf("Certificate folder is not owned by root") } // Get file stat fileStat, err := getStat(certificatePath) if err != nil { return nil, fmt.Errorf("Certificate does not exist") } // Check if is file if !getIsRegular(fileStat) { return nil, fmt.Errorf("Certificate path is not a file") } // Check if certificate has read only permission if getPerm(fileStat) != 0400 { return nil, fmt.Errorf("Certificate does not have only owner read permission: %d", uint32(getPerm(fileStat))) } // Check if file ownership is root fileSys := getSys(fileStat) if fileSys.(*syscall.Stat_t).Uid != 0 || fileSys.(*syscall.Stat_t).Gid != 0 { return nil, fmt.Errorf("Certificate is not owned by root") } // Read certificate cert, err := readFile(certificatePath) if err != nil { return nil, fmt.Errorf("Failed to read certificate") } return cert, nil }