func loadSystemRoots() (*CertPool, error) { const CRYPT_E_NOT_FOUND = 0x80092004 store, err := syscall.CertOpenSystemStore(0, syscall.StringToUTF16Ptr("ROOT")) if err != nil { return nil, err } defer syscall.CertCloseStore(store, 0) roots := NewCertPool() var cert *syscall.CertContext for { cert, err = syscall.CertEnumCertificatesInStore(store, cert) if err != nil { if errno, ok := err.(syscall.Errno); ok { if errno == CRYPT_E_NOT_FOUND { break } } return nil, err } if cert == nil { break } // Copy the buf, since ParseCertificate does not create its own copy. buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] buf2 := make([]byte, cert.Length) copy(buf2, buf) if c, err := ParseCertificate(buf2); err == nil { roots.AddCert(c) } } return roots, nil }
func loadStore(roots *x509.CertPool, name string) { store, errno := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name)) if errno != 0 { return } var cert *syscall.CertContext for { cert = syscall.CertEnumCertificatesInStore(store, cert) if cert == nil { break } var asn1Slice []byte hdrp := (*reflect.SliceHeader)(unsafe.Pointer(&asn1Slice)) hdrp.Data = cert.EncodedCert hdrp.Len = int(cert.Length) hdrp.Cap = int(cert.Length) buf := make([]byte, len(asn1Slice)) copy(buf, asn1Slice) if cert, err := x509.ParseCertificate(buf); err == nil { roots.AddCert(cert) } } syscall.CertCloseStore(store, 0) }
func ImportCAToSystemRoot(cert *x509.Certificate) error { data := cert.Raw store, err := syscall.CertOpenStore(10, 0, 0, 0x4000|0x20000|0x00000004, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("root")))) if err != nil { return err } defer syscall.CertCloseStore(store, 0) _, _, err = procCertAddEncodedCertificateToStore.Call(uintptr(store), 1, uintptr(unsafe.Pointer(&data[0])), uintptr(uint(len(data))), 4, 0) if err.(syscall.Errno) != 0 { return err } return nil }
func RemoveCAFromSystemRoot(name string) error { store, err := syscall.CertOpenStore(10, 0, 0, 0x4000|0x20000|0x00000004, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("root")))) if err != nil { return nil } defer syscall.CertCloseStore(store, 0) certs := make([]*syscall.CertContext, 0) var cert *syscall.CertContext for { cert, err = syscall.CertEnumCertificatesInStore(store, cert) if err != nil { break } buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] buf2 := make([]byte, cert.Length) copy(buf2, buf) c, err := x509.ParseCertificate(buf2) if err != nil { return err } if c.Subject.CommonName == name || (len(c.Subject.Names) > 0 && c.Subject.Names[0].Value == name) || (len(c.Subject.Organization) > 0 && c.Subject.Organization[0] == name) { certs = append(certs, cert) } } for _, cert := range certs { _, _, err = procCertDeleteCertificateFromStore.Call(uintptr(unsafe.Pointer(cert))) } if se, ok := err.(syscall.Errno); ok && se != 0 { return err } return nil }
func loadStore(roots *x509.CertPool, name string) { store, err := syscall.CertOpenSystemStore(syscall.InvalidHandle, syscall.StringToUTF16Ptr(name)) if err != nil { return } defer syscall.CertCloseStore(store, 0) var cert *syscall.CertContext for { cert, err = syscall.CertEnumCertificatesInStore(store, cert) if err != nil { return } buf := (*[1 << 20]byte)(unsafe.Pointer(cert.EncodedCert))[:] // ParseCertificate requires its own copy of certificate data to keep. buf2 := make([]byte, cert.Length) copy(buf2, buf) if c, err := x509.ParseCertificate(buf2); err == nil { roots.AddCert(c) } } }
// Creates a new *syscall.CertContext representing the leaf certificate in an in-memory // certificate store containing itself and all of the intermediate certificates specified // in the opts.Intermediates CertPool. // // A pointer to the in-memory store is available in the returned CertContext's Store field. // The store is automatically freed when the CertContext is freed using // syscall.CertFreeCertificateContext. func createStoreContext(leaf *Certificate, opts *VerifyOptions) (*syscall.CertContext, error) { var storeCtx *syscall.CertContext leafCtx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &leaf.Raw[0], uint32(len(leaf.Raw))) if err != nil { return nil, err } defer syscall.CertFreeCertificateContext(leafCtx) handle, err := syscall.CertOpenStore(syscall.CERT_STORE_PROV_MEMORY, 0, 0, syscall.CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, 0) if err != nil { return nil, err } defer syscall.CertCloseStore(handle, 0) err = syscall.CertAddCertificateContextToStore(handle, leafCtx, syscall.CERT_STORE_ADD_ALWAYS, &storeCtx) if err != nil { return nil, err } if opts.Intermediates != nil { for _, intermediate := range opts.Intermediates.certs { ctx, err := syscall.CertCreateCertificateContext(syscall.X509_ASN_ENCODING|syscall.PKCS_7_ASN_ENCODING, &intermediate.Raw[0], uint32(len(intermediate.Raw))) if err != nil { return nil, err } err = syscall.CertAddCertificateContextToStore(handle, ctx, syscall.CERT_STORE_ADD_ALWAYS, nil) syscall.CertFreeCertificateContext(ctx) if err != nil { return nil, err } } } return storeCtx, nil }