// OpenToEncode creates new Msg in encode mode. func OpenToEncode(dest io.Writer, options EncodeOptions) (res *Msg, err error) { var flags C.DWORD res = new(Msg) if len(options.Signers) == 0 { err = fmt.Errorf("Signer certificates list is empty") return } if options.HashAlg == nil { options.HashAlg = GOST_R3411 } if options.Detached { flags = C.CMSG_DETACHED_FLAG } si := C.mkStreamInfo(unsafe.Pointer(res)) defer C.free(unsafe.Pointer(si)) signedInfo := C.mkSignedInfo(C.int(len(options.Signers))) defer C.freeSignedInfo(signedInfo) hashOID := C.CString(options.HashAlg.String()) defer C.free(unsafe.Pointer(hashOID)) for i, signerCert := range options.Signers { var ( hCryptProv C.HCRYPTPROV dwKeySpec C.DWORD ) if 0 == C.CryptAcquireCertificatePrivateKey(signerCert.pCert, 0, nil, &hCryptProv, &dwKeySpec, nil) { err = getErr("Error acquiring certificate private key") return } C.setSignedInfo(signedInfo, C.int(i), hCryptProv, signerCert.pCert, dwKeySpec, (*C.CHAR)(hashOID)) } res.hMsg = C.CryptMsgOpenToEncode( C.MY_ENC_TYPE, // encoding type flags, // flags C.CMSG_SIGNED, // message type unsafe.Pointer(signedInfo), // pointer to structure nil, // inner content OID si, // stream information ) if res.hMsg == nil { err = getErr("Error opening message for encoding") return } res.dest = dest res.updateCallback = res.onEncode return }
// OpenToDecode creates new Msg in decode mode. If detachedSig parameter is specified, // it must contain detached P7S signature func OpenToDecode(src io.Reader, detachedSig ...[]byte) (res *Msg, err error) { var ( flags C.DWORD si *C.CMSG_STREAM_INFO ) res = new(Msg) if len(detachedSig) > 0 { flags = C.CMSG_DETACHED_FLAG si = nil } else { si = C.mkStreamInfo(unsafe.Pointer(res)) defer C.free(unsafe.Pointer(si)) } res.hMsg = C.CryptMsgOpenToDecode( C.MY_ENC_TYPE, // encoding type flags, // flags 0, // message type (get from message) 0, // default cryptographic provider nil, // recipient information si, // stream info ) if res.hMsg == nil { err = getErr("Error opening message for decoding") return } res.src = src res.updateCallback = res.onDecode for i, p := range detachedSig { if !res.update(p, len(p), i == len(detachedSig)-1) { err = getErr("Error updating message header") return } } return }