1 package org.metricshub.ipmi.core.coding.protocol.encoder;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 import org.metricshub.ipmi.core.coding.protocol.AuthenticationType;
26 import org.metricshub.ipmi.core.coding.protocol.IpmiMessage;
27 import org.metricshub.ipmi.core.coding.protocol.Ipmiv15Message;
28 import org.metricshub.ipmi.core.common.TypeConverter;
29
30 import java.security.InvalidKeyException;
31
32
33
34
35 public class Protocolv15Encoder extends ProtocolEncoder {
36
37
38
39
40
41
42
43
44
45
46 @Override
47 public byte[] encode(IpmiMessage ipmiMessage) throws InvalidKeyException {
48 if (!(ipmiMessage instanceof Ipmiv15Message)) {
49 throw new IllegalArgumentException("IPMIMessage must be in 1.5 version.");
50 }
51 Ipmiv15Message message = (Ipmiv15Message) ipmiMessage;
52
53 byte[] raw = new byte[getMessageLength(message)];
54
55 raw[0] = encodeAuthenticationType(message.getAuthenticationType());
56
57 int offset = 1;
58
59 encodeSessionSequenceNumber(message.getSessionSequenceNumber(), raw, offset);
60 offset += 4;
61
62 encodeSessionId(message.getSessionID(), raw, offset);
63 offset += 4;
64
65 if (message.getAuthenticationType() != AuthenticationType.None) {
66 encodeAuthenticationCode(message.getAuthCode(), raw, offset);
67 offset += message.getAuthCode().length;
68 }
69
70 byte[] payload = message.getPayload().getEncryptedPayload();
71
72 if (payload == null) {
73 message.getPayload().encryptPayload(message.getConfidentialityAlgorithm());
74 payload = message.getPayload().getEncryptedPayload();
75 }
76
77 encodePayloadLength(payload.length, raw, offset);
78 ++offset;
79
80 offset = encodePayload(payload, raw, offset);
81
82 encodeSessionTrailer(raw, offset);
83
84 return raw;
85 }
86
87 private int getMessageLength(IpmiMessage ipmiMessage) {
88 int length = 11
89 + ipmiMessage.getConfidentialityAlgorithm().getConfidentialityOverheadSize(ipmiMessage.getPayloadLength())
90 + ipmiMessage.getPayloadLength();
91
92 if (ipmiMessage.getAuthenticationType() != AuthenticationType.None) {
93 length += 16;
94 }
95
96 return length;
97 }
98
99
100
101
102
103
104
105
106
107
108
109 private void encodeAuthenticationCode(byte[] authCode, byte[] message, int offset) {
110 if (authCode.length + offset > message.length) {
111 throw new IndexOutOfBoundsException("Message is too short");
112 }
113 System.arraycopy(authCode, 0, message, offset, authCode.length);
114 }
115
116 @Override
117 protected void encodePayloadLength(int value, byte[] message, int offset) {
118 message[offset] = TypeConverter.intToByte(value);
119 }
120
121
122
123
124
125
126
127
128
129
130
131
132
133 private int encodeSessionTrailer(byte[] message, int offset) {
134 if (1 + offset > message.length) {
135 throw new IndexOutOfBoundsException("Message is too short");
136 }
137
138 message[offset] = 0;
139
140 return offset + 1;
141 }
142 }