github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/show-cert/main.go (about)

     1  package main
     2  
     3  import (
     4  	"crypto/x509"
     5  	"encoding/pem"
     6  	"fmt"
     7  	"io"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"os"
    11  	"time"
    12  
    13  	"github.com/Cloud-Foundations/Dominator/lib/constants"
    14  	"github.com/Cloud-Foundations/Dominator/lib/format"
    15  	"github.com/Cloud-Foundations/Dominator/lib/stringutil"
    16  	"github.com/Cloud-Foundations/Dominator/lib/x509util"
    17  )
    18  
    19  func showCertFile(filename string) {
    20  	data, err := ioutil.ReadFile(filename)
    21  	if err != nil {
    22  		fmt.Fprintf(os.Stderr, "Unable to read certfile: %s\n", err)
    23  		return
    24  	}
    25  	fmt.Println("Certificate:", filename+":")
    26  	showCert(data)
    27  }
    28  
    29  func showCertMetadata() {
    30  	client := http.Client{Timeout: 100 * time.Millisecond}
    31  	resp, err := client.Get(constants.MetadataUrl +
    32  		constants.MetadataIdentityCert)
    33  	if err != nil {
    34  		return
    35  	}
    36  	defer resp.Body.Close()
    37  	if resp.StatusCode != http.StatusOK {
    38  		return
    39  	}
    40  	data, err := io.ReadAll(resp.Body)
    41  	if err != nil {
    42  		return
    43  	}
    44  	fmt.Println("Certificate:", "MetadataIdentity:")
    45  	showCert(data)
    46  }
    47  
    48  func showCert(data []byte) {
    49  	block, rest := pem.Decode(data)
    50  	if block == nil {
    51  		fmt.Fprintf(os.Stderr, "Failed to parse certificate PEM")
    52  		return
    53  	}
    54  	if len(rest) > 0 {
    55  		fmt.Fprintf(os.Stderr, "%d extra bytes in certfile\n", len(rest))
    56  		return
    57  	}
    58  	cert, err := x509.ParseCertificate(block.Bytes)
    59  	if err != nil {
    60  		fmt.Fprintf(os.Stderr, "Unable to parse certificate: %s\n", err)
    61  		return
    62  	}
    63  	now := time.Now()
    64  	if notYet := cert.NotBefore.Sub(now); notYet > 0 {
    65  		fmt.Fprintf(os.Stderr, "  Will not be valid for %s\n",
    66  			format.Duration(notYet))
    67  	}
    68  	if expired := now.Sub(cert.NotAfter); expired > 0 {
    69  		fmt.Fprintf(os.Stderr, "  Expired %s ago\n", format.Duration(expired))
    70  	} else {
    71  		fmt.Fprintf(os.Stderr, "  Valid until %s (%s from now)\n",
    72  			cert.NotAfter, format.Duration(-expired))
    73  	}
    74  	username, err := x509util.GetUsername(cert)
    75  	if err != nil {
    76  		fmt.Fprintf(os.Stderr, "Unable to get username: %s\n", err)
    77  		return
    78  	}
    79  	fmt.Printf("  Issued to: %s\n", username)
    80  	permittedMethods, err := x509util.GetPermittedMethods(cert)
    81  	if err != nil {
    82  		fmt.Fprintf(os.Stderr, "Unable to get methods: %s\n", err)
    83  		return
    84  	}
    85  	if len(permittedMethods) > 0 {
    86  		fmt.Println("  Permitted methods:")
    87  		showList(permittedMethods)
    88  	} else {
    89  		fmt.Println("  No methods are permitted")
    90  	}
    91  	groupList, err := x509util.GetGroupList(cert)
    92  	if err != nil {
    93  		fmt.Fprintf(os.Stderr, "Unable to get group list: %s\n", err)
    94  		return
    95  	}
    96  	if len(groupList) > 0 {
    97  		fmt.Println("  Group list:")
    98  		showList(groupList)
    99  	} else {
   100  		fmt.Println("  No group memberships")
   101  	}
   102  }
   103  
   104  func showList(list map[string]struct{}) {
   105  	sortedList := stringutil.ConvertMapKeysToList(list, true)
   106  	for _, entry := range sortedList {
   107  		fmt.Println("   ", entry)
   108  	}
   109  }
   110  
   111  func main() {
   112  	if len(os.Args) == 1 {
   113  		showCertMetadata()
   114  		return
   115  	}
   116  	for _, filename := range os.Args[1:] {
   117  		showCertFile(filename)
   118  	}
   119  }