std::string KeyStatusResponse( IINField iin, uint8_t seq, uint32_t ksq, uint16_t user, KeyWrapAlgorithm keyWrap, KeyStatus status, HMACType hmacType, const std::string& challenge, const std::string& hmac ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_RESPONSE); apdu.SetIIN(iin); HexSequence challengeBuff(challenge); HexSequence hmacBuff(hmac); Group120Var5 rsp; rsp.keyChangeSeqNum = ksq; rsp.userNum = user; rsp.keyWrapAlgo = keyWrap; rsp.keyStatus = status; rsp.hmacAlgo = hmacType; rsp.challengeData = challengeBuff.ToRSlice(); rsp.hmacValue = hmacBuff.ToRSlice(); apdu.GetWriter().WriteFreeFormat(rsp); return ToHex(apdu.ToRSlice()); }
std::string ChallengeResponse( opendnp3::IINField iin, uint8_t seq, uint32_t csq, uint16_t user, HMACType hmacType, ChallengeReason reason, std::string challengeDataHex ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_RESPONSE); apdu.SetIIN(iin); HexSequence challengeBuff(challengeDataHex); Group120Var1 rsp( csq, user, hmacType, reason, challengeBuff.ToRSlice() ); apdu.GetWriter().WriteFreeFormat(rsp); return ToHex(apdu.ToRSlice()); }
std::string AuthErrorResponse( opendnp3::IINField iin, uint8_t appSeq, uint32_t challengeSeqNum, uint16_t user, uint16_t assocId, opendnp3::AuthErrorCode code, opendnp3::DNPTime timestamp, std::string hexErrorText) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, appSeq)); apdu.SetFunction(FunctionCode::AUTH_RESPONSE); apdu.SetIIN(iin); HexSequence hexErrorTextBuff(hexErrorText); Group120Var7 error( challengeSeqNum, user, assocId, code, timestamp, hexErrorTextBuff.ToRSlice() ); apdu.GetWriter().WriteFreeFormat(error); return ToHex(apdu.ToRSlice()); }
std::string Confirm(uint8_t seq, bool unsol) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, unsol, seq)); apdu.SetFunction(FunctionCode::CONFIRM); return ToHex(apdu.ToRSlice()); }
std::string EmptyAuthResponse(uint8_t seq, const opendnp3::IINField& iin) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse response(buffer.GetWSlice()); response.SetFunction(FunctionCode::AUTH_RESPONSE); response.SetControl(AppControlField(true, true, false, false, seq)); response.SetIIN(iin); return ToHex(response.ToRSlice()); }
std::string RequestKeyStatus(uint8_t seq, uint16_t user) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); Group120Var4 status; status.userNum = user; apdu.GetWriter().WriteSingleValue<UInt8>(QualifierCode::UINT8_CNT, status); return ToHex(apdu.ToRSlice()); }
APDUHeaderParser::Result<APDUHeader> APDUHeaderParser::ParseRequest(const openpal::RSlice& apdu, openpal::Logger* logger) { if (apdu.Size() < APDUHeader::REQUEST_SIZE) { FORMAT_LOGGER_BLOCK(logger, flags::WARN, "Request fragment with insufficient size of %u bytes", apdu.Size()); return Result<APDUHeader>::Error(); } return Result<APDUHeader>::Ok(APDUHeader(AppControlField(apdu[0]), FunctionCodeFromType(apdu[1])), apdu.Skip(APDUHeader::REQUEST_SIZE)); }
std::string FinishUpdateKeyChangeResponse( uint8_t seq, const std::string& hmac ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_RESPONSE); apdu.SetIIN(IINBit::DEVICE_RESTART); HexSequence hmacBuffer(hmac); apdu.GetWriter().WriteFreeFormat(Group120Var15(hmacBuffer.ToRSlice())); return ToHex(apdu.ToRSlice()); }
std::string BeginUpdateKeyChangeResponse( uint8_t seq, uint32_t ksq, uint16_t user, const std::string& outstationChallenge ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDUResponse apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_RESPONSE); apdu.SetIIN(IINBit::DEVICE_RESTART); HexSequence challenge(outstationChallenge); apdu.GetWriter().WriteFreeFormat(Group120Var12(ksq, user, challenge)); return ToHex(apdu.ToRSlice()); }
std::string BeginUpdateKeyChangeRequest( uint8_t seq, opendnp3::KeyChangeMethod method, const std::string& username, const std::string& masterChallenge ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); RSlice name(reinterpret_cast<const uint8_t*>(username.c_str()), static_cast<uint32_t>(username.size())); HexSequence challenge(masterChallenge); apdu.GetWriter().WriteFreeFormat(Group120Var11(method, name, challenge)); return ToHex(apdu.ToRSlice()); }
std::string ChallengeReply( uint8_t appSeq, uint32_t challengeSeqNum, uint16_t userNum, std::string hmacHex ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, appSeq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); HexSequence hmacBuff(hmacHex); Group120Var2 rsp(challengeSeqNum, userNum, hmacBuff.ToRSlice()); apdu.GetWriter().WriteFreeFormat(rsp); return ToHex(apdu.ToRSlice()); }
std::string FinishUpdateKeyChangeRequest( uint8_t seq, uint32_t ksq, uint16_t user, const std::string& encryptedData, const std::string& hmac ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); HexSequence encryptedBuffer(encryptedData); HexSequence hmacBuffer(hmac); auto writer = apdu.GetWriter(); writer.WriteFreeFormat(Group120Var13(ksq, user, encryptedBuffer.ToRSlice())); writer.WriteFreeFormat(Group120Var15(hmacBuffer.ToRSlice())); return ToHex(apdu.ToRSlice()); }
std::string KeyChangeRequest( uint8_t seq, uint32_t ksq, uint16_t user, const std::string& keyWrapData ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); HexSequence keyBuffer(keyWrapData); Group120Var6 rsp; rsp.keyChangeSeqNum = ksq; rsp.userNum = user; rsp.keyWrapData = keyBuffer.ToRSlice(); apdu.GetWriter().WriteFreeFormat(rsp); return ToHex(apdu.ToRSlice()); }
std::string UserStatusChangeRequest( uint8_t seq, opendnp3::KeyChangeMethod keyChangeMethod, opendnp3::UserOperation userOperation, uint32_t statusChangeSeqNum, uint16_t userRole, uint16_t userRoleExpDays, const std::string& userName, const std::string& userPublicKeyHex, const std::string& certificationDataHex ) { Buffer buffer(DEFAULT_MAX_APDU_SIZE); APDURequest apdu(buffer.GetWSlice()); apdu.SetControl(AppControlField(true, true, false, false, seq)); apdu.SetFunction(FunctionCode::AUTH_REQUEST); RSlice name(reinterpret_cast<const uint8_t*>(userName.c_str()), static_cast<uint32_t>(userName.size())); HexSequence userPublicKeyBuffer(userPublicKeyHex); HexSequence certificationDataBuffer(certificationDataHex); Group120Var10 statusChange( keyChangeMethod, userOperation, statusChangeSeqNum, userRole, userRoleExpDays, name, userPublicKeyBuffer.ToRSlice(), certificationDataBuffer.ToRSlice() ); apdu.GetWriter().WriteFreeFormat(statusChange); return ToHex(apdu.ToRSlice()); }
AppControlField AppControlField::Request(uint8_t seq) { return AppControlField(true, true, false, false, seq); }