Example #1
0
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
}
Example #2
0
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)
}
Example #3
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
}
Example #4
0
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
}
Example #5
0
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)
		}
	}
}
Example #6
0
// 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
}