MCPcopy
hub / github.com/mongodb/node-mongodb-native / continueScramConversation

Function continueScramConversation

src/cmap/auth/scram.ts:116–204  ·  view source on GitHub ↗
(
  cryptoMethod: CryptoMethod,
  response: Document,
  authContext: AuthContext
)

Source from the content-addressed store, hash-verified

114}
115
116async function continueScramConversation(
117 cryptoMethod: CryptoMethod,
118 response: Document,
119 authContext: AuthContext
120): Promise<void> {
121 const connection = authContext.connection;
122 const credentials = authContext.credentials;
123 if (!credentials) {
124 throw new MongoMissingCredentialsError('AuthContext must provide credentials.');
125 }
126 if (!authContext.nonce) {
127 throw new MongoInvalidArgumentError('Unable to continue SCRAM without valid nonce');
128 }
129 const nonce = authContext.nonce;
130
131 const db = credentials.source;
132 const username = cleanUsername(credentials.username);
133 const password = credentials.password;
134
135 const processedPassword =
136 cryptoMethod === 'sha256' ? saslprep(password) : passwordDigest(username, password);
137
138 const payload: Binary = ByteUtils.isUint8Array(response.payload)
139 ? new Binary(response.payload)
140 : response.payload;
141
142 const dict = parsePayload(payload);
143
144 const iterations = parseInt(dict.i, 10);
145 if (iterations && iterations < 4096) {
146 // TODO(NODE-3483)
147 throw new MongoRuntimeError(`Server returned an invalid iteration count ${iterations}`);
148 }
149
150 const salt = dict.s;
151 const rnonce = dict.r;
152 if (rnonce.startsWith('nonce')) {
153 // TODO(NODE-3483)
154 throw new MongoRuntimeError(`Server returned an invalid nonce: ${rnonce}`);
155 }
156
157 // Set up start of proof
158 const withoutProof = `c=biws,r=${rnonce}`;
159 const saltedPassword = await HI(
160 processedPassword,
161 ByteUtils.fromBase64(salt),
162 iterations,
163 cryptoMethod
164 );
165
166 const clientKey = await HMAC(cryptoMethod, saltedPassword, 'Client Key');
167 const serverKey = await HMAC(cryptoMethod, saltedPassword, 'Server Key');
168 const storedKey = await H(cryptoMethod, clientKey);
169 const firstMessageBytes = clientFirstMessageBare(username, nonce);
170 const firstMessage = ByteUtils.toUTF8(firstMessageBytes, 0, firstMessageBytes.length, false);
171 const payloadString = ByteUtils.toUTF8(payload.buffer, 0, payload.position, false);
172 const authMessage = [firstMessage, payloadString, withoutProof].join(',');
173

Callers 2

authMethod · 0.85
executeScramFunction · 0.85

Calls 11

nsFunction · 0.90
cleanUsernameFunction · 0.85
passwordDigestFunction · 0.85
parsePayloadFunction · 0.85
HIFunction · 0.85
HMACFunction · 0.85
clientFirstMessageBareFunction · 0.85
xorFunction · 0.85
compareDigestFunction · 0.85
HFunction · 0.70
commandMethod · 0.45

Tested by

no test coverage detected